0

当我尝试更新 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 给出了语法错误。在不先获取模型并将值分配给字段的情况下更新它的最佳方法是什么?

4

1 回答 1

0

我们最终让它运行起来,在此处记录以帮助可能遇到此问题的其他人;请注意,我们使用的是新select方法,并且async.

正如您已经建议的那样,我们通过将更新的值直接分配给记录对象来解决这个问题。我们基本上是从 SQLAlchemy 文档中实现这个解决方案

    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
于 2022-02-28T11:51:56.433 回答