0

SyncEntities クラスがあります (以下を参照)。

SyncEntities クラスに関連する他のいくつかのクラス (以下に示す CommodityTypes など) があります。

すべての基本サブクラスにこの列がありますuuidKey = Column(String, primary_key=True)

se が SyncEntities のインスタンスであるとします。se.entityKind は Base サブクラスの名前です。

se.uuidKey をフィルタリングする se.entityKind クラスにあるオブジェクトをクエリするにはどうすればよいですか?

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
4

1 に答える 1

2

ここでの構造は、「ポリモーフィック アソシエーション」とまったく同じではありませんが、似ています。このパターンについては、次のブログ投稿で読むことができます : Associations-with-sqlalchemy/ . これは古い投稿ですが、http://techspot.zzzeek.org/files/2007/discriminator_on_association.pyの例は、更新された例として後で追加されました。

このケースは、CommodityTypes のようなオブジェクトが単一の SyncEntities のみを参照し、通常のポリモーフィック アソシエーションのように複数を参照しないという点で少し異なります。SyncEntities は、entityKind をローカルに持っているため、単一のタイプの関連オブジェクトしか参照できません。

この設計の潜在的な問題は、特定の SyncEntities インスタンスを指す uuidKey を持つが、「entityKind」に一致する型ではない行が他のテーブルにある可能性があることです。CommodityTypes と SyncEntities の間の関係が実際には 1 対 1 である場合、すべてが変更されます。このパターンは非常に単純な結合テーブルの継承であり、http://docs.sqlalchemy.org/en/rel_0_7/で説明されているパターンを使用します。 orm/inheritance.html .

また、ターゲットと SyncEntities の間に後方参照がありません。これは、多くの場合、これらのスタイルのルックアップを自動化する方法です。しかし、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()

backref を使用して、これも実行できる mixin を次に示します。

class HasSyncEntity(object):
    entity_kind = None
    "subclasses need to populate this"

    @declared_attr
    def uuidKey(cls):
        return Column(String, ForeignKey("SyncEntities.uuidKey"), primary_key=True)

    @declared_attr
    def mySyncEntity(cls):
        return relationship("SyncEntities", backref="_%s_collection" % cls.entity_kind)

CommodityTypes は次のようになります。

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

次に、このようなメソッドを SyncEntities に追加し、適切な backref を検索して完了です。

def get_related(self):
    return getattr(self, "_%s_collection" % self.entityKind)
于 2012-05-03T18:05:29.277 に答える