如何修复“内部错误:在子计划目标列表中找不到变量”

con*_*ror 13 python django postgresql pytest docker

我有一个旧版 Django 项目 (django-1.1.29) 和 pytest (pytest-4.3.0) 中的一些测试,全部在 Docker 内运行。数据库是PostgreSQL 10,是应用程序依赖的docker-compose服务。python版本是2.7.18。

最近测试开始失败并出现一个奇怪的错误:

InternalError: variable not found in subplan target list

仅当我计算某个模型的对象数量时才会出现错误,例如Problem.objects.count()。该指令变成以下查询

(0.000) SELECT COUNT(*) AS "__count" FROM "problems_problem"; args=() 由姜戈.

整个日志在这里:

self = <integration_tests.project_name.subjects.test_views.test_theme_problem_view_set.TestThemeProblemViewSet object at 0x7f01faccbe50>
jclient = <project_name.common.test_utils.json_client.JSONClient object at 0x7f01fadb8ed0>

    def test_all_is_ok(self, jclient, subject_model, content_manager):
        url, data = self._main_prepare(jclient, subject_model, content_manager)
        response = jclient.post_json(url, data[0])
        assert response.status_code == 201
>       assert Problem.objects.count() == 1

integration_tests/project_name/subjects/test_views/test_theme_problem_view_set.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py:85: in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
/usr/local/lib/python2.7/dist-packages/django/db/models/query.py:364: in count
    return self.query.get_count(using=self.db)
/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py:499: in get_count
    number = obj.get_aggregation(using, ['__count'])['__count']
/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py:480: in get_aggregation
    result = compiler.execute_sql(SINGLE)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.models.sql.compiler.SQLCompiler object at 0x7f01faee3a50>
result_type = 'single', chunked_fetch = False

    def execute_sql(self, result_type=MULTI, chunked_fetch=False):
        """
        Run the query against the database and returns the result(s). The
        return value is a single data item if result_type is SINGLE, or an
        iterator over the results if the result_type is MULTI.
    
        result_type is either MULTI (use fetchmany() to retrieve all rows),
        SINGLE (only retrieve a single row), or None. In this last case, the
        cursor is returned if any query is executed, since it's used by
        subclasses such as InsertQuery). It's possible, however, that no query
        is needed, as the filters describe an empty set. In that case, None is
        returned, to avoid any unnecessary database interaction.
        """
        if not result_type:
            result_type = NO_RESULTS
        try:
            sql, params = self.as_sql()
            if not sql:
                raise EmptyResultSet
        except EmptyResultSet:
            if result_type == MULTI:
                return iter([])
            else:
                return
        if chunked_fetch:
            cursor = self.connection.chunked_cursor()
        else:
            cursor = self.connection.cursor()
        try:
            cursor.execute(sql, params)
        except Exception as original_exception:
            try:
                # Might fail for server-side cursors (e.g. connection closed)
                cursor.close()
            except Exception:
                # Ignore clean up errors and raise the original error instead.
                # Python 2 doesn't chain exceptions. Remove this error
                # silencing when dropping Python 2 compatibility.
                pass
>           raise original_exception
E           InternalError: variable not found in subplan target list

/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py:899: InternalError
Run Code Online (Sandbox Code Playgroud)

如果有人能帮助我解决这个问题或者至少给出一些提示来查找原因,我将非常感激。

到目前为止,这是我尝试做的事情,但这些都没有帮助:

  • 使用不同版本的 PostgreSQL(10、11、12、13)
  • 禁用服务器端光标

jam*_*rty 9

看来 postgres 已经发布了一些分解为所有次要版本的东西:

https://www.postgresql.org/message-id/2121219.1644607692%40sss.pgh.pa.us

例如,postgres:12 dockerhub 现在与 postgres:12.10 dockerhub 映像相同,而不是 12.9。如果您明确指定 postgres:12.9 (或任何其他版本的先前次要版本),我相信它将开始工作。