【问题标题】:How do you create a table with Sqlalchemy within a transaction in Postgres?如何在 Postgres 的事务中使用 Sqlalchemy 创建表?
【发布时间】:2013-03-24 09:13:13
【问题描述】:

我在多租户 Flask 应用程序中使用 Sqlalchemy,并且需要在添加新租户时动态创建表。我一直在使用 Table.create 在新的 Postgres 架构中创建单独的表(以及 search_path 修改),并且效果很好。

我发现的限制是,如果当前事务中有任何待处理的内容,Table.create 方法会阻塞。我必须在 .create 调用之前提交事务,否则它会阻塞。它似乎没有在 Sqlalchemy 中被阻止,因为您不能 Ctrl-C 它。您必须终止该进程。所以,我假设它在 Postgres 中更进一步。

我在其他答案中读到 CREATE TABLE 是事务性的并且可以回滚,所以我认为这应该可以工作。我尝试使用当前引擎启动新事务并将其用于表创建(与当前的 Flask 相比),但这也无济于事。

有人知道如何在不提前提交的情况下使其工作(并冒部分悬空数据的风险)吗?

这是 Python 2.7、Postgres 9.1 和 Sqlalchemy 0.8.0b2。

【问题讨论】:

  • 刚刚找到关于 DROP 的答案:stackoverflow.com/questions/6778942/… 如果 CREATE 也是如此,那么听起来好像没有办法解决这个问题。
  • Sqlalchemy 上的相关常见问题解答:sqlalchemy.org/trac/wiki/…
  • 您的Table.create 似乎不是在同一个事务中完成的。尝试触发块并检查SELECT * FROM pg_stat_activity的输出。
  • 假设sess 是会话,您可以改为使用sess.execute(CreateTable(tenantX_tableY))
  • 对不起,“触发块”是什么意思?无论如何,我认为你是对的,但我不确定如何让 Sqlalchemy 将创建粘贴到我当前的事务中,因为它需要一个可连接的来执行它。

标签: python postgresql sqlalchemy ddl flask-sqlalchemy


【解决方案1】:

(从评论中复制)

假设sess 是会话,您可以改为使用sess.execute(CreateTable(tenantX_tableY))

编辑:CreateTable 只是调用table.create() 时所做的事情之一。请改用table.create(sess.connection())

【讨论】:

  • 我还在做一件事。我的一个表有一个枚举,而 CreateTable 没有创建它。关于如何处理的任何建议?
  • @DavidK.Hess 嗯.. 我对枚举没有经验。我从事的项目必须支持不同的RDBMS,而枚举是我想用但不能用的东西。
  • 你不想使用 table.create(sess.connection()) 代替吗?这也将执行包含在其中的 ENUM 类型。
  • @zzzeek 对。我错误地认为sess.execute(CreateTable(table))table.create(sess.connection()) 都做同样的事情,并且碰巧更喜欢前者的语法。原来visit_table 的作用远不止CreateTable
  • 嗯,这要好得多,而且直接从源头开始。我从问题中删除了关于 Enum 的更新。
猜你喜欢
  • 1970-01-01
  • 2020-06-05
  • 2010-11-20
  • 2021-05-25
  • 2015-05-04
  • 2022-01-15
  • 1970-01-01
  • 2023-02-02
  • 2014-03-23
相关资源
最近更新 更多