Django (или sqlite3) изменяют последовательность атрибутов модели - PullRequest
0 голосов
/ 23 января 2019

Я использую django с sqlite3, а вот мой models.py:

from django.db import models
from django.conf import settings
from django.utils import timezone

class VoterDetails(models.Model):
    number = models.CharField(max_length=200,null=True)
    voter_id = models.CharField(null=True,max_length=200)
    elector_name = models.CharField(max_length=200,null=True)
    father_or_husband_name = models.CharField(max_length=200,null=True)
    has_husband = models.CharField(max_length=200,null=True)
    house_no = models.CharField(max_length=200,null=True)
    age = models.CharField(max_length=200,null=True)
    sex = models.CharField(max_length=6,null=True)
    ac_name = models.CharField(max_length=200,null=True)
    parl_constituency = models.CharField(max_length=200,null=True)
    part_no = models.CharField(max_length=200,null=True)
    year = models.CharField(max_length=200,null=True)
    state = models.CharField(max_length=200,null=True)
    filename = models.CharField(max_length=200,null=True)
    main_town = models.CharField(max_length=200,null=True)
    police_station = models.CharField(max_length=200,null=True)
    mandal = models.CharField(max_length=200,null=True)
    revenue_division = models.CharField(max_length=200,null=True)   
    district = models.CharField(max_length=200,null=True)
    pin_code = models.CharField(max_length=200,null=True) 
    polling_station_name = models.CharField(max_length=200,null=True)
    polling_station_address = models.CharField(max_length=200,null=True)
    net_electors_male = models.CharField(max_length=200,null=True)
    net_electors_female = models.CharField(max_length=200,null=True) 
    net_electors_third_gender = models.CharField(max_length=200,null=True)
    net_electors_total = models.CharField(max_length=200,null=True)
    change = models.CharField(default="",max_length=200,null=True)

    def __str__(self):
        return self.elector_name

Как видно, нет атрибута, который бы претендовал на первичный ключ . В этом случае django генерирует атрибут id, который представляет собой автоинкремент Auto field, который выбирается в качестве первичного ключа.

Я выполнил миграцию, а затем проверил схему таблицы, сгенерированной таким образом temp_voterdetails (temp - это имя моего приложения.)

sqlite> .schema temp_voterdetails
CREATE TABLE IF NOT EXISTS "temp_voterdetails" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"age" varchar(200) NULL,
"ac_name" varchar(200) NULL,
"change" varchar(200) NULL,
"district" varchar(200) NULL, 
"elector_name" varchar(200) NULL, 
"father_or_husband_name" varchar(200) NULL, 
"filename" varchar(200) NULL, 
"has_husband" varchar(200) NULL, 
"main_town" varchar(200) NULL, 
"mandal" varchar(200) NULL, 
"net_electors_female" varchar(200) NULL, 
"net_electors_male" varchar(200) NULL, 
"net_electors_third_gender" varchar(200) NULL, 
"net_electors_total" varchar(200) NULL, 
"number" varchar(200) NULL, 
"pin_code" varchar(200) NULL, 
"police_station" varchar(200) NULL, 
"polling_station_address" varchar(200) NULL, 
"polling_station_name" varchar(200) NULL, 
"revenue_division" varchar(200) NULL, 
"sex" varchar(6) NULL, 
"state" varchar(200) NULL, 
"voter_id" varchar(200) NULL, 
"year" varchar(200) NULL, 
"house_no" varchar(200) NULL, 
"parl_constituency" varchar(200) NULL, 
"part_no" varchar(200) NULL);

Как видите, порядок атрибутов является алфавитным, и поэтому он изменяется по сравнению с первоначальным порядком объявления атрибутов в файле models.py.

Помимо этого, я попытался импортировать CSV (который следовал структуре, определенной в файле models.py):

.mode csv
.separator ","
.import /path/to/my/csv temp_voterdetails 

Тогда я получаю ошибку (раз количество строк, очевидно):

INSERT failed: UNIQUE constraint failed: temp_voterdetails.id
/path/to/my/csv:164705: expected 28 columns but found 27 - filling the rest with NULL

Итак, изначально я подумал, что я не даю никакого ввода для "id", поэтому он должен генерироваться автоматически, и, следовательно, никогда не должен выходить за рамки уникального ограничения. Но, увы, при алфавитном перетасовке преобразования django в sqlite3, id, кажется, вводится с number, и в конце остается один столбец. Из-за чего ограничение UNIQUE не выполняется, а последний столбец остается неиспользованным.

Как мне убедиться, что схема таблицы, которую я создаю, правильно спроектирована и соответствует модели, определенной в models.py?


ОБНОВЛЕНИЕ: После остановки автоматического алфавитного упорядочения атрибутов я добавлю атрибут global_number (AUTO INCREMENT, первичный ключ) только в конце. Все остальные атрибуты могут быть сопоставлены с 27 существующими заголовками столбцов, и последний, поскольку он отсутствует в CSV-файле, будет сгенерирован автоматически, в результате чего будет сгенерирован мой первичный ключ.

Это то, что я планирую. Поправь меня, если это как-то не так.


1 Ответ

0 голосов
/ 11 февраля 2019

Кажется, что атрибуты всегда упорядочены в алфавитном порядке, в модели sqlite3, из-за чего мы не можем напрямую импортировать наш CSV с использованием sqlite3.Основной проблемой, с которой я столкнулся, была медленная скорость добавления строк в таблицу.Это было потому, что я делал 1 запрос на добавление строки.Эту проблему легко решить, составив список объектов ввода и массово добавив его в таблицу.Это занимает всего один запрос, а значит, занимает значительно меньше времени.Вот код:

import os
import django
os.environ['DJANGO_SETTINGS_MODULE']='<your-site>.settings'
django.setup()
from temp.models import <your-model>
import csv
with open('/path/to/csvfile','r') as f:
    reader = csv.reader(f)
    lst = []
    for i,row in enumerate(reader):
        print('Adding :'+str(i))
        if(i!=0):
            lst.append(<your-model>(
                name = row[0], #attribute 1
                popularity = row[1], #attribute 2
                ssum = row[2], # attribute 3
                yearrange = row[3], #attribute 4
                state = row[4] # attribute 5
                ))
    <your-model>.objects.bulk_create(lst)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...