0

我正在使用 sqlalchemy 对以下关系进行建模:

  • 有停靠点,并且许多停靠点可以具有相同的名称。
  • 有翻译,多个翻译使用相同的站点名称(但不同的语言)。这样一站式名称就可以翻译成多种语言。

由于 stop_name 在停靠点中不是唯一的,当我尝试创建一对多关系时,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,它会失败,因为 stop_name 不是唯一的(我不希望它是唯一的!):

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)
4

0 回答 0