在一个实体中定义两个外键,目标是 SQLAlchemy 中的另一个实体

问题描述 投票:0回答:1

我的实体设置如下

from sqlalchemy import ForeignKey
from sqlalchemy.orm import mapped_column, relationship, Mapped, DeclarativeBase

class Base(DeclarativeBase):
    pass

class UserEntity(Base):
    __tablename__ = "user"

    id: Mapped[str] = mapped_column(primary_key=True)
    last_message = relationship("MessageEntity", back_populates="from_user", uselist=False)

class MessageEntity(Base):
    __tablename__ = "message"

    id: Mapped[str] = mapped_column(primary_key=True)
    content: Mapped[str] = mapped_column()
    from_user_id: Mapped[str] = mapped_column(ForeignKey('user.id'))
    to_user_id: Mapped[str] = mapped_column(ForeignKey('user.id'))
    # relationships
    from_user = relationship("UserEntity", back_populates="last_message", foreign_keys=[from_user_id], uselist=False)

这描述了某些用户可以拥有他们的最后一条消息,即与

from_user
中的
MessageEntity
列处于一对一关系。现在我想将
to_user_id
存储在
MessageEntity
中,与
UserEntity
没有任何关系,它应该只存储用户的 ID,但是现在当我添加此字段时,我得到了

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship UserEntity.last_message - there are multiple foreign key paths linking the tables.  Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.

我不确定 SQLAlchemy 试图通过

to_user_id
外键来推断哪种关系,但我只希望它存储一个简单的 id,不附加任何字符串。这可能吗?

python sqlalchemy orm
1个回答
0
投票

看来需要指定关系两边的

foreign_keys

第一个定义使用字符串,因为类还没有定义,

foreign_keys="[MessageEntity.from_user_id]"
,在handling-multiple-join-paths底部提到过。

  • 另请注意,您可以在字符串包含列表符号:
    foreign_keys="[MessageEntity.from_user_id]"
  • 或者排除列表符号:
    foreign_keys="MessageEntity.from_user_id"
  • 但是如果您使用字符串,则不能将其留在外面,即。不起作用:
    foreign_keys=["MessageEntity.from_user_id"]
class UserEntity(Base):
    __tablename__ = "user"

    id: Mapped[str] = mapped_column(primary_key=True)
    last_message = relationship("MessageEntity", back_populates="from_user", uselist=False, foreign_keys="[MessageEntity.from_user_id]")

class MessageEntity(Base):
    __tablename__ = "message"

    id: Mapped[str] = mapped_column(primary_key=True)
    content: Mapped[str] = mapped_column()
    from_user_id: Mapped[str] = mapped_column(ForeignKey('user.id'))
    to_user_id: Mapped[str] = mapped_column(ForeignKey('user.id'))
    # relationships
    from_user = relationship("UserEntity", back_populates="last_message", foreign_keys=[from_user_id], uselist=False)
© www.soinside.com 2019 - 2024. All rights reserved.