【问题标题】:SQLAlchemy ORM Update for HSTORE fieldsHSTORE 字段的 SQLAlchemy ORM 更新
【发布时间】:2022-08-24 18:45:16
【问题描述】:
当我尝试更新 hstore 字段时遇到问题。我有以下翻译混合和数据库模型。
translation_hybrid = TranslationHybrid(
current_locale=\'en\',
default_locale=\'de\'
)
class Book:
__tablename__ = \"Book\"
id = Column(UUID(as_uuid=True), primary_key=True)
title_translations = Column(MutableDict.as_mutable(HSTORE), nullable=False)
title = translation_hybrid(title_translations)
我想使用单个 orm 查询使用当前语言环境更新标题。当我尝试以下查询时
query(Book).filter(Book.id == id).update({\"title\": \"new_title\"})
ORM 将其转换为以下 sql:
UPDATE \"Book\" SET coalesce(title_translations -> \'en\', title_translations -> \'de\') = \"new_title\" WHERE \"Book\".id = id
这个 sql 给出了语法错误。在不先获取模型并将值分配给字段的情况下更新它的最佳方法是什么?
标签:
python
sqlalchemy
orm
hstore
【解决方案1】:
我们最终让它运行起来,在此处记录以帮助可能遇到此问题的其他人;请注意,我们使用的是新的select 方法和async。
正如您已经建议的那样,我们通过将更新的值直接分配给记录对象来解决这个问题。我们基本上是在实现this solution from the SQLAlchemy docu:
updated_record: models.Country = None # type: ignore
try:
# fetch current data from database and lock for update
record = await session.execute(
select(models.Country)
.filter_by(id=str(country_id))
.with_for_update(nowait=True)
)
updated_record = record.scalar_one()
logger.debug(
"update() - fetched current data from database",
record=record,
updated_record=vars(updated_record),
)
# merge country_dict (which holds the data to be updated) with the data in the DB
for key, value in country_dict.items():
setattr(updated_record, key, value)
logger.debug(
"update() - merged new data into record",
updated_record=vars(updated_record),
)
# flush data to database
await session.flush()
# refresh updated_record and commit
await session.refresh(updated_record)
await session.commit()
except Exception as e: # noqa: PIE786
logger.error("update() - an error occurred", error=str(e))
await session.rollback()
raise ValueError("Record can not be updated.")
return updated_record