2

多対多の関係 A と B として 2 つのクラスがあり、ここで基本的な関係を示すために短縮されています。

class A(Base):

    bclss = relationship("B",
                          backref = "aclss",
                          secondary = "a_b_association",
                          collection_class = attribute_mapped_collection('identifier'))   

    a_b_association_table = Table('a_b_association', Base.metadata,
                             Column('a_id', Integer, ForeignKey('a.id')),
                             Column('b_id', Integer, ForeignKey('b.id')) )

したがって、A のインスタンスは B のインスタンスを追加し、識別子によってキー付けされた辞書で参照できます...ただし、B インスタンスにはオブジェクトの [リスト] しか含まれず、関連するインスタンスを引き出すためにミラーリングされたインターフェイスが必要ですディクショナリ内の識別子キーによって b インスタンスに。b でリレーションシップ ステートメントをミラーリングし、同じ関連付けテーブルを参照しても機能しないため、sqlalchemy での実装方法がまだ正確にわかっていない領域について考えています。

したがって、これが 100% 明確でなくても、私の質問は次のとおりです。

ディクショナリを取得する方法、多対多の関係で関連する 2 つのアイテムの属性マップ コレクションを取得する方法。各側は、私が取得しているものではなく、関連するアイテムをディクショナリ キーでプルできます。非対称の片側ディクショナリ/反対側リスト インターフェイス。

4

1 に答える 1

1

これがあなたが探しているものだと思います(backref別の との多対多の関係で関係を定義する必要があるだけですattribute_mapped_collection):

from sqlalchemy import Column, ForeignKey, Integer, String, Table, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref, relationship, sessionmaker
from sqlalchemy.orm.collections import attribute_mapped_collection


Base = declarative_base()


class A(Base):
    __tablename__ = 'a'

    id = Column(Integer, primary_key=True)


a_b_association_table = Table(
    'a_b_association', Base.metadata,
    Column('a_id', Integer, ForeignKey('a.id')),
    Column('b_id', Integer, ForeignKey('b.id'))
)


class B(Base):
    __tablename__ = 'b'

    id = Column(String, primary_key=True)

    a_instances = relationship(
        A,
        backref = backref(
            'b_instances',
            collection_class = attribute_mapped_collection('id'),
        ),
        secondary = a_b_association_table,
        collection_class = attribute_mapped_collection('id'),
    )


engine = create_engine('sqlite://')
Base.metadata.bind = engine
Base.metadata.create_all()

Session = sessionmaker(bind=engine)

session = Session()

a1, a2, a3 = A(id=1), A(id=2), A(id=3)
b1, b2, b3 = B(id='a'), B(id='b'), B(id='c')

session.add_all([a1, a2, a3, b1, b2, b3])
session.flush()

print(a1.b_instances)
print(b1.a_instances)
a1.b_instances[b1.id] = b1
a1.b_instances[b2.id] = b2
b1.a_instances[a1.id] = a1
b1.a_instances[a2.id] = a2
session.flush()
session.expunge_all()
a1 = session.query(A).get(1)
b1 = session.query(B).get('a')
print(a1.b_instances)
print(b1.a_instances)

出力:

{}
{}
{u'a': <__main__.B object at 0x2816490>, u'b': <__main__.B object at 0x28b0350>}
{1: <__main__.A object at 0x28ac9d0>, 2: <__main__.A object at 0x28b0650>}
于 2012-10-21T21:00:18.677 に答える