Загрузка данных из CSV в таблицы базы данных в Django - PullRequest
1 голос
/ 29 февраля 2020

Мне удалось успешно загрузить страну и штат, но я получаю сообщение об ошибке при загрузке города

Что-то не так при сохранении этого города: 0000000698 Значение QuerySet для точного поиска должно быть ограничено к одному результату, используя нарезку.

Это мои 3 модели "страна", "штат" и "город"

class Country(BaseModel):
    id = models.CharField(
            primary_key=True,
            max_length=3,
            unique=True
        )

    class Meta:
        db_table = 'country'
class State(models.Model):
    id = models.CharField(
            primary_key=True,
            max_length=3,
            unique=True
        )
    country = models.ForeignKey(
            Country, 
            on_delete=models.CASCADE, 
            blank=True, 
            null=True
        )
    state_code =  models.CharField(
            max_length=4,
            null=True,
            blank=True,
            unique=True
        )
    capital_city =  models.CharField(
            max_length=10,
            null=True,
            blank=True,
        )

    class Meta:
        db_table = 'state'
class City(models.Model):
    id = models.CharField(
            primary_key=True,
            max_length=10,
            unique=True
        )

    country = models.ForeignKey(
            Country, 
            on_delete=models.CASCADE, 
            blank=True, 
            null=True
        )

    state = models.ForeignKey(
        State,
        on_delete=models.CASCADE,
        blank=True,
        null=True
    )


    class Meta:
        db_table = 'city'

Это образец CSV файлы, которые я хочу загрузить

country.csv

10,Antarctica,Antarktika
16,American Samoa,Amerikanisch-Samoa
60,Bermuda,Bermuda
74,Bouvet Island,Bouvetinsel

state.csv

1,276,BW,0000000111,Baden-Württemberg,Baden-Württemberg
2,276,BY,0000000165,Bavaria,Bayern
3,276,BE,0000000028,Berlin,Berlin
4,276,BB,0000000019,Brandenburg,Brandenburg
5,276,HB,0000000195,Bremen,Bremen
6,276,HH,0000000255,Hamburg,Hamburg

city.csv

0000000001,276,BB,Bernau bei Berlin,Bernau bei Berlin
0000000002,276,BB,Blankenfelde-Mahlow,Blankenfelde-Mahlow
0000000003,276,BB,Brandenburg an der Havel,Brandenburg an der Havel
0000000004,276,BB,Cottbus,Cottbus
0000000005,276,BB,Eberswalde,Eberswalde
0000000029,276,BW,Aalen (Württemberg),Aalen (Württemberg)
0000000030,276,BW,Achern (Baden),Achern (Baden)
0000000031,276,BW,Albstadt (Württemberg),Albstadt (Württemberg)
0000000032,276,BW,Backnang,Backnang
0000000209,276,HE,Dillenburg,Dillenburg
0000000210,276,HE,Dreieich,Dreieich
0000000211,276,HE,Eschborn (Taunus),Eschborn (Taunus)
0000000212,276,HE,Flörsheim am Main,Flörsheim am Main

Вот мой взгляд / logi c для импорта "city.csv"

def import_city_from_file(self):
        data_folder = os.path.join(settings.BASE_DIR, 'app_name', 'resources/city_csv')
        for data_file in os.listdir(data_folder):
            with open(os.path.join(data_folder, data_file), encoding='utf-8') as data_file:
                data = csv.reader(data_file)
                for data_object in data:
                    id = data_object[0]

                    if data_object[1] != '':
                        country = models.Country.objects.get(pk=(data_object[1]),)
                    else:
                        country= models.Country.objects.get(pk = 1)

                    if data_object[2] != '':
                        state = models.State.objects.filter(pk=(data_object[2]))
                        print(state)

                    else:
                        state= models.State.objects.filter(pk = 1)

                    long_description_eng = data_object[3]
                    long_description_deu = data_object[4]


                    try:
                        city, created = models.City.objects.get_or_create(
                                id=id,
                                country_id=country,
                                state_id = state,
                                long_description_eng=long_description_eng,
                                long_description_deu=long_description_deu,

                            )
                        if created:
                            city.save()
                            display_format = "\nCity, {}, has been saved."
                            print(display_format.format(city))
                    except Exception as ex:
                        print(str(ex))
                        msg = "\n\nSomething went wrong saving this city: {}\n{}".format(id, str(ex))
                        print(msg)

Вот ошибка, которую я получаю при попытке импортировать файл CSV для города enter image description here

Буду признателен за любую помощь в решении этой проблемы.

Ответы [ 2 ]

0 голосов
/ 01 марта 2020

Мне удалось это исправить, изменив filter() на get() и использовав попытку и исключая ошибку, чтобы поймать ошибку.

def import_city_from_file(self):
        data_folder = os.path.join(settings.BASE_DIR, 'app_name', 'resources/city_csv')
        for data_file in os.listdir(data_folder):
            with open(os.path.join(data_folder, data_file), encoding='utf-8') as data_file:
                data = csv.reader(data_file)
                for data_object in data:
                    country = None
                    state = None
                    try:
                        country = models.Country.objects.get(id=data_object[0])
                    except:
                        pass
                    try:
                        state = models.State.objects.get(state_code=str(data_object[1]))

                    except:
                        pass
                    long_description_eng = data_object[2]
                    long_description_deu = data_object[3]


                    try:
                        city, created = models.City.objects.get_or_create(
                                id=id,
                                country_id=country,
                                state_id = state,
                                long_description_eng=long_description_eng,
                                long_description_deu=long_description_deu,

                            )
                        if created:
                            city.save()
                            display_format = "\nCity, {}, has been saved."
                            print(display_format.format(city))
                    except Exception as ex:
                        print(str(ex))
                        msg = "\n\nSomething went wrong saving this city: {}\n{}".format(id, str(ex))
                        print(msg)

0 голосов
/ 29 февраля 2020

В вашем городе get_or_create метод, который вы использовали страна и штат поля. В этой ситуации переменные вашей страны и штата должны быть объектами. Но ваши переменные - набор запросов (state = models.State.objects.filter(pk=(data_object[2])) этот код возвращает набор запросов.) Если вы уверены, что это состояние существовало, вы можете использовать метод get() вместо filter() метода.) Также, если вы используете state_id в своем городе get_or_create параметры кода, используйте city.id, а не объект city. Итак, вы должны изменить два раздела:

country= models.Country.objects.filter(pk = 1).first()

state = models.State.objects.filter(pk=data_object[2]).first()
''' this code return None if you have not any state object with this pk, 
    or you can use get() method but it raise DoesNotExist error, 
    you must     implement catching it 
'''

....


City.objects.get_or_create(
                            id=id,
                            country_id=country.id if country else None,
                            state_id = state.id if state else None,
                            long_description_eng=long_description_eng,
                            long_description_deu=long_description_deu,

                        )
...