操作错误:游标“_django_curs_<id>”不存在

问题描述 投票:0回答:3

我们有一个在线商店网络应用程序,由 django、postgresql 和 heroku 提供支持。

对于特定的活动(您可以将活动视为要购买的产品),我们已成功售出 10k+ 份。然而,根据我们的哨兵报告,我们的一些用户遇到了这个错误。这些用户的共同规范是;他们都没有购买前的地址信息。通常,用户在注册后立即填写地址表。如果他们不这样做,他们需要在购买产品时填写表格并一起提交。

轨迹是这样的:

OperationalError: cursor "_django_curs_140398688327424_146" does not exist

(66 additional frame(s) were not displayed)
...
  File "store/apps/store_main/templatetags/store_form_filters.py", line 31, in render_form
    return render_to_string('widgets/store_form_renderer.html', ctx)
  File "store/apps/store_main/templatetags/store_form_filters.py", line 20, in render_widget
    return render_to_string('widgets/store_widget_renderer.html', ctx)
  File "store/apps/store_main/widgets.py", line 40, in render
    attrs=attrs) + "<span class='js-select-support select-arrow'></span><div class='js-select-support select-arrow-space'><b></b></div>"

OperationalError: cursor "_django_curs_140398688327424_146" does not exist 

所以另一个奇怪的常见事情是,在失败之前的 sql 查询之间有异常消息。您可以在下图中看到它:

如果它们以某种方式相关,我将添加它。也可能相关的是,出现此错误的用户是在批量邮寄后立即尝试购买活动的用户。因此,大量的流量可能是原因,但我们也不确定。

我们向 Heroku 询问了这个问题,因为他们正在托管 postgres,但他们也没有任何线索。

我知道这个错误的正式原因是在提交后试图到达光标。因为它在交易后被销毁,试图到达它会导致这个错误,但我在我们的场景中没有看到这个。我们没有以任何方式触摸光标。我错过了什么?什么可能会产生这个错误?如何预防?任何想法将不胜感激。

python django postgresql sentry heroku-postgres
3个回答
30
投票

您的错误原因可能是您将字段添加到模型中而忘记了 makemigrations 和 migrate。

看看这个答案:在运行测试用例时,我会得到这个错误:psycopg2.OperationalError: cursor "_django_curs_140351416325888_23" does not exist


6
投票

如果您使用的是 django-pytest 并启用了优化

--reuse-db
并且在测试运行之间进行了数据库迁移,您需要再次重新创建数据库表。

pytest --create-db

3
投票

您很可能忘记进行迁移并将它们迁移到数据库。 如果您确定您确实进行了迁移并且运行

python manage.py makemigrations
python manage.py migrate
将找不到您所做的更改,那么数据库和模型不同步。 如果您有一个大数据库,有时这种情况会非常令人沮丧。您将需要手动检查您的模型。

为了帮助你可以试试这个技巧,它一直对我有用。

  • 第 1 步(从应用程序中删除所有迁移) 我将假设您使用的是 unix 终端。跑
    sudo rm -rv */migrations/*
    。这将删除所有迁移文件和缓存。
  • Step 2(在每个应用程序中制作迁移文件夹) 运行命令
    mkdir <app-folder>/migrations && touch <app-folder>/__init__.py
    。替换为您在默认 django 设置文件中的
    INSTALLED_APPS
    列表中的应用程序名称。
  • 第 3 步(进行迁移) 在这里,我们使用迁移文件填充每个应用程序中的迁移文件夹。运行
    python manage.py makemigrations
    。运行第二个命令。
    python manage.py migrate --fake
    。我们正在使用 --fake 标志,因为数据已经存在于数据库中,所以我们不想填充已经存在的名称数据库表,否则您将看到
    already exists error

如果这不起作用,那么您将需要调整数据库中的一些附加字段。例如 django_migrations 或类似名称的表。不推荐这样做,因为还有其他依赖于它的数据库表,例如 django_contenttypes,这会让您陷入一系列相关表中,您将手动检查这些表,这非常痛苦。

所以如果你想直接弄乱数据库,你可以尝试另一个技巧。因此,为此,您需要具有正确的权限才能以用户身份编辑数据库。如果您使用 sqlite3 作为数据库,则需要使用像 sqlite 工具这样的工具。

好的,一旦在您用于 Django 项目的数据库中,查找名为

django_migrations
的关系或表。删除/删除表。在正常情况下,由于外键约束,删除将失败,删除与 django_migrations 表相关的每个数据库关系/表。这些表包括 django_contenttypes、auth_permissions(以及我遗漏的任何其他表)。 无需担心,因为您没有修改重要的实际 Web 应用程序数据。删除后,在活动的虚拟环境中使用
python manage.py makemigrations
python manage.py migrate
运行迁移。

这很可能会消除该错误。

© www.soinside.com 2019 - 2024. All rights reserved.