首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQLAlchemy - sqlalchemy.exc.StatementError:(builtins.TypeError)序列项0:预期的str实例,元组找到

SQLAlchemy - sqlalchemy.exc.StatementError:(builtins.TypeError)序列项0:预期的str实例,元组找到
EN

Stack Overflow用户
提问于 2022-08-03 12:36:41
回答 1查看 85关注 0票数 0

我正在尝试使用Blockonomics API将BTC支付并入我的WEB应用程序,尽管我在根据以下模型创建新发票时遇到了问题:

代码语言:javascript
运行
复制
class Product(Base):
    __tablename__ = 'product'
    id          = Column(Integer,      primary_key=True)
    title       = Column(String(128),  nullable=False)
    description = Column(String(1024), nullable=False)
    price       = Column(Float,        nullable=False)
    thumbnail   = Column(LargeBinary,  nullable=False)

    def __init__(self, title, description, price, thumbnail):
        self.title       = title
        self.description = description
        self.price       = price
        self.thumbnail   = thumbnail

    def __repr__(self):
        return '<%r>' % (self.title) 

class Invoice(Base):
    __tablename__ = 'btc_invoice'
    STATUS_CHOICES         = ((-1, "Not Started"), (0, 'Unconfirmed'), (1, "Partially Confirmed"), (2, "Confirmed"))
    id                     = Column(Integer,      primary_key=True)
    product_id             = Column(Integer,      ForeignKey('product.id'))
    order_id               = Column(String(250))
    address                = Column(String(250),  nullable=True)
    btcvalue               = Column(Integer,      nullable=True)
    received               = Column(Integer,      nullable=True)  
    txid                   = Column(String(250),  nullable=True)
    rbf                    = Column(Integer,      nullable=True)
    created_at             = Column(DateTime,     default=datetime.now())
    status                 = Column(Enum(STATUS_CHOICES),default=-1)
    
    # New instance instantiation procedure
    def __init__(self, product_id, order_id, address,  btcvalue, status=null, received=null, txid=null, rbf=null):
        self.product_id   = product_id
        self.order_id  = order_id
        self.address   = address
        self.btcvalue  = btcvalue
        self.status    = status
        self.received  = received
        self.txid      = txid
        self.rbf       = rbf

    def __repr__(self):
        return '<%r>' % (self.address) 

下面是我的控制器中的一个函数,它会抛出一个错误,我不明白为什么:

代码语言:javascript
运行
复制
def checkout(mockup, category, language, product_title, front=None, back=None):
    if (language not in languages):
        language = app_language
    
    product = Product.query.filter_by(title=product_title).first()
    customer_item_id = front.split('_')[0]

    url      = os.getenv("BLOCKONOMICS_URL")
    headers  = {"Authorization": "Bearer " + os.getenv("API_KEY"), 'X-BLOCKONOMICS-VERSION': '1'}
    # Get BitCoin address from Blockonomics API (response) in order to perform address
    response = requests.post(url, headers=headers)

    if response.status_code == 200:
        address = response.json()['address']
        bits    = exchanged_rate(product.price)
        order_id = uuid.uuid1()
        
        invoice = Invoice(product_id=product.id, order_id=str(order_id), address=address, btcvalue=bits*1e8)
        
        Base.metadata.create_all(bind=engine)
        BTC_INVOICE_TABLE = Base.metadata.tables['btc_invoice']
        
        stmt = (
            insert(BTC_INVOICE_TABLE).values(product_id=invoice.product_id, order_id=invoice.order_id, address=invoice.address, btcvalue=int(invoice.btcvalue))
        )
        compiled = stmt.compile()
        
        with engine.connect() as conn:
            result = conn.execute(stmt)
            conn.commit()
        
        return redirect(url_for('payment.track_invoice',invoice_id=order_id, language=language, **languages[language]))

实际的堆栈跟踪是:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/sql/sqltypes.py", line 1625, in _db_value_for_elem
    return self._valid_lookup[elem]
