【问题标题】:IntegrityError after table restore from backup, PostgreSQL + Django从备份恢复表后的 IntegrityError,PostgreSQL + Django
【发布时间】:2018-10-12 18:44:51
【问题描述】:

我正在尝试从一些数据库备份中恢复我的数据库中的一个表。备份是通过pgAdmin 4 UI 工具创建的,选择一个表,然后备份它。这是pgAdmin 执行的命令:

--file "C:\\Users\\cchie\\DOCUME~1\\DB_BAC~1\\CURREN~1" --host "localhost" --port "5432" --username "postgres" --no-password --verbose --format=c --blobs --table "public.cosmetic_crawler_currency" "last_cosmetics"

问题是我在那个表中有一个AutoField,当我恢复一个表时,接下来尝试向其中添加新项目 - 我有这样的错误:

psycopg2.IntegrityError: duplicate key value violates unique constraint "cosmetic_crawler_product_pkey"
DETAIL:  Key (product_id)=(27) already exists.

The above exception was the direct cause of the following exception:

django.db.utils.IntegrityError: duplicate key value violates unique constraint "cosmetic_crawler_product_pkey"
DETAIL:  Key (product_id)=(27) already exists.

据我了解 - 这意味着 PostgreSQL 服务器不知道我已恢复 AutoField 计数器并尝试从 0 开始计数有没有办法解决这个问题并使其从最后一个数字开始计算?

有人告诉我必须使用this recipe。但是当我运行 manage.py sqlsequencereset my_app_name - 我看到该命令运行时:

BEGIN;
SELECT setval(pg_get_serial_sequence('"cosmetic_crawler_product"','product_id'), coalesce(max("product_id"), 1), max("product_id") IS NOT null) FROM "cosmetic_crawler_product";
SELECT setval(pg_get_serial_sequence('"cosmetic_crawler_sale"','sale_id'), coalesce(max("sale_id"), 1), max("sale_id") IS NOT null) FROM "cosmetic_crawler_sale";
SELECT setval(pg_get_serial_sequence('"cosmetic_crawler_promo"','promo_id'), coalesce(max("promo_id"), 1), max("promo_id") IS NOT null) FROM "cosmetic_crawler_promo";
SELECT setval(pg_get_serial_sequence('"cosmetic_crawler_brand_shops"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "cosmetic_crawler_brand_shops";
SELECT setval(pg_get_serial_sequence('"cosmetic_crawler_brand_categories"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "cosmetic_crawler_brand_categories";
SELECT setval(pg_get_serial_sequence('"cosmetic_crawler_brand"','brand_id'), coalesce(max("brand_id"), 1), max("brand_id") IS NOT null) FROM "cosmetic_crawler_brand";   
COMMIT;

但这仍然没有效果 - 当我添加新项目时 - PostgreSQL 一直从 0 开始计数(更准确地说 - 从之前因 IntegrityError 失败的最后一个数字开始)。

附:恢复过程与备份相同 - 在pgAdmin UI 中手动进行。

【问题讨论】:

  • sqlsequencereset 只是打印命令。它不运行它们。您必须运行命令。
  • 那么我应该如何运行它们?
  • 由于您使用的是 pgAdmin,您可以使用它,或者直接使用 manage.py dbshell
  • 啊,抱歉,我是新手,不知道如何使用这些功能:) 会试试你的食谱,谢谢
  • 成功了!谢谢!

标签: python django postgresql autofield


【解决方案1】:

sqlsequencereset 只打印命令,不运行它们。

您必须使用pgAdminmanage.py dbshell 运行命令。

【讨论】:

    【解决方案2】:

    按照“Alasdair”的建议,您可以获取命令来解决运行sqlsequencereset 的问题。

    您可以通过这种方式在python中执行sqlsequencereset生成的SQL查询(使用默认数据库):

    from django.core.management.color import no_style
    from django.db import connection
    
    from myapps.models import MyModel1, MyModel2
    
    
    sequence_sql = connection.ops.sequence_reset_sql(no_style(), [MyModel1, MyModel2])
    with connection.cursor() as cursor:
        for sql in sequence_sql:
            cursor.execute(sql)
    

    我使用 Python3.6Django 2.0PostgreSQL 10 测试了这段代码。

    【讨论】:

      猜你喜欢
      • 2017-02-14
      • 2020-10-10
      • 2012-01-14
      • 2014-08-19
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 2014-09-03
      • 2013-12-27
      相关资源
      最近更新 更多