psycopg2、Redshift 和 unittest 的并发问题

Posted

技术标签:

【中文标题】psycopg2、Redshift 和 unittest 的并发问题【英文标题】:Concurrency issue with psycopg2, Redshift, and unittest 【发布时间】:2015-10-21 01:40:00 【问题描述】:

我使用 Python 2.7,使用 psycopg2 连接到 Amazon Redshift 数据库。我有单元测试,在这个测试类的 setUp 和 tearDown 方法中,我删除了为此测试创建的表。所以方案是:

def setUp(self):
    drop_specific_tables()
    create_specific_tables()

def tearDown(self):
    drop_specific_tables()

删除 setUp 和 tearDown 的原因是,如果测试不安全地退出并跳过 tearDown,我们仍然可以知道,无论何时再次运行,它仍然会以全新的状态开始。

这是 drop_specific_tables 方法,而 rcur 是指向我们的 redshift 数据库的 psycopg2 游标。

def drop_specific_tables(rcur):
    rcur.execute("BEGIN;")
    rcur.execute("SELECT table_name "
                 "  FROM information_schema.tables "
                 "  WHERE table_schema='public' ")
    tables = [row for row, in rcur]
    rcur.execute("DROP TABLE IF EXISTS " + ", ".join(tables) + " CASCADE;")
    rcur.execute("END;")

运行单个测试时,它会通过。但是当整个类运行时,setUp或tearDown中的某些测试错误(不确定哪个测试错误和哪个drop_specific_tables),在drop_specific_tables()中,与

rcur.execute("SELECT table_name "
             "  FROM information_schema.tables "
             "  WHERE table_schema='public' ")

产生错误ProgrammingError: Relation with OID 1454844 does not exist. 我打印了“information_schema.tables”的 OID,它与错误消息中的 OID 不同。

为什么会发生这种情况?我明白关系不存在意味着什么,但是这个查询正在寻找它找不到的关系是什么?为什么有时它不存在,导致查询出错?

更新:我还把每张表的OID在drop前都打印出来了,也都不是报错信息中的OID!

【问题讨论】:

【参考方案1】:

您正在使用带有 CASCADE 选项的 DROP。因此,任何具有参照完整性的表的删除也将删除与父表关联的子表。

要排除这是否真的发生的事情,在运行代码之前拍摄现有表及其 OID 的快照(我认为 pg_tables 或 pg_relations 应该有这些信息)。运行代码并使用表名的快照检查错误消息的 OID。

编辑:这可能是因为计划是如何在 PostgreSQL 中缓存的(所以在 Redshift 中)用于函数。在 8.2 之前,这是一个记录在案的错误,因此您可能需要搜索它的修复程序。该计划将根据函数的第一次执行被缓存,但对于第二次执行,一些对象会因为重新创建而获得新的 OID。 http://merlinmoncure.blogspot.ie/2007/09/as-previously-stated-postgresql-8.html

http://www.postgresql.org/message-id/eea51fdb0708170848w77e27daarfc375ad5c7bc1e09@mail.gmail.com

【讨论】:

阅读您的答案后的一些线索:1)对于每个表,我在删除它之前打印了它的 UID,并且它们都不是错误消息中的那个。 2)我打印了 information_schema.tables 的 OID,它不是错误消息中的那个。为什么这个简单的查询会发生错误?甚至使用的是 information_schema 表,甚至不是用户创建的表! @tscizzle :编辑了上面的答案。如果您找到解决方法,请分享:-)

以上是关于psycopg2、Redshift 和 unittest 的并发问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Psycopg2 将 Spark DataFrame 写入 Redshift 时出错:无法腌制 psycopg2.extensions.cursor 对象

使用带有 Lambda 的 psycopg2 插入 Redshift (Python)

使用 Psycopg2 从 Redshift 写入文件引发异常

尝试使用 psycopg2.sql 在 python 中创建 Redshift 表

Psycopg2 是不是允许使用 Python 在 redshift 上运行 udf create 查询?

无法使用 psycopg2 从 Amazon Redshift 读取数据