Phi*_*ord 21 django postgresql
我最近将旧数据库中的大量数据导入到新的Postgresql数据库中,作为新Django站点中模型的基础.
我使用旧数据库中的ID(因为各个表中的行互相引用),但它们并非都是顺序的 - 通常存在很大的差距.
我注意到,当我通过Django应用程序添加一个新对象时,它一直使用从1开始的ID,这对于没有ID非常低的行来说并不是问题.
但是一旦它到达第一行遗留数据,那么postgres显然会抱怨:
ERROR: duplicate key value violates unique constraint "django_comments_pkey"
DETAIL: Key (id)=(25) already exists.
Run Code Online (Sandbox Code Playgroud)
查看表格描述我猜我需要在每个表格上重置某种序列:
Table "public.django_comments"
Column | Type | Modifiers
-----------------+--------------------------+--------------------------------------------------------------
id | integer | not null default nextval('django_comments_id_seq'::regclass)
...
Run Code Online (Sandbox Code Playgroud)
我需要做什么来重置该序列,以便添加ID高于当前最大ID的新行?
Dmi*_*nko 45
运行sqlsequencereset,它将打印您需要的所有重置命令.
Pao*_*rre 10
按照“德米特里·舍甫琴科”的建议,您可以运行sqlsequencereset以解决您的问题。
要么
您可以通过sqlsequencereset以下方式执行python内部生成的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)
Run Code Online (Sandbox Code Playgroud)
我使用Python3.6,Django 2.0和PostgreSQL 10测试了此代码。
这是一个简短的片段,用于重置Django 1.9+中的所有序列(基于http://djangosnippets.org/snippets/2774/)并与Python 3兼容:
import os
from io import StringIO
os.environ['DJANGO_COLORS'] = 'nocolor'
from django.core.management import call_command
from django.apps import apps
from django.db import connection
commands = StringIO()
cursor = connection.cursor()
for app in apps.get_app_configs():
label = app.label
call_command('sqlsequencereset', label, stdout=commands)
cursor.execute(commands.getvalue())
Run Code Online (Sandbox Code Playgroud)
所以在我看来,最快、最简单、最“Django”的方法是使用以下管理命令:
python manage.py sqlsequencereset app_name
Run Code Online (Sandbox Code Playgroud)
在此之后,您将得到如下信息:
BEGIN;
SELECT setval(pg_get_serial_sequence('"measurements_quantity"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Quantities";
SELECT setval(pg_get_serial_sequence('"measurements.Prefixes"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Prefixes";
COMMIT;
Run Code Online (Sandbox Code Playgroud)
下一步是在python manage.py dbshell管理命令中运行它,因此运行它,然后您将在终端中看到交互数据库外壳:
psql (11.7 (Debian 11.7-0+deb10u1), server 11.5 (Debian 11.5-1.pgdg90+1))
Type "help" for help.
postgres=# BEGIN;
BEGIN
postgres=# SELECT setval(pg_get_serial_sequence('"measurements.Quantities"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Quantities";
setval
--------
1
(1 row)
postgres=# SELECT setval(pg_get_serial_sequence('"measurements.Prefixes"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Prefixes";
setval
--------
1
(1 row)
postgres=# COMMIT;
COMMIT
postgres=# exit
Run Code Online (Sandbox Code Playgroud)
就那么简单。该python manage.py sqlsequencereset app_name命令将为您提供需要运行的 SQL,您可以在dbshell.
无需编写您自己的自定义 SQL 或自定义代码,它将以正确的格式和选择的数据库引擎为您提供所需的内容。
| 归档时间: |
|
| 查看次数: |
12668 次 |
| 最近记录: |