我在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()
运行此操作会从AttributeError: 'list' object has no attribute '_sa_instance_state'
提供session.add(p)
。
我尝试将类更改为:
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 :(得分:0)
来自docs中的SQLAlchemy relationship
API:
也就是说,如果此relationship()的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]
应该解决你的问题。