gpt4 book ai didi

python - SQLAlchemy 使用 case 子句和枚举更新记录

转载 作者:太空宇宙 更新时间:2023-11-03 15:53:16 29 4
gpt4 key购买 nike

我定义了以下模型和枚举:

class StatusEnum(enum.Enum):
NEW = 'NEW'
PROCESSED = 'PROCESSED'
IN_PROGRESS = 'IN_PROGRESS'

class RequestLog(Base):
__tablename__ = 'request_log'

...
status = Column(Enum(StatusEnum))
...

我正在尝试通过以下方式更新记录:

>>> session.query(RequestLog).filter(RequestLog.id.in_([8])).update(
{'status': case(
[(RequestLog.attempt_done_count == RequestLog.attempt_count - 1, StatusEnum.PROCESSED)],
else_=StatusEnum.IN_PROGRESS)},
synchronize_session=False)

在此期间,我收到一个错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'StatusEnum' [SQL: 'UPDATE request_log SET status=CASE WHEN (request_log.attempt_done_count = request_log.attempt_count - %(attempt_count_1)s) THEN %(param_1)s ELSE %(param_2)s END WHERE request_log.id IN (%(id_1)s)'] [parameters: {'param_2': <StatusEnum.IN_PROGRESS: 'IN_PROGRESS'>, 'attempt_count_1': 1, 'param_1': <StatusEnum.PROCESSED: 'PROCESSED'>, 'id_1': 8}]

最佳答案

对于一个简单的 Python 枚举对象,绑定(bind)值 bind processor of sqltypes.Enum正在运行,uses the string name of the enum object有问题:

In [27]: session.query(RequestLog).filter(RequestLog.id.in_([8])).update(
...: {'status': StatusEnum.NEW},
...: synchronize_session=False)
2017-07-24 15:15:43,848 INFO sqlalchemy.engine.base.Engine UPDATE request_log SET status=%(status)s WHERE request_log.id IN (%(id_1)s)
INFO:sqlalchemy.engine.base.Engine:UPDATE request_log SET status=%(status)s WHERE request_log.id IN (%(id_1)s)
2017-07-24 15:15:43,848 INFO sqlalchemy.engine.base.Engine {'status': 'NEW', 'id_1': 8}
INFO:sqlalchemy.engine.base.Engine:{'status': 'NEW', 'id_1': 8}
Out[27]: 0

虽然对于 SQL 表达式,这似乎不会递归发生,因此在您的 case() 中,枚举对象绑定(bind)值被传递给 psycopg,而 psycopg 不知道如何处理它们。要模拟 SQL 表达式中的行为,您可以手动传递 names of the enum objects , 适当的转换:

In [60]: session.query(RequestLog).filter(RequestLog.id.in_([8])).update(
...: {'status': case(
...: [(true(), StatusEnum.PROCESSED.name)],
...: else_=StatusEnum.IN_PROGRESS.name).cast(RequestLog.status.type)},
...: synchronize_session=False)
2017-07-24 15:40:52,853 INFO sqlalchemy.engine.base.Engine UPDATE request_log SET status=CAST(CASE WHEN true THEN %(param_1)s ELSE %(param_2)s END AS statusenum) WHERE request_log.id IN (%(id_1)s)
INFO:sqlalchemy.engine.base.Engine:UPDATE request_log SET status=CAST(CASE WHEN true THEN %(param_1)s ELSE %(param_2)s END AS statusenum) WHERE request_log.id IN (%(id_1)s)
2017-07-24 15:40:52,853 INFO sqlalchemy.engine.base.Engine {'param_2': 'IN_PROGRESS', 'param_1': 'PROCESSED', 'id_1': 8}
INFO:sqlalchemy.engine.base.Engine:{'param_2': 'IN_PROGRESS', 'param_1': 'PROCESSED', 'id_1': 8}
Out[60]: 0

这很不雅观,我有点确定有更好的方法,但目前这是我能想到的最好的方法。

关于python - SQLAlchemy 使用 case 子句和枚举更新记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45237951/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com