Soru Django + PostgreSQL: Birincil anahtarı nasıl sıfırlarsınız?


Django’da bir uygulama üzerinde çalışıyorum. Başlamak için, basitlik için veritabanı için sqlite3 kullanıyordum.

Ancak, bir kez PostgreSQL'e geçtiğimde biraz problemle karşılaştım: Bir tabloyu temizlediğimde ana anahtar sıfırlanmaz.

Bu uygulama, uzun bir süre (hafta) boyunca oynanan bir oyundur. Böylelikle, yeni bir oyun her başladığında, tüm veriler veri tabanından silinir ve yeni, rastgele veri eklenir.

Başlangıcından başlayarak birincil anahtarlar ile "baştan başla" yapabilmek istiyorum. 1 Oyunu her temizlediğimde / yeniden oluşturduğumda.

Kod hala olduğu gibi çalışır, ancak tamsayılar oyunumdaki nesneleri tanımlamak için oldukça doğal bir yoldur. Son oyunun kaldığı yerden her yeni oyuna 1 tane başlamak istiyorum.

PostgreSQL'de birincil anahtar sayacını nasıl sıfırlayabilirim? Tablodaki verileri korumam gerekmediği için onu sildiğimi unutmayın.


21
2018-02-13 05:00


Menşei


Sanırım masayı bırakıp yeniden yaratmaya çalışabilirim, ama önlenebilirse ... - TM.
masayı kendim düşürdüm ... anlamaya çalışırken çok fazla zaman harcıyordum - fuentesjr


Cevaplar:


Uygulama dizininizde şunu deneyin:

python manage.py help sqlsequencereset

Sıfırlamayı çalıştırmak için bunu psql'ye pipetleyin:

python manage.py sqlsequencereset myapp1 myapp2 | psql

Düzenleme: tablolarımdan birinde bu komutun çıktısının bir örneği:

BEGIN;
SELECT setval('"project_row_id_seq"', coalesce(max("id"), 1), max("id") IS NOT null) FROM "project_row";
COMMIT;

26
2018-02-13 07:04



Ya bir pencere kuruyorsa? - fuentesjr
Sqlsequencereset commmand, birincil anahtar sayacını sıfırlamak için gereken SQL'i üretir, bu nedenle pencereleri, çıktıları psql'ye aktarmak yerine, kopyala + kullandığınız herhangi bir yönetici uygulamasına yapıştırın. Örneğin, pgAdminIII kuruluysa, "rasgele SQL sorguları yürüt" içine yapıştırın. - Van Gale
İşten eve döndüğümde bunu kontrol edeceğim, teşekkürler! Bunu programlı bir şekilde yapmak için bir yolu var mı? Mümkünse kolayca django görünümünde yapışmayı çok isterim. - TM.
Bu biraz tehlikeli görünüyor, ama her biri için! Bu yöntemi kullan: docs.djangoproject.com/en/dev/topics/db/sql - Van Gale
Burada da önerilen yöntem budur code.djangoproject.com/ticket/11423. Dbshell'e bağlayarak basitleştirebilirsiniz python manage.py sqlsequencereset <appname> | python managy.py dbshell - user


İşlenmemiş bir sql gerçekleştirirseniz, bunu yapabilirsiniz:

ALTER SEQUENCE youApp_id_seq RESTART WITH 1;

docs: http://www.postgresql.org/docs/8.2/static/sql-altersequence.html


3
2017-12-20 19:44





Otomatik artışlı birincil anahtarları, veritabanı kayıtları için tamamen dahili tanımlayıcılar olarak görüyorum ve bunları kullanıcılara göstermeyi sevmiyorum. Verilen, bu URL'lerin bir parçası olarak bunları kullanmak için ortak bir tasarıma sahiptir, ancak orada sümüklü böcekler veya diğer tanımlayıcılar daha uygun hissettirir.


1
2018-02-14 11:57



Normalde ben de yapardım, ama buradaki nesneler zaten numaralandırılacak ve 1, 2, 3 ... vb. Olarak görüntülenecektir. - TM.


Tabloyu kırpmanız gerekiyor. Görmek http://www.postgresql.org/docs/8.1/static/sql-truncate.html


0
2018-02-13 05:28



Çalışmıyor gibi gözüküyor ... tüm verileri siler, ancak ana anahtarlar hala daha önce bıraktıkları yerden başlar. Örneğin, 500 satır eklerseniz, tabloyu kırpın, sonra başka bir 500 ekleyin, birincil anahtarlar 1-500 arasında değil, 501 ile 1000 arasında olacaktır. - TM.
Hmmm, bunu deneyin: ALTER TABLE theTableInQuestion AUTO_INCREMENT = 0 - superUntitled
Unutmayın, bu MySQL için üzgünüm, hiç bir şekilde yardım edemem. - superUntitled


"Van Gale" nin önerdiği gibi, probleminizi çözmek için komutları alabilirsiniz. sqlsequencereset.

veya

Tarafından oluşturulan SQL sorgusunu çalıştırabilirsiniz. sqlsequencereset python içinden bu şekilde (varsayılan veritabanını kullanarak):

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)

Bu kodu ile test ettim Python3.6, Django 2.0 ve PostgreSQL 10.


0
2018-05-10 15:20