5

Bazı tabloda bileşik birincil anahtarın bulunduğu eski bir veritabanım var. manage.py inspectdb komutunu çalıştırarak elde ettiğim model buna benziyor.Eski veritabanıyla django projesinde birleşik birincil anahtar ile çalışma

class MyTable(models.Model): 
    field1_id = models.IntegerField(db_column='field1id', primary_key=True) 
    is_favorite = models.BooleanField(db_column='isfavorite', default=False, null=False) 
    is_admin = models.BooleanField(db_column='isadmin', default=False, null=False) 
    role = models.IntegerField(default=USER_GUEST, null=False) 
    field2 = models.BooleanField(null=False, default=True) 
    field3 = models.BooleanField(null=False, default=True) 
    is_active = models.BooleanField(db_column='isactive', null=False, default=True) 

    user = models.ForeignKey(
     CustomUser, models.DO_NOTHING, db_column='userid', primary_key=True) 

    class Meta: 
     managed = False 
     db_table = 'mytable' 
     unique_together = (('user', 'field1_id'),) 

Verileri normal şekilde alabilirim. Ancak, bazı model örnekte save() komutunu çalıştırmak istediğimde sorun ortaya çıkıyor. Django yürütme sorgusu doğru değil. Örneğin:

>>> from web_services.apps.my_app.models import MyTable 
>>> g = MyTable.objects.get(field1_id=12) 
>>> g.is_active = True 
>>> g.save() 
>>> connection.queries[-1] 
{'time': '0.000', 'sql': 'UPDATE `mytable` SET `isfavorite` = 0, `isadmin` = 1, `role` = 3, `field2` = 1, `field3` = 1, `isactive` = 1 WHERE `mytable`.`field1id` = 12'} 

Ama gerekir: Django kompozit birincil anahtar desteklemediği

{'time': '0.000', 'sql': 'UPDATE `mytable` SET `isfavorite` = 0, `isadmin` = 1, `role` = 3, `field2` = 1, `field3` = 1, `isactive` = 1 WHERE `mytable`.`field1id` = 12' AND `mytable`.`userid` = 1'} 

ya o sorunu aşmak için en iyi çözüm olurdu? Not, eski veritabanı tablosu ve AutoField yoktu.

DÜZENLEME:

+------------+------------+------+-----+---------+-------+ 
| Field  | Type  | Null | Key | Default | Extra | 
+------------+------------+------+-----+---------+-------+ 
| userid  | int(11) | NO | PRI | NULL |  | 
| field1id | int(11) | NO | PRI | NULL |  | 
| isfavorite | int(11) | NO |  | 0  |  | 
| isadmin | int(11) | NO |  | 0  |  | 
| role  | int(11) | YES |  | NULL |  | 
| field2  | tinyint(1) | NO |  | 1  |  | 
| field3  | tinyint(1) | NO |  | 1  |  | 
| isactive | tinyint(4) | NO |  | 1  |  | 
+------------+------------+------+-----+---------+-------+ 
+0

sizin masayı düzenlemek muktedir modelden = False komutunu yönetilen Sil gerekir. – e4c5

+0

@ e4c5 eski tablo yapısını ekledi – AmirM

cevap

1

Ne yazık ki not yet have a composite primary key (bileşik birincil anahtarları da çok sütun birincil anahtarları olarak adlandırılır)

üçüncü bir kütüphane bulunmaktadır, şaşırtıcı django-compositekey adı etmez django eski tablo yapısını ekler çoklu sütun birincil anahtarına sahip bir model oluşturmayı mümkün kılar. Ancak bu proje şu anda korunur ve django'nun son sürümleriyle uyumlu değildir.

En iyi bahsiniz, tablonuza AutoField olan yeni bir sütun eklemek ve yeni birincil anahtarı yapmaktır. Şu anda birincil anahtarı oluşturan alanlar daha sonra unique_together olarak işaretlenebilir. Bu birkaç sorgu için ideal olmayabilir. Çoğu için yeterince iyi.

Sorunuzu güncel tablo yapısına göre güncelleştirirseniz (sql konsolunda gösterildiği gibi) modelin neye benzeyeceğini göstermek için cevabımı güncellerim.

Güncelleme eski kompozit birincil anahtar bırakın ve yeni bir otomatik artış birincil anahtar ile değiştirin hangi farklı şekillerde çok sayıda bulunmaktadır. İşte

CREATE TABLE newtable LIKE mytable; 
ALTER TABLE newtable DROP PRIMARY KEY; 
ALTER TABLE newtable ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY; 
RENAME TABLE mytable to mytable_old; 
RENAME TABLE newtable to mytable; 
INSERT INTO mytable(userid,field1id, rest of the fields) 
    SELECT * FROM mytable_old; 

Ardından modeli düzenleyebilir ve bu alanlardan primary_key = Gerçek bayrağını kaldırmak sadece SQL içerir, en kolay yoldur.

Dipnot: sqlite gibi
bazı veritabanları örneğin bir CREATE TABLE içinde LIKE maddesini desteklemez. Bu durumlarda, orijinal tablo için create table deyimini aramak ve tablo adını düzenledikten sonra yapıştırmak gerekir. Tablo yapınıza bakarak mysql kullanıyorsunuz ve LIKE maddesini destekliyor.

+0

Bu 'salt SQL' olsa? '' CREATE TABLE''DA LIKE''nın standart SQL olduğundan emin değilim, belki de 'saf MySQL'de değişiklik ekleyebilir miyim?(MySQL/MyISAM LIKE destekliyor ama Firebird, diğer motorlar/RDMBS'ler hakkında emin değil) –

+0

@JanSegre'nin tüm veritabanları tarafından desteklenmediğinden haklısınız. Ben yukarıdaki cevapta saf sql yazarken ben sadece ansi standardı değil django nd dahil değil düşünüyordum. Cevabımı güncelleme. – e4c5

0

Sen de tablo yapısını eklerseniz iyi olur

İlgili konular