【发布时间】:2018-02-24 00:52:27
【问题描述】:
我正在使用 SQLAlchemy 对以下概念进行建模:
- 一个用户可以是一个
member_of一个组 - 一个群组可以有多个用户
members,并且可以提供access_to多个Nodes。 - 一个节点可以是
accessed_by多个Groups
我正在使用关联表模式为用户 -> 组和节点 -> 组创建多对多关系。
代码如下(我使用的是 Flask-SQLAlchemy,这就是为什么我有 db.Model 等)
如何查询用户所属的所有组可以访问的所有节点?
这是对象模型
group_access = Table('access', db.metadata,
Column('group_id', Integer, ForeignKey('groups.group_id')),
Column('nid', BigInteger, ForeignKey('nodes.nid')),
)
group_membership = Table('membership', db.metadata,
Column('group_id', Integer, ForeignKey('groups.group_id')),
Column('uid', Integer, ForeignKey('users.id')),
)
edges = Table('edges', db.metadata,
Column('src_id', BigInteger, ForeignKey('nodes.nid'), primary_key=True),
Column('dest', BigInteger, ForeignKey('nodes.nid'), primary_key=True),
)
class User(db.Model):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
email = Column(String, unique=True, nullable=False)
member_of = relationship("Group", secondary=group_membership, back_populates='members')
def __init__(self, email):
self.email = email
class Node(db.Model):
__tablename__ = 'nodes'
nid = Column(BigInteger, primary_key=True)
type = Column(String)
parents = relationship("Node",
secondary=edges,
primaryjoin="Node.nid==edges.c.src_id",
secondaryjoin="Node.nid==edges.c.dest",
backref="children")
accessed_by = relationship("Group", secondary=group_access, back_populates='access_to')
def __init__(self, owner=None, type=None):
self.type = type
# self.owner = owner
def __repr__(self):
return "<{} nid:{} >".format(self.type, self.nid)
class Group(db.Model):
__tablename__ = 'groups'
group_id = Column(Integer, primary_key=True)
type = Column(String)
members = relationship("User", secondary=group_membership, back_populates="member_of")
access_to = relationship("Node", secondary=group_access, back_populates="accessed_by")
def __init__(self, name):
self.type = name
def __repr__(self):
return self.type
【问题讨论】:
-
您想如何查询节点?作为单独的查询,或者您想在获取用户时预先加载它们?
-
假设作为一个单独的查询,假设给定用户可以访问的节点本身可能没有父子关系。因此,数据将是一棵树,用户可以在其中访问不同的节点。
标签: python sqlalchemy