请查看底部的更新
我有三节课。我们把它们称为Post
,PostVersion
,和{
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
author_id = db.Column(db.Integer, db.ForeignKey("user.id"))
author = db.relationship("User", backref="posts")
head_id = db.Column(db.Integer, db.ForeignKey("post_version.id"))
HEAD = db.relationship("PostVersion", foreign_keys=[head_id])
added = db.Column(db.DateTime, default=datetime.utcnow)
class PostVersion(db.Model):
id = db.Column(db.Integer, primary_key=True)
editor_id = db.Column(db.Integer, db.ForeignKey("user.id"))
editor = db.relationship("User")
previous_id = db.Column(db.Integer, db.ForeignKey("post_version.id"), default=None)
previous = db.relationship("PostVersion")
pointer_id = db.Column(db.Integer, db.ForeignKey("post.id"))
pointer = db.relationship("Post", foreign_keys=[pointer_id])
post = db.Column(db.Text)
modified = db.Column(db.DateTime, default=datetime.utcnow)
tag_1_id = db.Column(db.Integer, db.ForeignKey("tag.id"), default=None)
tag_2_id = db.Column(db.Integer, db.ForeignKey("tag.id"), default=None)
tag_3_id = db.Column(db.Integer, db.ForeignKey("tag.id"), default=None)
tag_4_id = db.Column(db.Integer, db.ForeignKey("tag.id"), default=None)
tag_5_id = db.Column(db.Integer, db.ForeignKey("tag.id"), default=None)
tag_1 = db.relationship("Tag", foreign_keys=[tag_1_id])
tag_2 = db.relationship("Tag", foreign_keys=[tag_2_id])
tag_3 = db.relationship("Tag", foreign_keys=[tag_3_id])
tag_4 = db.relationship("Tag", foreign_keys=[tag_4_id])
tag_5 = db.relationship("Tag", foreign_keys=[tag_5_id])
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
tag = db.Column(db.String(128))
为了创建一个新的post,我创建了一个post和一个PostVersion
指向的初始Post.head_id
。每次进行编辑时,都会创建一个指向上一个PostVersion
的新的PostVersion
,而{PostVersion
。要将post版本重置为早期版本——嗯,我还没有走到那么远,但是复制以前的版本或只是将指针重置到以前的版本似乎很简单。在
不过,我的问题是:如何编写Post
和{
Post.tags
将是当前{Tag.posts
将是当前具有该特定标记的所有{第一个条件似乎很简单,一个简单的方法
^{pr2}$这个技巧暂时还可以,但第二个条件现在对我来说几乎是棘手的。我目前在Tag中使用了一种令人讨厌的方法,我使用一个or_
过滤器查询带有该标记的所有PostVersion
:
这是非常低效的,我不能分页的结果。在
我知道这将是从Post
到Tag
或{
回顾我的代码,我开始想知道为什么有些关系需要定义foreign_keys
参数,而另一些则不需要。我认为这与它们的定义位置有关(是否紧跟在FK id列之后),并注意到有一个foreign_keys
的列表,我在想这就是我应该如何定义的它。但我不知道该怎么做。在
我现在还想知道是否可以用一个配置良好的关系来免除pointer_id
上的PostVersion
。然而,这与问题无关(尽管循环引用确实会引起头痛)。在
作为参考,我使用了Flask SQLAlchemy、Flask migrate和MariaDB。我非常关注Miguel Grinberg's Flask Megatutorial。在
任何帮助或建议都是天赐之物。在
我设计了以下mysql查询,它的工作原理是,现在我需要将其转换为sqlalchemy:
SELECT
post.id, tag.tag
FROM
post
INNER JOIN
post_version
ON
post.head_id=post_version.id
INNER JOIN
tag
ON
post_version.tag_1_id=tag.id OR
post_version.tag_2_id=tag.id OR
post_version.tag_3_id=tag.id OR
post_version.tag_4_id=tag.id OR
post_version.tag_5_id=tag.id OR
WHERE
tag.tag="<tag name>";
我自己解决了这个问题,它实际上只包括在主连接中定义一个主连接和一个辅助连接:
我可以把名字和表格混在一起。我会在实验时更新答案,使之更具规律性。在
你能改变数据库的设计吗,还是必须让你的应用程序在你不能改变的数据库上工作?如果是后者,我帮不了你。如果你能改变设计,你应该这样做:
用Post-to-PostVersions之间的一对多关系替换PostVersions的链接链。您的“Post”类最终将与与该Post相关的PostVersion的所有实例具有关系“versions”。
使用附加的关联表将tag_id成员替换为多对多关系。
这两种方法在SQLAlchemy文档中都有很好的解释。一定要从最少的代码开始,在小型的非烧瓶命令行程序中进行测试。一旦你完成了基本功能,就把这个概念转移到更复杂的类中。之后,再问自己最初的问题。答案会来得容易得多。在
相关问题 更多 >
编程相关推荐