KeyError: -1

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1720, in _execute_context
    dialect, self, conn, execution_options, *args, **kw
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 1074, in _init_compiled
    for key in positiontup
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 1074, in <listcomp>
    for key in positiontup
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/sql/sqltypes.py", line 1773, in process
    value = self._db_value_for_elem(value)
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/sql/sqltypes.py", line 1647, in _db_value_for_elem
    langhelpers.repr_tuple_names(self.enums),
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 1928, in repr_tuple_names
    return ", ".join(res)
TypeError: sequence item 0: expected str instance, tuple found

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/flask/app.py", line 2486, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/flask/app.py", line 2466, in wsgi_app
    response = self.handle_exception(e)
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/flask/app.py", line 2463, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/flask/app.py", line 1760, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/flask/app.py", line 1758, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/flask/app.py", line 1734, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/home/stefan/Desktop/Python/document-generator/app/mod_payment/controllers.py", line 91, in mockup_checkout
    result = conn.execute(stmt)
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1306, in execute
    return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/sql/elements.py", line 326, in _execute_on_connection
    self, multiparams, params, execution_options
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1508, in _execute_clauseelement
    cache_hit=cache_hit,
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1726, in _execute_context
    e, util.text_type(statement), parameters, None, None
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 2044, in _handle_dbapi_exception
    sqlalchemy_exception, with_traceback=exc_info[2], from_=e
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1720, in _execute_context
    dialect, self, conn, execution_options, *args, **kw
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 1074, in _init_compiled
    for key in positiontup
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 1074, in <listcomp>
    for key in positiontup
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/sql/sqltypes.py", line 1773, in process
    value = self._db_value_for_elem(value)
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/sql/sqltypes.py", line 1647, in _db_value_for_elem
    langhelpers.repr_tuple_names(self.enums),
  File "/home/stefan/anaconda3/envs/flask-web-dev/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 1928, in repr_tuple_names
    return ", ".join(res)
sqlalchemy.exc.StatementError: (builtins.TypeError) sequence item 0: expected str instance, tuple found
[SQL: INSERT INTO btc_invoice (product_id, order_id, address, btcvalue, created_at, status) VALUES (?, ?, ?, ?, ?, ?)]

我已尝试打印正在插入表中的所有值,以及它们的类型:

代码语言:javascript
运行
复制
print(type(invoice.order_id))
print(type(invoice.product_id))
print(type(invoice.address))
print(type(invoice.btcvalue))

print("Statement -> ", stmt)
print("Compiled Parameters -> ", compiled.params)

<class 'str'>
<class 'int'>
<class 'str'>
<class 'float'>

Statement ->  INSERT INTO btc_invoice (product_id, order_id, address, btcvalue, created_at, status) VALUES (:product_id, :order_id, :address, :btcvalue, :created_at, :status)

Compiled Parameters ->  {'product_id': 1, 'order_id': 'a41c2be0-1327-11ed-914b-752bb22010b9', 'address': 'bc1qcynyjkg9qz5jswa2dm5ddqp2s3ryps7vk3uxst', 'btcvalue': 86540, 'created_at': None, 'status': None}

我在任何地方都看不见元组。SQLAlchemy是否在内部做一些我不知道的事情?我应该尝试普通的SQL,还是模型设计有什么问题?

EN

回答 1

Stack Overflow用户

发布于 2022-08-04 12:54:52

错误很可能来自status列:您不能通过传递Enum列列表来声明tuples列。

您可以做的是传递一个简单的列表并解压它:

代码语言:javascript
运行
复制
STATUS_CHOICES = ["Not Started", "Unconfirmed", "Partially Confirmed", "Confirmed"]
status = Column(Enum(*STATUS_CHOICES), default="Not Started")

您应该做什么(says SQLAlchemy's final boss,而不是我):使用python:

代码语言:javascript
运行
复制
import enum

class StatusChoices(enum.Enum):
    not_started = -1
    unconfirmed = 0
    partially_confirmed = 1
    confirmed = 2

[...]

status = Column(Enum(StatusChoices), default=StatusChoices.not_started)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73221864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档