Создание записей по модели - PullRequest
0 голосов
/ 02 декабря 2018

Предположим, у меня есть такие модели:

class Recipe (models.Model):
    par_recipe = models.CharField(max_length=200)

class Line (models.Model):
    par_machine = models.CharField(max_length=200)

class Measurements (models.Model):
    par_value = models.IntegerField(default=0)
    id_line = models.ForeignKey(Line)
    id_recipe = models.ForeignKey(Recipe)

Правильно ли я понимаю, что таким образом у меня есть отношение 1: 1, и идентификаторы добавления записей будут создаваться автоматически id_line,id_recipe.

добавлю например:

for row in ws.iter_rows(row_offset=1):
        recipe =Recipe()
        line = line()
        measurements = Measurements()

        recipe.par_recipe = row[1].value
        line.par_machine = row[2].value
        measurements.par_value = row[8].value

И небольшой вопрос об измерениях был задуман, что все вторичные ключи должны идти на него, теперь это реализовано правильно?

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Правильно ли я понимаю, что таким образом у меня есть отношение 1: 1, и при добавлении идентификаторов записей будут автоматически создаваться id_line, id_recipe.

Отношения будут не ссылка на ранее созданные объекты, что также было бы небезопасно, поскольку небольшое изменение фрагмента кода может привести к совершенно другому способу связывания элементов вместе.

Кроме того, ForeignKey является отношение многие-к-одному : несколько Measurements объектов могут ссылаться на один и тот же объект Recipe.

Это необходимо сделать вручную, например:

for row in ws.iter_rows(row_offset=1):
    recipe = Recipe.objects.create(par_recipe=row[1].value)
    line = Line.objects.create(par_machine=row[2].value)
    measurements = Measurements.objects.create(
        par_value=row[8].value,
        <b>id_line=line,
        id_recipe=recipe</b>
    )

Обратите внимание, что ForeignKey относится к объектам, а не к значению первичного ключа, поэтому вы, вероятно, захотите переименовать свои ForeignKey s.Модель обычно имеет единственное имя, поэтому Measurement вместо Measurements:

class <b>Measurement</b>(models.Model):
    par_value = models.IntegerField(default=0)
    <b>line</b> = models.ForeignKey(Line, on_delete=models.CASCADE)
    <b>recipe</b> = models.ForeignKey(Recipe, on_delete=models.CASCADE)
0 голосов
/ 02 декабря 2018

Это не совсем так, вам придется связать их вместе:

for row in ws.iter_rows(row_offset=1):
    recipe =Recipe.objects.create(par_recipe=row[1].value)
    line = Line.objects.create(par_machine=row[2].value)
    measurements = Measurements.objects.create(
        par_value=row[8].value, 
        id_line=line, 
        id_recipe=recipe
    )

Ничего из этого не оптимизировано в БД, вы можете использовать транзакции для оптимизации записи в БД.

Вы могли бы сделать это быстрее, если есть много строк, используя транзакции:

from django.db import transaction

with transaction.atomic():
    for row in ws.iter_rows(row_offset=1):
        recipe =Recipe.objects.create(par_recipe=row[1].value)
        line = Line.objects.create(par_machine=row[2].value)
        measurements = Measurements.objects.create(
            par_value=row[8].value, 
            id_line=line, 
            id_recipe=recipe
        )

Это создаст транзакцию и запишет одну вместо каждого.Но при этом также произойдет ошибка всей транзакции.

см. Транзакции с базой данных Django

Вы можете проявить больше творчества, подсчитав количество записей и записав каждую 1000 записей.например:

from django.db import transaction

with transaction.atomic():
    for idx, row in enumerate(ws.iter_rows(row_offset=1)):
        recipe =Recipe.objects.create(par_recipe=row[1].value)
        line = Line.objects.create(par_machine=row[2].value)
        measurements = Measurements.objects.create(
            par_value=row[8].value, 
            id_line=line, 
            id_recipe=recipe
        )
        # every 1000 records, commmit the transaction
        if idx % 1000 == 0:
           transaction.commit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...