从备份恢复表后的IntegrityError,PostgreSQL + Django

时间:2018-05-02 15:29:26

标签: python django postgresql autofield

我正在尝试从某些数据库备份中恢复数据库中的表。备份是通过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失败的数字开始)。

P.S。恢复过程与备份相同 - 在pgAdmin UI中手动完成。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

根据“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.6 Django 2.0 PostgreSQL 10 测试了此代码。