我正在使用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)