Alembic迁移困在postgresql?

时间:2014-04-06 16:08:03

标签: python postgresql alembic

我编写了一个在sqlite上工作正常的迁移脚本,但如果我尝试将其应用于postgres,它将永远停留。 通过一个简单的ps我可以看到postres卡在“创建表等待”。 有什么最好的做法吗?

4 个答案:

答案 0 :(得分:23)

如果它真的卡在锁上,你需要看看它在等什么。 CREATE TABLE被卡在锁上是很奇怪的,但这并非不可能。

获取卡住的进程ID

获取等待后端的进程ID。您可以在psSELECT pg_stat_activity中找到它,查找waiting为true的流程,以找到您感兴趣的命令:< / p>

SELECT * FROM pg_stat_activity WHERE waiting;

找出它等待的锁定

通过查询pg_locks来查看卡住的pid正在等待的锁定:

SELECT * FROM pg_locks WHERE pid = <the-waiting-pid> AND NOT granted;

您可以将这两个步骤合并到:

\x

SELECT * 
FROM pg_locks l
INNER JOIN pg_stat_activity s ON (l.pid = s.pid)
WHERE waiting
AND NOT granted;

然后查看结果,或使用LIKE字段上的s.query过滤器来查找您尝试识别锁定问题的查询。

查找持有该锁的人

您现在可以查询pg_locks以找出哪个进程找到了锁定,以及他们正在做什么。

假设我们发现create正在等待关系= relation的locktype = AccessExclusiveLock锁定模式= 14421。我们想找到关于该关系的其他会话持有的锁:

SELECT * 
FROM pg_locks l 
INNER JOIN pg_stat_activity s ON (l.pid = s.pid)
WHERE locktype = 'relation'
AND   relation = 14421;

这应该告诉你阻止创建的内容。

皱纹

a handy lock monitoring query on the PostgreSQL wiki,但它只能找到行级锁。所以它对DDL一般没用。

另外,我故意没有将整个批次合并到一个查询中。在AccessExclusiveLock的情况下,它很容易找到通过pid阻止给定后端的锁定持有者,但是对于较弱的锁定请求,它不是那么简单 - 我必须写出来关于哪些锁与SQL中哪些锁冲突的规则,这非常复杂。最好只关注它。

答案 1 :(得分:3)

你总是可以重新启动postgresql。

答案 2 :(得分:1)

您的数据库很可能被另一个查询锁定。

特别是如果你使用他们的GUI pgAdmin做事,这可能会发生很多我发现。 (截断表格特别棘手,有时pgAdmin崩溃,数据库卡住了)

您要做的是重新启动完整的postgresql服务,然后重试。

请确保你:

  1. 最小化GUI pgadmin的使用
  2. 如果你不需要,请用psycopg2关闭你的游标/ dbs

答案 3 :(得分:0)

对于任何遇到此问题的人,这是为我解决的问题:

标准的alembic env.py包含该段落

with context.begin_transaction():
    logger.info("Running Transaction.")
    context.run_migrations()

但是,如果您随后将迁移引擎中的引擎引入

config = op.get_context().config
engine = engine_from_config(config.get_section(
                            config.config_ini_section), prefix='sqlalchemy.')

该交易将被卡在“空闲交易”中。我不太清楚为什么,但是看起来好像是事务内的事务,而外部事务从未提交。

要解决此问题,只需移除外部的begin_transaction()

# with context.begin_transaction():
logger.info("Running Transaction.")
context.run_migrations()

你应该很好。