使用SQLAlchemy,如何建立动态关系?

2024-06-28 12:20:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个SyncEntities类(如下所示)。在

我还有其他几个与SyncEntities类相关的类(如下面还显示的CommodityTypes)。在

我所有的基本子类都有这个列uuidKey = Column(String, primary_key=True)

假设se是SyncEntities的一个实例。 实体种类基子类的名称。在

如何查询实体种类类筛选seuuidkey?在

class SyncEntities(Base):
    __tablename__ = 'SyncEntities'

    uuidKey = Column(String, primary_key=True)
    dateCreated = Column(DateTime, index=True)
    dateModified = Column(DateTime, index=True)
    dateSynced = Column(DateTime, index=True)
    username = Column(String)
    entityKind = Column(String)
    deleted = Column(Boolean)

    def __init__(self, entity, security):
        self.uuidKey = newUUID()
        self.dateCreated = security.now
        self.dateModified = security.now
        self.dateSynced = security.then
        self.username = security.username
        self.entityKind = entity.__tablename__
        self.deleted = False

    def modified(self, security):
        self.dateModified = security.now
        self.username = security.username

class CommodityTypes(Base):
    __tablename__ = 'CommodityTypes'
    uuidKey = Column(String, ForeignKey('SyncEntities.uuidKey'), primary_key=True)
    myName = Column(String, unique = True)
    sortKey = Column(Integer, unique = True)

    mySyncEntity = relationship("SyncEntities")

    def __init__(self, security, myName, sortKey):
        self.syncEntity = SyncEntities(self, security)
        self.uuidKey = self.syncEntity.uuidKey
        self.myName = myName
        self.sortKey = sortKey

Tags: keyselftruedatetimestringusernamecolumnsecurity
1条回答
网友
1楼 · 发布于 2024-06-28 12:20:52

这里的结构与“多态关联”相似,但并不完全相同,您可以在这篇博文中阅读关于此模式的文章:http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-sqlalchemy/。这是一篇旧文章,但是http://techspot.zzzeek.org/files/2007/discriminator_on_association.py上的示例后来被添加为更新的示例。在

这个例子有点不同,像CommodityTypes这样的对象只引用一个syncentity,而不是像通常的多态关联那样多个syncentity。SyncEntities也只能引用一种类型的相关对象,因为您在本地对它进行了entityKind。在

我要指出的是,这种设计的一个潜在问题是,在其他表中,可能会有一个uuidKey指向特定的SyncEntities实例,但其类型与“entityKind”不匹配。如果CommodityTypes和SyncEntities之间的关系实际上是一对一的,那么一切都会改变——这种模式实际上是简单的连接表继承,您将使用http://docs.sqlalchemy.org/en/rel_0_7/orm/inheritance.html中描述的模式。在

目标和SyncEntities之间也没有backref,这通常是自动化这些查找样式的一种方法。但您仍然可以使用entityKind类型对类进行查找来近似处理:

def lookup_related(se):
    types = {
        'commodity':CommodityTypes,
        'foobar':FooBarTypes
    }
    cls = types[se.entityKind]
    session = object_session(se)
    return session.query(cls).filter(cls.mySyncEntity==se).all()

这里有一个mixin也可以使用backref:

^{pr2}$

商品类型变为:

class CommodityTypes(HasSyncEntity, Base):
    entity_kind = "commodity"
    # ...

然后,向SyncEntities添加一个类似这样的方法,该方法将查找适当的backref,这样就完成了:

def get_related(self):
    return getattr(self, "_%s_collection" % self.entityKind)

相关问题 更多 >