Python sqlalchemy一对多关系,其中该外键在模型中使用两次
我有这样一个简单的模型Python sqlalchemy一对多关系,其中该外键在模型中使用两次,python,sqlalchemy,Python,Sqlalchemy,我有这样一个简单的模型 class ChatMessage(Base): __tablename__ = 'chat_messages' id = Column(Integer, ForeignKey('messages.id')) sender_id = Column(Integer, ForeignKey('users.id')) receiver_id = Column(Integer, ForeignKey('users.id')) 我尝试添加与用户相关的消息
class ChatMessage(Base):
__tablename__ = 'chat_messages'
id = Column(Integer, ForeignKey('messages.id'))
sender_id = Column(Integer, ForeignKey('users.id'))
receiver_id = Column(Integer, ForeignKey('users.id'))
我尝试添加与用户相关的消息
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
chat_messages = relationship("ChatMessage", backref="participants",
foreign_keys="[ChatMessage.sender_id, ChatMessage.receiver_id]")
它给出:
InvalidRequestError:一个或多个映射程序未能初始化-无法继续初始化其他映射程序。最初的异常是:无法确定relationship User.chat_消息上的父/子表之间的联接条件-有多个外键路径链接这些表。指定'foreign_keys'参数,提供那些应被视为包含父表外键引用的列的列表。定义primaryjoin似乎有点帮助,只是append现在不起作用
class User(Backend.instance().get_base()):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
chat_messages = relationship("ChatMessage", backref="participants",
primaryjoin="User.id==ChatMessage.sender_id or User.id==ChatMessage.receiver_id")
看起来定义primaryjoin有点帮助,只是append现在不起作用
class User(Backend.instance().get_base()):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
chat_messages = relationship("ChatMessage", backref="participants",
primaryjoin="User.id==ChatMessage.sender_id or User.id==ChatMessage.receiver_id")
在创建两个类后设置特殊关系
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, backref
engine = sa.create_engine('sqlite:///test.db', echo=True)
Session = sessionmaker(bind=engine)
Base = declarative_base(bind=engine)
class User(Base):
__tablename__ = 'users'
id = sa.Column(sa.Integer, primary_key=True)
class ChatMessage(Base):
__tablename__ = 'chat_messages'
id = sa.Column(sa.Integer, primary_key=True)
sender_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
receiver_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
content = sa.Column(sa.String, nullable=False)
__table_args__ = (
sa.CheckConstraint(receiver_id != sender_id),
)
sender = relationship(User, foreign_keys=sender_id, backref='sent_chat_messages')
receiver = relationship(User, foreign_keys=receiver_id, backref='received_chat_messages')
User.chat_messages = relationship(ChatMessage, primaryjoin=sa.or_(
User.id == ChatMessage.sender_id,
User.id == ChatMessage.receiver_id
), backref=backref('participants', uselist=True, viewonly=True), viewonly=True)
之所以使用
viewonly=True
,是因为此关系使用自定义联接,并且如果数据发生更改,SQLAlchemy不知道该怎么办。例如,如果附加到参与者,它会将用户添加为发送者还是接收者?在创建这两个类后设置特殊关系
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, backref
engine = sa.create_engine('sqlite:///test.db', echo=True)
Session = sessionmaker(bind=engine)
Base = declarative_base(bind=engine)
class User(Base):
__tablename__ = 'users'
id = sa.Column(sa.Integer, primary_key=True)
class ChatMessage(Base):
__tablename__ = 'chat_messages'
id = sa.Column(sa.Integer, primary_key=True)
sender_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
receiver_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
content = sa.Column(sa.String, nullable=False)
__table_args__ = (
sa.CheckConstraint(receiver_id != sender_id),
)
sender = relationship(User, foreign_keys=sender_id, backref='sent_chat_messages')
receiver = relationship(User, foreign_keys=receiver_id, backref='received_chat_messages')
User.chat_messages = relationship(ChatMessage, primaryjoin=sa.or_(
User.id == ChatMessage.sender_id,
User.id == ChatMessage.receiver_id
), backref=backref('participants', uselist=True, viewonly=True), viewonly=True)
之所以使用viewonly=True
,是因为此关系使用自定义联接,并且如果数据发生更改,SQLAlchemy不知道该怎么办。例如,如果附加到参与者,它会将用户添加为发送者还是接收者