Я пытаюсь установить отношение «один ко многим» в существующей базе данных.
Упрощенный 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:masterkey@127.0.0.1/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.
.
Мои возможные решения этой проблемы:
1
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')
Но этоПодход требует, чтобы мне пришлось добавить каждый столбец ограничения внешнего ключа вручную, что приводит к созданию отражений.(Поскольку у меня есть много ссылок на столбцы на другие таблицы.)
2
class SlOrder(Base):
__table__ = Table('accnt', metadata, autoload = True, autoload_with=engine)
accnt = relationship('Accnt', backref='slorders', primaryjoin=(__table__.c_accnt==Accnt.code))
У этого подхода есть еще одно последствие (см. мой предыдущийвопрос )
Так чего мне не хватает?Каков наилучший способ определить отношения, используя рефлексию и декларативный синтаксис?
EDIT:
Я понял, что 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 выдаст ошибку, если между двумя таблицами существует более одного отношения?