2012-10-21 82 views
1

我有2個班作爲一個多對多的關係A和B,縮短在這裏展示的基本關係:雙向許多一對多attribute_mapped_collection,SQLAlchemy的

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'))) 

所以的情況下,可以添加B的情況下, ,並且在被標識符鍵入的字典中被引用...但是B實例僅包含它們的一個對象的[列表],並且我想要一個鏡像接口,通過標識符關鍵字來提取與b實例相關的實例字典。鏡像b上的關係語句並引用相同的關聯表不起作用,所以我正在思考一個我不完全知道如何在sqlalchemy中實現的區域。

所以,即使這是不是100%清楚,我的問題是這樣的:

如何獲得一本字典,屬性在許多涉及到很多的關係,其中每個邊可以通過字典拉兩個項目集合映射鍵入相關的項目,而不是我所得到的:一個不對稱的單面字典/另一個列表界面。

回答

0

我相信這是你要找的東西(你只需要定義在許多一對多的關係與另一個attribute_mapped_collection一個backref關係):

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>} 
+0

這基本上是我第一次做的,然後在這之後回去,給出了不同的名字而不是鏡像名稱。您需要爲每個類設置兩對引用,而不是每個類上相同的引用對。後者是我得到錯誤的地方。 – blueblank