Множественное обновление с помощью RAW SQL в Django

У меня есть ситуация в Django, когда мне нужно обновить несколько строк в базе данных, используя RAW SQL, потому что это таблица, созданная на другой системе и не управляемая ORM.

Поскольку необходимо обновить несколько строк, возможно ли выполнить одну команду, которая обновляет все сразу, без необходимости включать cursor.execute(SQL,params) внутрь цикла for?

На данный момент я смог заставить это обновление работать правильно, только включив каждую строку обновления в цикл for, но я не думаю, что это хорошая практика. Это работает примерно так:

person_list=[[john,33,50],[mary,20,41],[peter,12,93]]

with connection.cursor() as cursor:
    for item in person_list:
        SQL="UPDATE PERSON SET NAME = %s, AGE = %s WHERE PERSON_ID = %s"
        params.extend([item[0], item[1], item[2]])
        cursor.execute(SQL,params)

Я хотел бы, чтобы Django выполнял одну команду SQL следующим образом:

    SQL+="""
        update person name='john', age='33' where person_id=50;
        update person name='mary', age='20' where person_id=41;
        update person name='John', age='12' where person_id=93;
    """
    cursor.execute(SQL)

Я пытался сделать следующее, но безуспешно, с сообщением об ошибке "ORA-00933:SQL command not properly ended":

    for item in person_list:
        SQL+="UPDATE PERSON SET NAME = %s, AGE = %s WHERE PERSON_ID = %s; "
        params.extend([item[0], item[1], item[2]])

    with connection.cursor() as cursor:
        cursor.execute(SQL,params)
        

Я не знаю, не слишком ли я беспокоюсь об этом, и действительно ли это что-то, что повлияет на производительность системы. Мое беспокойство связано именно с тем, что я всегда слышал от всех, что никогда не следует включать SQL-команду внутрь цикла.

Базой данных является Oracle.

Спасибо

Если у вас есть модель Person, вы можете выполнить обновление в массовом порядке с помощью Django ORM. Итак, если модель выглядит следующим образом:

class Person(models.Model):
    person_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    age = models.IntegerField()

Затем вы можете обновлять массово с помощью .bulk_update(…) [Django-doc]:

person_list=[['john', 33, 50], ['mary', 20, 41], ['peter', 12, 93]]

Person.objects.bulk_update(
    [Person(person_id=person_id, name=name, age=age) for name, age, person_id in person_list]
    fields=['name', 'age']
)

Использование Django ORM удобнее, меньше вероятность ошибок, и он будет, если вы правильно определите settings.py разговаривать на правильном диалекте с базой данных.

Вернуться на верх