我試圖在現有數據庫上設置一對多關係。一對多關係使用sqlalchemy中的反射和聲明語法定義連接條件錯誤
簡化DDL是:
create table accnt (
code varchar(20) not null
, def varchar(100)
, constraint pk_accnt primary key (code)
);
commit;
create table slorder (
code varchar(20) not null
, def varchar(100)
, dt date
, c_accnt varchar(20) not null
, constraint pk_slorder primary key (code)
, constraint fk_slorder_accnt foreign key (c_accnt)
references accnt (code)
on update cascade on delete cascade
);
commit;
SQLAlchemy的代碼:
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import *
engine = create_engine('firebird://sysdba:[email protected]/d:\\prj\\db2\\makki.fdb?charset=WIN1254', echo=False)
Base = declarative_base()
Base.metadata.bind = engine
class Accnt(Base):
__tablename__ = 'accnt'
__table_args__ = {'autoload': True}
defi = Column('def', String(100))
class SlOrder(Base):
__tablename__ = 'slorder'
__table_args__ = {'autoload': True}
defi = Column("def", String(100))
accnt = relationship('Accnt', backref='slorders')
給
sqlalchemy.exc.ArgumentError: Could not determine join condition between parent/child tables on relationship SlOrder.accnt. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well.
錯誤。
我對這個問題的可能解決方案是:
class SlOrder(Base):
__tablename__ = 'slorder'
__table_args__ = {'autoload': True}
defi = Column("def", String(100))
c_accnt = Column("c_accnt", String(20), ForeignKey('accnt.code'))
accnt = relationship('Accnt', backref='slorders')
但這種方法需要,我必須手動添加每一個外鍵約束列,這會導致使反射useles。 (因爲我有很多列的引用其他表。)
class SlOrder(Base):
__table__ = Table('accnt', metadata, autoload = True, autoload_with=engine)
accnt = relationship('Accnt', backref='slorders', primaryjoin=(__table__.c_accnt==Accnt.code))
這種方法有一個另一個後果(請參閱my previous question)
所以我缺少什麼?使用反射和聲明式語法來定義關係的最佳方式是什麼?
編輯:
我已經想通SQLAlchemy的發現和建立關係,如果孩子表只有一個引用父表。
但如果孩子表中有多於一個參考:
create table slorder (
code varchar(20) not null
, def varchar(100)
, dt date
, c_accnt varchar(20) not null
, c_accnt_ref varchar(20)
, constraint pk_slorder primary key (code)
, constraint fk_slorder_accnt foreign key (c_accnt)
references accnt (code)
on update cascade on delete cascade
, constraint fk_slorder_accnt_ref foreign key (c_accnt_ref)
references accnt (code)
on update cascade on delete no action
);
發生上述錯誤。
因此,如果兩個表之間存在多個關係,那麼SqlAlchemy的預期行爲會產生錯誤?
1.是的,我確實有 2.火鳥沒有架構支持 3. SQLAlchemy的正確發現我的外鍵和它的屬性。 – ctengiz
嗯,你真的回答你的問題。不幸的是你原來的(簡化)代碼沒有公開這個問題,這是多個FK到父表的確實存在。爲了完整性,我會更新我的答案。 – van
...我很驚訝,儘管你的解決方案'1.'工作雖然... – van