在SQLAlchemy/Gino中,更新/插入语句能否返回关联查询列?
问题
我拥有Users和Tags两张数据表,希望在更新Tags表后,将Tags.created_by_user_id替换为左关联的Users.hash_id。
表定义如下:
class Tag(BaseClass): __tablename__ = "tags" ... created_by_user_id: Optional["UserId"] = db.Column( db.BigInteger, db.ForeignKey("users.id"), index=True, ) class User(BaseClass): __tablename__ = "users" ... id: Optional[int] = db.Column(db.BigInteger, primary_key=True, autoincrement=True) hash_id: Optional[str] = db.Column( db.Text, index=True, server_default=FetchedValue(), nullable=False, )
我当前的解决方案是更新Tag后,通过更新语句返回的列再次查询Tag:
tag_int: int = ( await ORMTag.update.values(**t) .where( and_( ORMTag.hash_id == id, ) ) .returning(Tag.id) .gino.load(ColumnLoader(Tag.id)) .first() ) tag: Tag = await db.select( [ Tag.id, ... User.hash_id.label("created_by_user_id"), ] ).select_from( Tag.join(User, Tag.created_by_user_id == User.id, isouter=True) ).gino.first()
请问能否无需额外查询数据库,直接实现该需求?我已研究过with_expressions、query_expressions以及Gino子查询加载。
解决方案
可以直接在更新语句的returning子句中通过子查询获取关联的User.hash_id,无需二次查询数据库,示例代码如下:
updated_tag = await ( ORMTag.update.values(**t) .where(ORMTag.hash_id == id) .returning( ORMTag.id, # 按需添加其他需要返回的Tag字段 db.select([User.hash_id]) .where(User.id == ORMTag.created_by_user_id) .label("created_by_user_id") ) .gino.first() )
说明
- 子查询逻辑和你二次查询时的左关联逻辑一致,能直接匹配到对应用户的
hash_id - 如果
created_by_user_id为NULL,子查询会返回NULL,符合左关联的预期 - 更新完成后,
updated_tag会直接包含所有你需要的字段,包括替换后的created_by_user_id
内容的提问来源于stack exchange,提问作者Hyperion
相关产品推荐
相关产品推荐

