#python #django #postgresql #psycopg2 #wsl-2
Вопрос:
Я использую Django Postgres в Windows 10 WSL Ubuntu 18.04.5 LTS. Сохранение данных в postgres, похоже, работает, но когда я получаю доступ к таблице с помощью psql в командной строке, данных там нет. Обновление веб-страницы (перезагрузка Django) также показывает старые данные, предшествовавшие сохранению.
В журнале postgresql нет ошибок.
У меня нет кэширования, явно включенного в Django settings.py.
Все это отлично работало в течение многих лет, но, чтобы быть уверенным, я обновил Django до 3.2.6, Python до 3.8.11, postgresql до 12 и psycopg2 до 2.9.1, плюс необходимые зависимости. Тот же результат.
Вот код на Джанго:
try:
nodeToUpdate.save() # Hit the database.
node = Node.objects.get(pk=itemID, ofmap=mapId) # Retrieve again to confirm it was saved
# This shows the correct data:
print("STORE TO MAP:" str(node.ofmap_id) " NODE:" str(node.id) " label:" str(node.label))
except psycopg2.InterfaceError as err:
print(str(err))
raise Exception(err)
except ValidationError as err:
raise Exception(err)
Ключ к пониманию того, что происходит, приходит, когда я запускаю модульные тесты:
Traceback (most recent call last):
File "/var/www/mysite/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 237, in _cursor
return self._prepare_cursor(self.create_cursor(name))
File "/var/www/mysite/venv/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/var/www/mysite/venv/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 236, in create_cursor
cursor = self.connection.cursor()
**psycopg2.InterfaceError: connection already closed**
Но это исключение ошибки интерфейса не поймано в коде, который я показал выше.
Я попытался установить CONN_MAX_AGE в настройках Django, но это ничего не изменило, поэтому я удалил его.
Поиск в Интернете этой ошибки привел только к появлению решений в других типах сред, как правило, несколько лет назад.
Может ли это быть связано с обновлением Windows до WSL2? В поисковых системах Google ничего не появилось.
ОБНОВЛЕНИЕ: Я только что заметил, что журналы apache исчезли (я использую «django runserver» для вышеперечисленного вместо apache, поэтому я не заметил). журналы postgres все новые с тех пор, как я начал отлаживать эту проблему. sql-дампы postgres, которые я делал в прошлом, исчезли. К счастью, мой исходный код в /var/www остается. Возможно, проблема с обновлением WSL?
Комментарии:
1. «Но это исключение ошибки интерфейса не зафиксировано в коде, который я показал выше». — > сообщается ли об этом вообще, за пределами модульных тестов?
2. @snakecharmerb Не то, что я нашел, но посмотрите обновление, которое я добавил к вопросу.
Ответ №1:
Ошибка «psycopg2.Ошибка интерфейса: соединение уже закрыто» появляется всякий раз, когда в тестируемом коде возникает ошибка, прежде чем он перейдет к проверке утверждения в тесте. По сути, это не ошибка psycopg2. По меньшей мере, неинтуитивное сообщение.
Я открыт для предложений о том, как проводить модульное тестирование в Django, в котором выявляются такие ошибки и их местоположение указывается в исходном коде, а не только в тестах. Я нашел их методом исключения: комментируя тесты и просматривая код с помощью pdb.
Мои тестовые классы все подклассы взяты из django.test.Тестовый случай, так как они запрашивают модели местами. Из документов модульного тестирования django:
Если ваши тесты зависят от доступа к базе данных, такого как создание или запрос моделей, не забудьте создать тестовые классы в качестве подклассов django.test.Тестовый, а не полный.Тестовый кейс.
Используя unittest.TestCase позволяет избежать затрат на выполнение каждого теста в транзакции и очистку базы данных, но если ваши тесты взаимодействуют с базой данных, их поведение будет отличаться в зависимости от порядка их выполнения исполнителем тестирования. Это может привести к модульным тестам, которые проходят при изолированном запуске, но завершаются неудачей при запуске в комплекте.