我已經有一組關係在生產中運行SQLAlchemy 0.9.10一年多了,我期待升級到1.0+。所有測試在簡單升級包後都會通過,但是現在正在記錄新的警告。SQLAlchemy:拒絕多個一對多的列副本
SAWarning:關係 'A.C' 將列test_c.a_id複製到柱 test_a.id,其與關係(一個或多個)相沖突: 'A·B'(拷貝 test_b.a_id到test_a.id)。考慮將viewonly = True應用於 只讀關係,或者使用foreign()註釋提供標記 可寫列的主連接條件。
我儘可能地簡化了表格來演示。
的想法是,父A
有表現爲一對那些由每個孩子的家長表示他們的「電流」 ID兩個一對多子女關係(B
和C
)。
class A(Base):
__tablename__ = 'test_a'
id = Column(BigInteger, primary_key=True, autoincrement='ignore_fk')
b_id = Column(BigInteger)
c_id = Column(BigInteger)
__table_args__ = (
ForeignKeyConstraint(
['id', 'b_id'],
['test_b.a_id', 'test_b.id'],
use_alter=True,
name='a_b_fk',
),
ForeignKeyConstraint(
['id', 'c_id'],
['test_c.a_id', 'test_c.id'],
use_alter=True,
name='a_c_fk',
),
)
class B(Base):
__tablename__ = 'test_b'
id = Column(BigInteger, autoincrement=True, primary_key=True)
a_id = Column(ForeignKey('test_a.id'), primary_key=True)
class C(Base):
__tablename__ = 'test_c'
id = Column(BigInteger, autoincrement=True, primary_key=True)
a_id = Column(ForeignKey('test_a.id'), primary_key=True)
# A has exactly one *current* B
A.b = sa_orm.relationship(
B,
primaryjoin=sa_sql.and_(A.id == B.a_id,
A.b_id == B.id),
uselist=False,
)
# Every C refers to a single A
C.a = sa_orm.relationship(
A,
primaryjoin=C.a_id == A.id,
foreign_keys=[C.a_id],
)
# Conversely, every A has zero or one C
A.c = sa_orm.relationship(
C,
primaryjoin=sa_sql.and_(A.id == C.a_id,
A.c_id == C.id),
uselist=False,
)
使用viewonly
不是一個選項,因爲關係中的某些列會寫入。 我試過每個組合都可以想到關於關係定義的foreign()
,但是我仍然沒有能夠在仍然具有代碼功能時得到警告停止。在閱讀完文檔和SA代碼庫的很大一部分之後,我似乎被困在如何設置它。
據我所知,我需要在B
和C
上表示A.id
的值是不可變的。
- 我在正確的軌道上嗎?
- 有沒有什麼值得在the docs以外尋求幫助的例子呢?
- 我的疼痛是由
primaryjoin
使用and_()
這一事實引起的嗎?