2013-08-16 73 views
0

我在sqlalchemy中擁有一對多關係,但我沒有得到插入正常工作。我試圖做一個小例子,在這裏:無法在sqlalchemy中插入一對多關係

from sqlalchemy import * 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import relationship, sessionmaker 

db = create_engine('sqlite://') 
db.echo = True 

metadata = MetaData(db) 
Base = declarative_base() 
Session = sessionmaker(bind=db) 
session = Session() 

class Child(Base): 
    __table__ = Table('child', Base.metadata, 
     Column('id', Integer, primary_key=True), 
     Column('parent_id', Integer), 
     Column('name', String(50)) 
    ) 

class Parent(Base): 
    __table__ = Table('parent', Base.metadata, 
     Column('id', Integer, primary_key=True), 
     Column('name', String(50)) 
    ) 

    children = relationship(Child, primaryjoin="Parent.id == Child.parent_id", 
          foreign_keys=[__table__.c.id]) 



Base.metadata.create_all(db) 

c = Child(id=1, name="C") 
p = Parent(id=1, name="P", children=[c]) 
session.add(p) 
session.commit() 

運行此給出了session.add(p)AttributeError: 'list' object has no attribute '_sa_instance_state'

我試圖改變類這樣的:

class Child(Base): 
    __tablename__ = 'child' 

    id = Column('id', Integer, primary_key=True) 
    parent_id = Column('parent_id', Integer, ForeignKey('parent.id')) 
    name = Column('name', String(50)) 

class Parent(Base): 
    __tablename__ = 'parent' 

    id = Column('id', Integer, primary_key=True) 
    name = Column('name', String(50)) 

    children = relationship(Child, backref="parent") 

,然後它的作品。我指定parent_id是一個外鍵,並使用backref語法。但是在我的生產代碼中,Parent表是一個臨時表,所以我不能直接使用ForeignKey來引用它。那麼第一個代碼塊有什麼問題,它如何解決?

回答

0

從SQLAlchemy的relationship API的docs

也就是說,如果這種關係)的primaryjoin條件(是a.id == b.a_id,並且需要在b.a_id值要存在於a.id中,則此關係()的「外鍵」列是b.a_id。

在你的例子中,child.parent_id需要存在於parent.id。所以你的「外鍵」欄是child.parent_id

因此,改變:

foreign_keys=[__table__.c.id] 

這樣:

foreign_keys=[Child.__table__.c.parent_id] 

應該解決您的問題。