ぷろぐら×でざいん

Django 一括 作成/更新/削除

Django 一括 作成/更新/削除

Django 一括 作成/更新/削除

Model

このModelを使ってコードを書いていきますー。


# -*- coding: utf-8 -*-
from django.db import models


class User(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=255, default='')
    email = models.CharField(max_length=255, default='')

    created_at = models.DateTimeField(auto_now_add=True, )
    updated_at = models.DateTimeField(auto_now=True, )


一括作成


from app.models.user import User


users = []
users.append(User(name='太郎', email='taro@mail.com')
users.append(User(name='次郎', email='jiro@mail.com'))
users.append(User(name='三郎', email='saburo@mail.com'))

User.objects.bulk_create(users)

listUserインスタンスを入れていき、それを bulk_createに入れることで一括でデータを作成できます。


from app.models.user import User


users = []
for _ in range(0, 1000000):
    users.append(User(name='太郎', email='taro@mail.com')
    users.append(User(name='次郎', email='jiro@mail.com'))
    users.append(User(name='三郎', email='saburo@mail.com'))

User.objects.bulk_create(users, batch_size=1000)

上記のロジックでは300万インスタンスがリストに入っているので、それを一括作成しようとするMySQLの場合はデータベースのエラーになる可能性があります。それを防ぐ為に batch_sizeというものがあり、上記の場合だと 1,000レコードずつ作成するようになっています。適宜使って行くと良いかも知れません。


一括更新

Filter編

objects.filterで取得したインスタンスのあるカラムが一括で更新するケースです。


from app.models.user import User


User.objects.filter(email='bar@mail.com').update(email='hoge@mail.com')

上記ではメールアドレスが「bar@mail.com」になっているユーザーのメールアドレス「hoge@mail.com」に更新しています。

個別一括更新

bulk_updateを利用し、それぞれのインスタンスの更新を一括でする方法です。


from app.models.user import User


user1 = User.objects.get(id=1)
user2 = User.objects.get(id=2)
user3 = User.objects.get(id=3)

user1.email = 'new1@mail.com'
user2.email = 'new2@mail.com'
user3.email = 'new3@mail.com'

users = [user1, user2, user3]
User.objects.bulk_update(users, fields=['email'], batch_size=1000)

bulk_createと同様に Userのインスタンスリストを引数に渡し、更新したいカラムを fieldsにリストで渡します。複数のカラムを更新対象にしたい場合はリストに追加しましょう。あと、batch_sizeも一括作成の時と同様に適宜利用すると良いかも知れません。

上記の場合はメールだけの更新ですので fieldsのリストには emailのみを入れています。


一括削除

一括削除は特に固有のメソッドはありません。


from app.models.user import User


User.objects.filter(email='hoge@mail.com').delete()

こちらも削除対象となるデータ量があまり多いとデータベース側のエラーになることがあるので注意が必要です。
大量データになる場合はページネーションを利用して削除すると良いかも知れませんね。


あとがき

如何だったでしょうか?とても簡単に実装できますので、ループ文の中でデータを作成・更新・削除している人は今すぐにも実装を検討してみてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください