当前位置: 首页 > 面试题库 >

如何在SQLAlchemy ORM上回引用同一属性的情况下实现自引用多对多关系?

诸葛康胜
2023-03-14
问题内容

我正在尝试使用SQLAlchemy上的声明性实现自引用的多对多关系。

该关系表示两个用户之间的友谊。在网上(在文档和Google中)我都发现了如何建立自我参照的m2m关系,以某种方式区分角色。这意味着,在这种m2m关系中,UserA例如是UserB的老板,因此他在“下属”属性或您拥有的内容下列出了他。以相同的方式,用户B在“上级”下列出了用户A。

这是没有问题的,因为我们可以用这种方式声明对同一表的backref:

subordinates = relationship('User', backref='superiors')

因此,当然,“优级”属性在类中并不明确。

无论如何,这是我的问题:如果我想对引用backref的同一属性进行反向引用怎么办?像这样:

friends = relationship('User',
                       secondary=friendship, #this is the table that breaks the m2m
                       primaryjoin=id==friendship.c.friend_a_id,
                       secondaryjoin=id==friendship.c.friend_b_id
                       backref=??????
                       )

这是有道理的,因为如果A与B成为朋友,那么关系角色是相同的,并且如果我调用B的朋友,我应该得到带有A的列表。这是完整的有问题的代码:

friendship = Table(
    'friendships', Base.metadata,
    Column('friend_a_id', Integer, ForeignKey('users.id'), primary_key=True),
    Column('friend_b_id', Integer, ForeignKey('users.id'), primary_key=True)
)

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)

    friends = relationship('User',
                           secondary=friendship,
                           primaryjoin=id==friendship.c.friend_a_id,
                           secondaryjoin=id==friendship.c.friend_b_id,
                           #HELP NEEDED HERE
                           )

抱歉,如果文本太多,我只是想尽可能地明确。我似乎在网上找不到任何参考资料。


问题答案:

这是我今天早些时候在邮件列表中暗示的UNION方法。

from sqlalchemy import Integer, Table, Column, ForeignKey, \
    create_engine, String, select
from sqlalchemy.orm import Session, relationship
from sqlalchemy.ext.declarative import declarative_base

Base= declarative_base()

friendship = Table(
    'friendships', Base.metadata,
    Column('friend_a_id', Integer, ForeignKey('users.id'), 
                                        primary_key=True),
    Column('friend_b_id', Integer, ForeignKey('users.id'), 
                                        primary_key=True)
)


class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)

    # this relationship is used for persistence
    friends = relationship("User", secondary=friendship, 
                           primaryjoin=id==friendship.c.friend_a_id,
                           secondaryjoin=id==friendship.c.friend_b_id,
    )

    def __repr__(self):
        return "User(%r)" % self.name

# this relationship is viewonly and selects across the union of all
# friends
friendship_union = select([
                        friendship.c.friend_a_id, 
                        friendship.c.friend_b_id
                        ]).union(
                            select([
                                friendship.c.friend_b_id, 
                                friendship.c.friend_a_id]
                            )
                    ).alias()
User.all_friends = relationship('User',
                       secondary=friendship_union,
                       primaryjoin=User.id==friendship_union.c.friend_a_id,
                       secondaryjoin=User.id==friendship_union.c.friend_b_id,
                       viewonly=True)

e = create_engine("sqlite://",echo=True)
Base.metadata.create_all(e)
s = Session(e)

u1, u2, u3, u4, u5 = User(name='u1'), User(name='u2'), \
                    User(name='u3'), User(name='u4'), User(name='u5')

u1.friends = [u2, u3]
u4.friends = [u2, u5]
u3.friends.append(u5)
s.add_all([u1, u2, u3, u4, u5])
s.commit()

print u2.all_friends
print u5.all_friends


 类似资料:
  • 我决定在我最近开始的项目中使用JPA 2.1的实体图功能,但我遇到了一个问题。 当您将图形扩展到 ManyToOne 关系上时,效果很好,但对于 OneToMany,结果会重复,因为我的提供程序(Hibernate)使用左外连接。 我看到一些解决方案,他们提出了独特的关键字来解决这个问题,但我认为这是一个棘手的解决方案,即使我们如何才能让下一级实体不同。 我的意思是,如果我有3个实体A、B和C,我

  • 我想在Spring用石英调度器。配置多个作业时,我得到以下异常 Job2中方法jobTrigger的参数0需要类型为“org.quartz.jobDetail”的bean,但找不到该bean。 石英-V2.3,Spring-V4.2.x 配置类 春装工厂 @AutoWired私服服务; 如果只有一个作业使用这个autowired bean,那么也没有例外。如何使用相同的自动连线依赖关系配置多个作业

  • 我需要在Firestore上建立多对多关系模型。以下是对这些要求的总结。 > 一家公司可以为一个项目雇佣许多承包商。承包商可以在不同的时间为多家公司的不同项目工作。 承包商或公司的数量不应受到限制,即应使用集合或子集合。 承包商应能够按公司进行查询;反之亦然,公司应该能够通过承包商进行查询。例如,(1)承包商可能要求提供他/她工作过的公司的清单,并按项目排序 就公司而言,承包商可以改变状态,例如工

  • 我添加数据的表单如下所示: 当klik保存时,它将调用控制器 我的控制器是这样的: 我的服务是这样的: 我的模型用户是这样的: 所以我有3个表:users表、users\u banks表(pivot表)和master\u datas表 类型为bank的主数据表中的银行名称列表 Users表具有字段id、名称、电子邮件、密码等= Master_datas表有字段id(这是银行id)、名称(这是银行名

  • 使用JSON Schema 7执行验证 是否可以使用json模式进行以下验证。 object 中的“prop” 属性是属性中的依赖值。 即只有“properties.name”存在,那么该值可以添加到“prop”数组中 注意: “属性”数组可以具有{name:}类型的任何对象 “name”可以有任何可能的字符串,我事先不知道 我一直在查阅文件,但能找到一个答案。 Json Schema中还不支持此

  • 问题内容: 我的大脑开始为此烦恼,这很简单: 问题答案: 就像是: