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 表