Почему Django/Postgres вроде бы сохраняет, но не сохраняет, выдает "соединение уже закрыто"?

Я использую Django + Postgres на Windows 10 WSL Ubuntu 18.04.5 LTS. Сохранение данных в postgres вроде бы работает, но когда я обращаюсь к таблице с помощью psql в командной строке, данных там нет. Обновление веб-страницы (перезагрузка Django) также показывает старые данные, предшествующие сохранению.

В журнале postgresql нет ошибок.

У меня нет явного включения кэширования в файле settings.py.

в Django.

Все это прекрасно работало в течение многих лет, но для уверенности я обновил Django до 3.2.6, Python до 3.8.11, postgresql до 12, и psycopg2 до 2.9.1, плюс необходимые зависимости. Результат тот же.

Вот код на Django:

    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**

Но это исключение InterfaceError не поймано в коде, который я показал выше.

Я попробовал установить CONN_MAX_AGE в настройках Django, ничего не изменилось, поэтому я удалил его.

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

Может ли это быть связано с обновлением WSL2 в Windows? В поиске Google ничего не нашлось.

UPDATE: Я только что заметил, что журналы apache исчезли (я использую 'django runserver' для этого, вместо apache, поэтому я не заметил). Журналы postgres все новые с тех пор, как я начал отлаживать эту проблему. Дампы sql postgres, которые я делал в прошлом, исчезли. К счастью, мой исходный код в /var/www остался. Возможно, это проблема обновления WSL?

Ошибка "psycopg2.InterfaceError: connection already closed" появляется всякий раз, когда в тестируемом коде возникает ошибка до того, как он дойдет до проверки утверждений в тесте. Это не ошибка psycopg2, как таковая. Неинтуитивное сообщение, мягко говоря.

Я открыт для предложений о том, как сделать модульное тестирование в Django, при котором такие ошибки будут выявлены и их местоположение указано в исходном коде, а не только в тестах. Я находил их методом исключения: комментируя тесты и проходя по коду с помощью pdb.

Все мои тестовые классы подклассифицированы из django.test.TestCase, поскольку они местами запрашивают Models. Из документации django unit testing docs:

Если ваши тесты используют доступ к базе данных, например, создание или запрос модели, обязательно создавайте свои тестовые классы как подклассы django.test.TestCase, а не unittest.TestCase.

.

Использование unittest.TestCase позволяет избежать затрат на запуск каждого теста в транзакции и промывки базы данных, но если ваши тесты взаимодействуют с базой данных, их поведение будет меняться в зависимости от порядка, в котором тест runner выполняет их. Это может привести к тому, что модульные тесты будут успешными при выполнении изолированно, но проваливаются при запуске в наборе.

Вернуться на верх