sqlalchemy一对多,没有唯一约束

时间:2019-01-25 03:09:48

标签: python postgresql sqlalchemy

我正在使用sqlalchemy为以下关系建模:

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

由于stop_name在站点之间并不是唯一的,因此当我尝试创建一对多关系时,sqlaclhemy + postgres不喜欢它(请参见下文)。但这并不是一对多的。访问stop.translations时,我想要的是获取与此查询匹配的所有翻译:{{1​​}}。因此,我在这里接受实际的多对多关系,但想对我的用户隐藏它,以使其看起来像一对多。

我考虑过使用混合属性,但是它们似乎只是标量,因此这并不是一个选择。我试图完成多对多关系可能做得很糟糕,因为那需要花费很多时间和超时。

某些上下文:这是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中对此进行映射?

[评论后编辑]: 如果添加外键,则失败,因为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)

0 个答案:

没有答案