1

Я нахожусь в Python 2.7, используя psycopg2 для подключения к базе данных Amazon Redshift. У меня есть модульные тесты, а в методах setUp и tearDown для этого тестового класса я бросаю таблицы, созданные для этой проверки. Таким образом, схема:Проблема параллелизма с psycopg2, Redshift и unittest

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

def tearDown(self): 
    drop_specific_tables() 

Причиной падения в дистрибутиве, а также Teardown в случае тест выходит ненадежно и пропускает Teardown мы все еще можем знать, что всякий раз, когда он снова бежит он все равно будет начать с чистого листа ,

Это метод drop_specific_tables, а rcur - это курсор 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;") 

Когда выполняется индивидуальный тест, он проходит. Но когда весь класс запускаются, некоторые тесты ошибки в нАлАдкА или 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. I распечатал OID «information_schema.tables», и это не тот же OID, что и в сообщении об ошибке.

Почему это может произойти? Я понимаю, что это значит для отношения к не существует, но какое отношение этот запрос ищет, которого он не может найти? И почему это иногда не должно быть, вызывая запрос на ошибку?

UPDATE: Я также распечатывал OID каждой таблицы перед удалением, и ни один из них не является идентификатором OID в сообщении об ошибке!

ответ

1

Вы используете DROP с опцией CASCADE. Таким образом, любое падение таблиц, имеющих ссылочную целостность, также приведет к падению дочерней таблицы, связанной с родительской таблицей.

Чтобы устранить проблему, если это действительно то, что происходит, перед запуском вашего кода сделайте снимок существующих таблиц с их 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/[email protected]

+0

пару ключей, так как читать ваш ответ: 1) Для каждой таблицы, я напечатал свой UID, прежде чем упасть, и ни один из них не являются один в сообщении об ошибке. 2) Я распечатал OID информационных_схем.tables, и это не тот, что в сообщении об ошибке. Почему ошибка возникает из этого простого запроса? Который даже использует таблицу information_schema, даже не созданную пользователем таблицу! – tscizzle

+0

@tscizzle: Отредактирован ответ выше. Пожалуйста, поделитесь, если найдете исправление :-) – Paladin