【发布时间】:2020-08-12 03:29:07
【问题描述】:
我正在尝试使用几个相关模型构建一个示例,如下所示。 我们有一个模型 B 与模型 C 的关系为 1:n;那么我们有一个模型 A,它与 B 的关系为 n:1,与 C 的关系为 n:1。(C 有一个 2 列的主键)
我试过这段代码:
class C(db.Model):
__tablename__ = 'C'
key1 = Column(Integer, primary_key=True)
key2 = Column(Integer, primary_key=True)
attr1 = Column(Date)
attr2 = Column(Boolean)
related_b = Column(Integer, ForeignKey('B.spam'))
class B(db.Model):
__tablename__ = 'B'
spam = Column(Integer, default=1, primary_key=True)
eggs = Column(String, default='eggs')
null = Column(String)
n_relation = relationship(C, foreign_keys='C.related_b')
class A(db.Model):
__tablename__ = 'A'
foo = Column(String, default='foo', primary_key=True)
bar = Column(String, default='bar', primary_key=True)
baz = Column(String, default='baz')
rel = relationship(B, foreign_keys='A.related_b')
related_b = Column(Integer, ForeignKey('B.spam'))
related_c1 = Column(Integer, ForeignKey('C.key1'))
related_c2 = Column(Integer, ForeignKey('C.key2'))
other_rel = relationship(C, foreign_keys=(related_c1, related_c2))
只是为了获得例外:
sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship A.other_rel - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.
但是,嘿,我已经通过了那个论点。 我为该参数尝试了各种版本,指定 A 列,通过名称指定 C 列,通过直接引用指定 C 列,似乎没有任何影响此错误。 我还尝试使用单个复合外键,如下所示:
class A(db.Model):
__tablename__ = 'A'
foo = Column(String, default='foo', primary_key=True)
bar = Column(String, default='bar', primary_key=True)
baz = Column(String, default='baz')
rel = relationship(B, foreign_keys='A.related_b')
related_b = Column(Integer, ForeignKey('B.spam'))
related_c1 = Column(Integer, ForeignKey('C.key1'))
related_c2 = Column(Integer, ForeignKey('C.key2'))
compound = ForeignKeyConstraint(('related_c1', 'related_c2'), ('C.key1', 'C.key2'))
other_rel = relationship(C, foreign_keys=compound)
但没有任何改变。 我弄错了什么还是一个错误? (至少,错误信息不正确……)
【问题讨论】:
-
在我看来,如果你让 A 成为 C 的孩子,那么你试图直接让 A 成为 B 的孩子是多余的,因为 C 是 B 的孩子。在 A 对象中有
related_b没有必要,因为related_c还将确定与该 A 相关的 B。 (顺便说一句,更有意义的对象名称可能会更好地传达您的意图。) -
关系 A -> B 和 A -> C 是独立的。每个 A 对象都有一个 B“父级”和一个 C“父级”(如果您愿意,可以称它们为母亲和父亲)。反过来,B 对象与几个 C 对象相关(其中一个可能与 A 相关,也可能不相关)。 (他们可能是……母亲的朋友?)
-
换句话说,A.other_rel.related_b 可能等于也可能不等于 A.related_b
-
我在 SQLAlchemy 中没有看到任何错误。 This code 对我来说很好。
-
它有一些不同。如果我理解正确,在您的代码中,每个关系都是 1:1,而在我的代码中有 n:1 关系。此外,在我的代码中,C 有一个 2 列主键,我不知道这是否是问题的一部分,但可能是。
标签: python orm sqlalchemy foreign-keys relationship