IntegrityError после восстановления таблицы из резервной копии, PostgreSQL + Django - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь восстановить таблицу в моей базе данных из некоторых резервных копий БД. Резервная копия создается с помощью инструмента 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 ? Есть ли способ исправить это и заставить его считаться с последнего числа?

Мне сказали, что я должен использовать этот рецепт . Но когда я запускаю 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 голосов
/ 10 мая 2018

По предложению "Alasdair" вы можете получить команды для решения вашей проблемы, запустив sqlsequencereset.

или

Вы можете выполнить SQL-запрос, сгенерированный sqlsequencereset из Python, следующим образом (, используя базу данных по умолчанию ):

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 .

0 голосов
/ 02 мая 2018

sqlsequencereset только печатает команды, но не запускает их.

Вы должны запускать команды, используя pgAdmin или manage.py dbshell.

...