sqlalchemy один-ко-многим без единого ограничения - PullRequest
0 голосов
/ 25 января 2019

Я использую sqlalchemy для моделирования следующих отношений:

  • Есть остановки, и многие остановки могут иметь одно и то же имя.
  • Есть переводы, и несколько переводов используютодно и то же имя остановки (но разные языки).Чтобы одно имя остановки могло быть переведено на многие языки.

Поскольку имя остановки не является уникальным среди остановок, sqlaclhemy + postgres не нравится, когда я пытаюсь создать отношение один ко многим(увидеть ниже).Но это не совсем один ко многим.Когда я получаю доступ к файлу stop.translations, я хочу получить все переводы, соответствующие этому запросу: SELECT * from translation WHERE translation.stop_name == stop.stop_name.Так что я принимаю фактическое соотношение «многие ко многим» здесь, но хочу скрыть это от моих пользователей, чтобы оно выглядело как «один ко многим».

Я думал об использовании гибридных атрибутов, но они, похоже,быть только скалярным, так что это не совсем вариант.Я, вероятно, плохо справился с попыткой предварительно заполнить отношения многие ко многим, потому что это заняло вечность и истекло время ожидания.

Некоторый контекст: это часть pygtfs, но вот минимальный пример того, когда этопойдет не так.Когда я запускаю следующий скрипт:

import sqlalchemy
import sqlalchemy.orm
from sqlalchemy import Column
from sqlalchemy.types import Unicode
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Stop(Base):
    __tablename__ = 'stop'
    stop_id = Column(Unicode, primary_key=True)
    stop_name = Column(Unicode)

    # What I'd like:
    translations = sqlalchemy.orm.relationship('Translation', viewonly=True,
            primaryjoin="stop.c.stop_name==translation.c.stop_name")

class Translation(Base):
    __tablename__ = 'translation'
    stop_name = Column(Unicode, primary_key=True)
    lang = Column(Unicode, primary_key=True)
    translation = Column(Unicode)

if __name__ == "__main__":
    engine = sqlalchemy.create_engine("postgresql://postgres@localhost:5432")
    Session = sqlalchemy.orm.sessionmaker(bind=engine)

    session = Session()
    session.add(Stop(stop_id="hrld", stop_name="Herald Square"))

Я получаю:

[...]
sqlalchemy.exc.ArgumentError: Could not locate any relevant foreign key columns for primary join condition 'stop.stop_name = translation.stop_name' on relationship Stop.translations.  Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation.

Что я могу сделать, чтобы отобразить это в sqlaclhemy?

[редактировать после комментария]: Если я добавляю ForeignKey, он завершается ошибкой, потому что имя_стопа не уникально (и я не хочу, чтобы оно было уникальным!):

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) there is no unique constraint matching given keys for referenced table "translation"
[SQL: '\nCREATE TABLE stop (\n\tstop_id VARCHAR NOT NULL, \n\tstop_name VARCHAR, \n\tPRIMARY KEY (stop_id), \n\tFOREIGN KEY(stop_name) REFERENCES translation (stop_name)\n)\n\n'] (Background on this error at: http://sqlalche.me/e/f405)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...