我有一个数据库模型,我需要一对多的关系和两个一对一的关系.这是我制作的模型,但它会抛出错误
class Page(Base):
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)
title = Column(String(100), nullable=False)
content = Column(Text, nullable=False)
parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
children = relationship("Page", backref=backref("parent", remote_side=id))
next_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
next = relationship("Page", backref=backref("prev", remote_side=id, uselist=False))
prev_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
prev = relationship("Page", backref=backref("next", remote_side=id, uselist=False))
def __init__(self, title, content, parent_id=None, next_id=None, prev_id=None):
self.title = title
self.content = content
self.parent_id = parent_id
self.next_id = next_id
self.prev_id = prev_id
def __repr__(self):
return '<Page "%r">' % self.title
Run Code Online (Sandbox Code Playgroud)
每当我尝试对数据库做任何事情时,我都会收到以下错误
ArgumentError: Could not determine join condition between parent/child tables on relationship Page.children. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well.
Run Code Online (Sandbox Code Playgroud)
真正奇怪的是它没有下一个和上一个列的工作.谁知道什么是错的?
let*_*bee 15
这个话题很古老,但由于这太令人困惑,我会把它写下来.
你不需要单独的'prev'列,你已经将它作为'next'的backref.此外,由于同一目标有多个外键,因此需要手动指定主连接:
class Page(Base):
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)
title = Column(String(100), nullable=False)
content = Column(Text, nullable=False)
parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
parent = relationship("Page",
primaryjoin=('pages.c.id==pages.c.parent_id'),
remote_side='Page.id',
backref=backref("children" ))
next_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
next = relationship("Page",
primaryjoin=('pages.c.next_id==pages.c.id'),
remote_side='Page.id',
backref=backref("prev", uselist=False))
Run Code Online (Sandbox Code Playgroud)
我注意到几个错误或一些奇怪的行为:
- 你只能使用remote_side="Page.id",remote_side=[id]而不是remote_side=["Page.id"],或者它不会起作用(sqlalchemy 0.6.6).这很令人讨厌.
- 看起来你总是应该使用remote_side主键,无论你的实际远程是什么.remote_side="Pages.next_id"即使看起来合适,也会产生奇怪的错误.
- primaryjoin表达式令人困惑,因为它不使用别名,但这实际上是正确的方法.绑定引擎知道要用参数替换哪个表达式(这种方式过于隐含并且与Zen,btw相反).
您可以使用foreign_keys:
class Page(Base):
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)
title = Column(String(100), nullable=False)
content = Column(Text, nullable=False)
parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
parent = relationship("Page",
foreign_keys=[parent_id],
remote_side=[id],
backref=backref("children" ))
next_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
next = relationship("Page",
foreign_keys=[next_id],
remote_side=[id],
backref=backref("prev", uselist=False))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4286 次 |
| 最近记录: |