Tenho muitos objetos para salvar no banco de dados e, por isso, quero criar instâncias de Model com isso.
Com django, posso criar todas as instâncias de modelos, com MyModel(data)
, e depois quero salvá-los todos.
Atualmente, tenho algo assim:
for item in items:
object = MyModel(name=item.name)
object.save()
Estou me perguntando se posso salvar uma lista de objetos diretamente, por exemplo:
objects = []
for item in items:
objects.append(MyModel(name=item.name))
objects.save_all()
Como salvar todos os objetos em uma transação?
django
django-models
Alexis Métaireau
fonte
fonte
Respostas:
a partir do desenvolvimento do django, existe
bulk_create
como um método gerenciador de objetos que recebe como entrada um array de objetos criados usando o construtor de classe. verifique a documentação do djangofonte
bulk_create
: docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-createIf the model’s primary key is an AutoField it does not retrieve and set the primary key attribute, as save() does, unless the database backend supports it (currently only PostgreSQL).
bulk_create()
não dispara nenhum sinal. Eu quero saber porque.Use o
bulk_create()
método. É padrão no Django agora.Exemplo:
Entry.objects.bulk_create([ Entry(headline="Django 1.0 Released"), Entry(headline="Django 1.1 Announced"), Entry(headline="Breaking: Django is awesome") ])
fonte
funcionou para mim usar o tratamento manual de transações para o loop (postgres 9.1):
from django.db import transaction with transaction.commit_on_success(): for item in items: MyModel.objects.create(name=item.name)
na verdade, não é o mesmo que inserção em massa de banco de dados "nativo", mas permite que você evite / diminua os custos de transporte / operações orms / análise de consulta sql
fonte
commit_on_success
mais. Você deve usartransaction.atomic()
See: stackoverflow.com/questions/21861207/…Aqui está como criar entidades em massa a partir de arquivos separados por colunas, deixando de lado todas as rotinas de unquoting e un-escape:
SomeModel(Model): @classmethod def from_file(model, file_obj, headers, delimiter): model.objects.bulk_create([ model(**dict(zip(headers, line.split(delimiter)))) for line in file_obj], batch_size=None)
fonte
para uma implementação de linha única, você pode usar uma expressão lambda em um mapa
map(lambda x:MyModel.objects.get_or_create(name=x), items)
Aqui, lambda corresponde a cada item na lista de itens com x e cria um registro de banco de dados, se necessário.
Documentação Lambda
fonte
lambda
tem de sermap
ped sobreitems
:map(lambda name: MyModel.objects.get_or_create(name = name), items)
O uso de criar causará uma consulta por novo item. Se você deseja reduzir o número de consultas INSERT, você precisará usar outra coisa.
Tive algum sucesso usando o snippet Bulk Insert, embora o snippet seja bastante antigo. Talvez haja algumas mudanças necessárias para fazê-lo funcionar novamente.
http://djangosnippets.org/snippets/446/
fonte
Confira esta postagem do blog sobre o módulo bulkops .
No meu aplicativo django 1.3, experimentei uma aceleração significativa.
fonte
A maneira mais fácil é usar o
create
método Manager, que cria e salva o objeto em uma única etapa.for item in items: MyModel.objects.create(name=item.name)
fonte
name
for único e forem possíveis entradas duplicadas, é uma boa ideia usarget_or_create
.