그래서 맞춤 관리자를 만들었습니다.
class BulkInsertManager(models.Manager):
def _bulk_insert_or_update(self, create_fields, update_fields, values):
from django.db import connection, transaction
cursor = connection.cursor()
db_table = self.model._meta.db_table
values_sql = []
values_data =[]
for value_lists in values:
values_sql.append("(%s)" % (','.join([ "%s" for i in range(len(value_lists))]),))
values_data.extend(value_lists)
base_sql = "INSERT INTO %s (%s) VALUES " % (db_table, ",".join(create_fields))
on_duplicates = []
for field in update_fields:
on_duplicates.append(field + "=VALUES(" + field +")")
sql = "%s %s ON DUPLICATE KEY UPDATE %s" % (base_sql, ", ".join(values_sql), ",".join(on_duplicates))
cursor.executemany(sql, [values_data])
transaction.commit_unless_managed()
그리고 샘플 모델 :
class User_Friend(models.Model):
objects = BulkInsertManager() # assign a custom manager to handle bulk insert
id = models.CharField(max_length=255)
user = models.ForeignKey(User, null=False, blank=False)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
city = models.CharField(max_length=50, null=True, blank=True)
province = models.CharField(max_length=50, null=True, blank=True)
country = models.CharField(max_length=30, null=True, blank=True)
그리고 샘플 구현 : 여기에
def save_user_friends(user, friends):
user_friends = []
for friend in friends:
create_fields = ['id', 'user_id', 'first_name', 'last_name', 'city', 'province', 'country']
update_fields = ['first_name', 'last_name', 'city', 'province', 'country']
user_friends.append(
[
str(user.id),
str(friend['id']),
friend['first_name'],
friend['last_name'],
friend['city'],
friend['province'],
friend['country'],
]
)
User_Friend.objects._bulk_insert_or_update(create_fields, update_fields, user_friends)
가 gist입니다 여기에 관리자입니다.
왜 MySQL에서 djangos ORM을 사용하는 대신 원시 커서를 사용합니까? –
문제는 벌크 삽입입니다. 테이블에 이미있는 5k 개의 레코드를 받으면 5k 개의 ORM 오브젝트를 만드는 것이 효율적이지 않습니다. 그러나 objects.bulk_create를 사용하면 새 레코드를 삽입하는 것이 매우 효율적입니다. 나는 중복 엔트리 오류 (IntegrityError)를 얻을 것이다. – mmohiudd