【问题标题】:Flask relationship model multiple get or create if not existFlask 关系模型多次获取或创建(如果不存在)
【发布时间】:2012-02-25 20:15:28
【问题描述】:

我刚开始在烧瓶中使用 Flask 和 SQLAlchemy。

所以我有一个多对多关系使用这里的例子http://docs.sqlalchemy.org/en/latest/orm/tutorial.html 如果您向下滚动到关于关键字和标签的部分,这就是我正在做的事情。 到目前为止,我能够插入与我的帖子相关的新关键字,并且我正在使用 append。我知道这是错的。所以会发生的是,下一次在博客文章中出现非唯一关键字时,它会抛出关于 Conflict with Keyword 的错误(因为关键字应该是唯一的)

我知道正确的方法是另外一回事,我只是不知道是什么。我看过一个例子 get_or_create(keyword) 基本上按关键字过滤,如果找不到,则添加它。但是我相信随着数据量的增长,这也是错误的。 (每次保存都需要多次调用)。我喜欢 SQLAlchemy 自动进行多次插入的方式。我希望保留它,但要避免这个重复的密钥问题。

编辑:找到解决方案,SQLAlchemy 文档会引导您出错,但解释就在那里。我已经添加了答案。

【问题讨论】:

  • 顺便说一句,我正在为相关模型使用附加。像这样。 post.keywords.append(Keyword("foo")) 然后调用 commit.
  • 你能发布你的模型并添加一些真实的代码吗?
  • 我更新了帖子。我已经尝试过像 merge() 这样的东西,它显然不会做任何事情并且什么也不做。第二个页面加载总是会导致错误。我只想将不存在的游戏(标签)添加到游戏表和用户游戏(如果不存在)。当然,我不能有一个在用户游戏中的游戏,但不是游戏。那部分没问题。我收到 Game() 的重复错误

标签: python many-to-many sqlalchemy bulkinsert flask


【解决方案1】:

好的,经过数小时的反复试验,我找到了解决方案,以及我做错的事情。

这就是 SQL 炼金术的工作原理。答案是合并。

将标签列表作为标签模型,只要您的主键是名称或唯一的东西,它们是否存在都无关紧要。

tags = [Tag('a1'),Tag('a2')]

假设您在 DB 中已经有标签 a1,但我们并不关心。我们想要的只是在相关数据不存在时插入。这就是 SQLalchemy 所做的。 现在你用我们制作的所有标签的列表创建一个帖子。如果它只有一个,它也是一个列表。

因此

new_post = Post('a great new post',post_tags=tags)
db.session.merge(new_post)
db.session.commit()

我使用过 Flask 语法,但想法是一样的。只要确保您没有在会话之外创建模型。更有可能的是,你不会这样做。

这实际上很简单,但在 SQLAlchemy 文档中没有提到这个例子。他们使用 append() 这是错误的。只是为了知道您没有重复创建新标签。

希望对你有帮助。

【讨论】:

  • merge() 仅适用于 Tag() 将字符串内容“a1”、“a2”作为其主键,即自然主键 - 因为 merge() 仅处理主键键。一个更通用的“X 上唯一的对象”配方位于 sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject - 这或多或少超出了本教程的范围。本教程中“append()”的使用并非“错误”,它说明了多对多关系的工作原理。 merge() 在教程示例中也不起作用,因为关键字有一个代理 pk。
猜你喜欢
  • 1970-01-01
  • 2020-12-25
  • 2019-01-12
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2022-07-20
  • 2018-07-26
相关资源
最近更新 更多