我有一个数据库模型(见下文)。我正在研究一个项目,该项目应根据用户分配的类别过滤查询结果-可能有多个与用户相关联的类别。换句话说,我想显示User
与Articles
匹配的他/她分配的类别。 Articles
也可以与多个类别相关联。如何使用sqlalchemy查询实现此目标?
categories_users = db.Table(
'categories_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('category_id', db.Integer(), db.ForeignKey('category.id'))
)
categories_articles = db.Table(
'categories_articles',
db.Column('article_id', db.Integer(), db.ForeignKey('article.id')),
db.Column('category_id', db.Integer(), db.ForeignKey('category.id'))
)
class Category(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
articles = db.relationship('Article', secondary=categories_articles,
backref=db.backref('categories', lazy='dynamic'))
def __str__(self):
return self.name
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
def __str__(self):
return self.name
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True, nullable=False)
categories = db.relationship('Category', secondary=categories_users,
backref=db.backref('users', lazy='dynamic'))
def __str__(self):
return self.email
答案 0 :(得分:0)
在普通m2m中,您具有一个关联表,该表具有两个实体之间的连接路径,该路径由外键明确定义。这样,您只需告诉sqlalchemy您想要使用哪个表来关联其他两个表,其余的就由它完成(如您在此处所做的操作:secondary=categories_articles
)。将User
与Article
的连接稍微复杂些。
您希望User
和Article
之间存在多对多关系,因此您可以根据常见类别获得用户感兴趣的文章。或者简单地:
User
<===> some join path involving categories
<===> Article
。
我们的user
表具有categories_users
表的外键,而我们的categories_articles
表具有articles
表的外键。最重要的是,categories_users
表和categories_articles
表都具有category_id
字段,因此我们可以将这两个表连接在一起。
因此,您可以使用以下代码向您的articles
模型添加User
关系:
articles = db.relationship(
'Article',
secondary=\
'join(categories_users, categories_articles, '
'categories_users.c.category_id==categories_articles.c.category_id)'
)
访问User.articles
属性然后发出此SQL:
SELECT article.id AS article_id, article.name AS article_name
FROM article, categories_users
INNER JOIN categories_articles
ON categories_users.category_id = categories_articles.category_id
WHERE %(param_1)s = categories_users.user_id
AND article.id = categories_articles.article_id
很明显可以看到发生了什么。 categories_users
与categories_articles
结合在一起,有效地创建了一个新表,其中user
行与article
行在它们的共同类别上组合在一起。然后,SQLAlchemy可以将其视为具有单个关联表的“正常”多对多关系,并利用现有的外键将其余关系拼凑起来,并构造必要的查询。