gpt4 book ai didi

python - SQLAlchemy 中从表到模型的反向映射

转载 作者:行者123 更新时间:2023-12-01 06:16:50 29 4
gpt4 key购买 nike

为了在基于 SQLAlchemy 的应用程序中提供事件日志,我有一个如下所示的模型:

class ActivityLog(Base):
__tablename__ = 'activitylog'
id = Column(Integer, primary_key=True)
activity_by_id = Column(Integer, ForeignKey('users.id'), nullable=False)
activity_by = relation(User, primaryjoin=activity_by_id == User.id)
activity_at = Column(DateTime, default=datetime.utcnow, nullable=False)
activity_type = Column(SmallInteger, nullable=False)

target_table = Column(Unicode(20), nullable=False)
target_id = Column(Integer, nullable=False)
target_title = Column(Unicode(255), nullable=False)

日志包含多个表的条目,因此我无法使用外键关系。日志条目的制作方式如下:

doc = Document(name=u'mydoc', title=u'My Test Document',
created_by=user, edited_by=user)
session.add(doc)
session.flush() # See note below
log = ActivityLog(activity_by=user, activity_type=ACTIVITY_ADD,
target_table=Document.__table__.name, target_id=doc.id,
target_title=doc.title)
session.add(log)

这给我带来了三个问题:

  1. 在我的 doc 对象获得 id 之前,我必须刷新 session 。如果我使用了外键列和关系映射器,我可以简单地调用 ActivityLog(target=doc) 并让 SQLAlchemy 完成工作。有什么办法可以解决需要用手冲水的问题吗?

  2. target_table 参数过于冗长。我想我可以使用 ActivityLog 中的 target 属性 setter 来解决这个问题,该 setter 会自动从给定实例中检索表名称和 id。

  3. 最重要的是,我不确定如何从数据库中检索模型实例。给定一个 ActivityLog 实例 log,调用 self.session.query(log.target_table).get(log.target_id) 不起作用,因为 query() 需要一个模型作为参数。

一种解决方法似乎是使用多态性并从 ActivityLog 识别的基本模型派生我的所有模型。像这样的事情:

class Entity(Base):
__tablename__ = 'entities'
id = Column(Integer, primary_key=True)
title = Column(Unicode(255), nullable=False)
edited_at = Column(DateTime, onupdate=datetime.utcnow, nullable=False)
entity_type = Column(Unicode(20), nullable=False)
__mapper_args__ = {'polymorphic_on': entity_type}

class Document(Entity):
__tablename__ = 'documents'
__mapper_args__ = {'polymorphic_identity': 'document'}
body = Column(UnicodeText, nullable=False)

class ActivityLog(Base):
__tablename__ = 'activitylog'
id = Column(Integer, primary_key=True)
...
target_id = Column(Integer, ForeignKey('entities.id'), nullable=False)
target = relation(Entity)

如果我这样做,ActivityLog(...).target 在引用文档时会给我一个 Document 实例,但我不确定是否值得花费两个表的开销对于一切。我应该继续这样做吗?

最佳答案

解决这个问题的一种方法是多态关联。它应该可以解决您的所有 3 个问题,并且还可以使数据库外键约束发挥作用。请参阅polymorphic association example在 SQLAlchemy 源中。迈克·拜尔(Mike Bayer)有一个旧的blogpost更详细地讨论了这一点。

关于python - SQLAlchemy 中从表到模型的反向映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2850988/

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