Este pacote ajuda os desenvolvedores a fill o banco de dados com real data em vez de preenchê -los manualmente.
Os dados podem ser apresentados como CSV File , JSON File ou in-code .
Dependency-Injection também está disponível para injetar sua lógica, especificando um serializer_class ou escrevendo seu método seed personalizado.
Instalação usando PIP:
pip install django-seeding:
Adicione 'django_seeding' à sua configuração INSTALLED_APPS :
INSTALLED_APPS = [
...
'django_seeding',
]
Vamos dar uma olhada em um exemplo rápido de usar CSVFileModelSeeder SEEDER DO django-seeding para criar uma semeadora simples para inserir dados no banco de dados.
django_seeding_example/models.py:
from django.db import models
class M1(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
django_seeding_example/Seeders.py:
from django_seeding import seeders
from django_seeding.seeder_registry import SeederRegistry
from django_seeding_example.models import M1
@SeederRegistry.register
class M1Seeder(seeders.CSVFileModelSeeder):
model = M1
csv_file_path = 'django_seeding_example/seeders_data/M1Seeder.csv'
django_seeding_example/Seeders_data/m1seeder.csv:
title,description
t1,d1
t2,d2
Agora você só precisa executar este comando:
python manage.py seed
Agora vamos nos aprofundar nos diferentes tipos de sementes com seus detalhes:
Modelo .. Seeder precisa de model de atributo de classe
Serializer..seeder precisa serializer_class class-attribute
CSVFile..seeder precisa de csv_file_path class-attribute
Jsonfile..seeder precisa json_file_path class-attribute
id: str (tão recomendado)
É isso que será armazenado na tabela Appliedeeder para verificar se um semeador já está aplicado ou não
Recomenda -se defini -lo como o nome do semeador
Portanto, defina e não altere, porque quando o valor for alterado será considerado como um novo semeador e será aplicado novamente, mesmo que o antigo semeador com o nome antigo seja aplicado
Valor padrão: str(type(seeder))
priority: int|float
Os semeadores serão classificados, dependendo deste atributo (primeiro primeiro)
Valor padrão: float('inf')
just_debug: bool
Este atributo especificar se o semeador será aplicado quando o servidor estiver no modo de produção ou não dependendo da variável de depuração no arquivo de configurações
DEBUG=False & just_debug=True -> não aplique
DEBUG=False & just_debug=False -> Aplicar
DEBUG=True & just_debug=False -> Aplicar
DEBUG=True & just_debug=True -> Aplicar
Valor padrão: False
@SeederRegistry.register é o decorador que registra a semente, então, se este decorador não for aplicado, o semeador não será aplicado
Os semeadores do modelo usam o método BULK_CREATE, então, são mais rápidos que semeadores de serializador
As semeadoras infantis usam o método Bulk_create com o cache buscar objetos relacionados, então, são mais rápidos que os semeadores de serializador
O leitor de arquivos CSV está usando pandas para um melhor desempenho e menos bugs
Usando semeadores de modelo significa que os nomes de campo devem corresponder aos campos que você definiu em seu modelo
Usando semeadores de serializador significa que os nomes de campo devem corresponder aos campos que você definiu em seu serializador
Você pode definir os métodos get_ classe em vez de atributos de classe como abaixo:
python manage.py seed
python manage.py runserver --seed
SEEDING_ON_RUNSERVER = True
SEEDING_ON_RUNSERVER=True em seu arquivo de configurações, poderá parar de semear em um servidor de corrida usando --dont-seed python manage.py runserver --dont-seed
Por padrão, o comando SEEND usará a configuração de depuração do seu Django Project Settings.py. No entanto, você pode substituir isso passando explicitamente a opção - -debug ao executar o comando.
Força Debug to True:
python manage.py seed --debug=True
Depuração força para false:
python manage.py seed --debug=False
Se nenhum valor for especificado para -Debug, o comando voltará à configuração de depuração atual do projeto.
Para gerenciar semeadores a partir de um painel, fornecemos APIs que oferecem controle total sobre operações de semeador.
Rota Vistas de semeaddade de django em nosso aplicativo de semente URLs.py:
from rest_framework import routers
from django_seeding.apis.views import AppliedSeederViewSet, RegisteredSeederViewSet
router = routers.DefaultRouter()
router.register('registered-seeders', RegisteredSeederViewSet, 'registered-seeders')
router.register('applied-seeders', AppliedSeederViewSet, 'applied-seeders')
urlpatterns = router.urls
Rotear nosso aplicativo de semente no projeto URLS.PY:
from django.urls import include
...
urlpatterns = [
...
path('seeder/', include('django_seeding_example.urls')),
...
]
...
Você pode personalizar as permissões ou qualquer outra lógica, herdando os visualizações fornecidas e substituindo os métodos necessários para atender aos requisitos específicos do projeto.
Para facilitar o teste das APIs, fornecemos uma coleção Postman contendo todos os pontos de extremidade da API. Você pode baixar a coleção e importá -la para o Postman para testes rápidos e fáceis.
Etapas para usar a coleção Postman:
Neste pacote, as classes de sementes devem ser registradas para serem aplicadas. Este terminal permite que você:
Liste todos os semeadores registrados: isso inclui semeadores aplicados e não aplicados.
Get /registered-seeders/
Aplique semeadores específicos: você pode aplicar todos os semeadores ou selecionar os específicos.
POST /registered-seeders/seed-all/
Podemos especificar o modo de depuração para a semeadura e os IDs necessários para serem semeados no corpo como este (os dois são opcionais - podem ser nulos):
{
"debug": true,
"ids": [
"id1",
"id2"
]
}
As sementes aplicadas são rastreadas em um modelo dedicado para impedir que sejam aplicadas várias vezes. Os terminais de sementes aplicados fornecem gerenciamento completo sobre os registros de sementes aplicados, permitindo que você::
Liste todos os semeadores aplicados: veja todos os semeadores que foram aplicados.
Get /applied-seeders/
Recupere um semeador aplicado específico: Veja os detalhes de um determinado semeador.
Get /applied-seeders/{id}/
Marque um semeador como aplicado: Crie um registro no modelo de sementes aplicadas para indicar que foi aplicado.
Post /applied-seeders/
Solicitar corpo:
{
"id": "id"
}
Atualize um registro de sementes: útil para alterar o ID de um semente.
Put /applied-seeders/{id}/
Solicitar corpo:
{
"id": "new_id"
}
Exclua um semeador aplicado específico: remove um registro para marcar o semente como não aplicado.
Excluir /applied-seeders/{id}/
Exclua todos os semeadores aplicados: isso permite que todos os semeadores sejam aplicados.
Excluir /applied-seeders/delete-all/
ID: int (Primary Key)
Criado_at: datetime
atualizado_at: datetime
Aqui iremos mais fundo nas aulas de sementes e seus detalhes
Fast bulk_create Seeder
Observe que os títulos no csv-file precisam corresponder aos nomes de campo no model
models.py
class M1(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
semeres.py
@SeederRegistry.register
class M1Seeder(seeders.CSVFileModelSeeder):
id = 'M1Seeder'
priority = 1
model = M1
csv_file_path = 'django_seeding_example/seeders_data/M1Seeder.csv'
Seeders_data/m1seeder.csv
title,description
t1,d1
t2,d2
Fast bulk_create Seeder
Observe que as chaves no json-file devem corresponder aos nomes de campo no model
models.py
class M2(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
semeres.py
@SeederRegistry.register
class M2Seeder(seeders.JSONFileModelSeeder):
id = 'M2Seeder'
priority = 2
model = M2
json_file_path = 'django_seeding_example/seeders_data/M2Seeder.json'
Seeders_data/m2seeder.json
[
{
"title": "json t1",
"description": "json d1"
},
{
"title": "json t2",
"description": "json d2"
}
]
A semeadora bulk-create pisca-rápida implementada com a estratégia de cache.
Essa semeadora foi concebida para semear modelos de crianças JSONFileModelSeeder ou seja, modelos que pelo menos um campo é uma chave estrangeira ( models.ForeignKey .
Observe que as chaves no json-file devem corresponder aos nomes de campo no model e também na estrutura. Os modelos dos pais são representados como ditos internos.
models.py
class Father ( models . Model ):
name = models . TextField ()
class Son ( models . Model ):
name = models . TextField ()
father = models . ForeignKey ( Father , on_delete = models . CASCADE )semeres.py
@ SeederRegistry . register
class SonSeeder ( seeders . JSONFileChildSeeder ):
id = 'SonSeeder'
model = Son
priority = 10
json_file_path = 'django_seeding_example/seeders_data/SonSeeder.json'Seeders_Data/Sonseeder.json
[
{
"name" : " json son 1 " ,
"father" : { "name" : " json father 1 " }
},
{
"name" : " json son 2 " ,
"father" : { "name" : " json father 2 " }
}
]Observe que a prioridade da criança deve ser maior que a prioridade dos pais para que o modelo pai seja semeado antes. Não semear o pai antes, levantará erros! Cada campo que é um FK deve ser um dicionário com nomes de campo iguais ao seu modelo relacionado.
Essa classe de sementes pode lidar com relações bastante complexas entre os modelos. Vamos expandir a família (trocadilhos):
models.py
class Mother ( models . Model ):
name = models . TextField ()
class Daughter ( models . Model ):
name = models . TextField ()
father = models . ForeignKey ( Father , on_delete = models . CASCADE )
mother = models . ForeignKey ( Mother , on_delete = models . CASCADE )
class Meta :
constraints = [
UniqueConstraint (
fields = [ 'name' , 'father' , 'mother' ],
name = 'unique_parentage'
)]
class Grandson ( models . Model ):
name = models . TextField ()
parentage = models . ForeignKey ( Daughter , on_delete = models . CASCADE )semeres.py
@ SeederRegistry . register
class DaughterSeeder ( seeders . JSONFileChildSeeder ):
id = 'DaughterSeeder'
priority = 10
model = Daughter
json_file_path = 'django_seeding_example/seeders_data/DaughterSeeder.json'
@ SeederRegistry . register
class GrandsonSeeder ( seeders . JSONFileChildSeeder ):
id = 'GrandsonSeeder'
model = Grandson
json_file_path = 'django_seeding_example/seeders_data/GrandsonSeeder.json'Seeders_data/filhaseeder.json
[
{
"name" : " json daughter 1 " ,
"father" : { "name" : " json father 1 " },
"mother" : { "name" : " json mother 1 " }
},
{
"name" : " json daughter 2 " ,
"father" : { "name" : " json father 2 " },
"mother" : { "name" : " json mother 2 " }
}
]Seeders_data/netonseeder.json
[
{
"name" : " json grandson 1 " ,
"parentage" : {
"name" : " json daughter 1 " ,
"father" : { "name" : " json father 1 " },
"mother" : { "name" : " json mother 1 " }
}
},
{
"name" : " json grandson 2 " ,
"parentage" : {
"name" : " json daughter 2 " ,
"father" : { "name" : " json father 2 " },
"mother" : { "name" : " json mother 2 " }
}
}
]Semeador lento um a um
Observe que os títulos no csv-file precisam corresponder aos nomes de campo no serializer
Este semeador é usado para injetar um serializador para implementar a lógica Create Create personalizada
models.py
class M3(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
serializadores.py
class M3Serializer(serializers.ModelSerializer):
class Meta:
model = M3
fields = ['title', 'description']
def create(self, validated_data):
validated_data['title'] = '__' + validated_data['title'] + '__'
validated_data['description'] = '__' + validated_data['description'] + '__'
return super().create(validated_data)
semeres.py
@SeederRegistry.register
class M3Seeder(seeders.CSVFileSerializerSeeder):
id = 'M3Seeder'
priority = 3
serializer_class = M3Serializer
csv_file_path = 'django_seeding_example/seeders_data/M3Seeder.csv'
Seeders_data/m3seeder.csv
title,description
t1,d1
t2,d2
Semeador lento um a um
Observe que as chaves no json-file precisam corresponder aos nomes de campo no serializer
Este semeador é usado para injetar um serializador para implementar a lógica Create Create personalizada
models.py
class M4(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
serializadores.py
class M4Serializer(serializers.ModelSerializer):
class Meta:
model = M4
fields = ['title', 'description']
def create(self, validated_data):
validated_data['title'] = '__' + validated_data['title'] + '__'
validated_data['description'] = '__' + validated_data['description'] + '__'
return super().create(validated_data)
semeres.py
@SeederRegistry.register
class M4Seeder(seeders.JSONFileSerializerSeeder):
id = 'M4Seeder'
priority = 4
serializer_class = M4Serializer
json_file_path = 'django_seeding_example/seeders_data/M4Seeder.json'
Seeders_data/m4seeder.json
[
{
"title": "json t1",
"description": "json d1"
},
{
"title": "json t2",
"description": "json d2"
}
]
Fast bulk_create Seeder
models.py
class M5(models.Model):
title = models.CharField(max_length=100, null=True)
description = models.TextField(null=True)
semeres.py
@SeederRegistry.register
class M5Seeder(seeders.EmptySeeder):
id = 'M5Seeder'
priority = 5
model = M5
records_count = 2
Fast bulk_create Seeder
Observe que as chaves da classe de data precisam corresponder aos nomes de campo no model
models.py
class M6(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
semeres.py
@SeederRegistry.register
class M6Seeder(seeders.ModelSeeder):
id = 'M6Seeder'
priority = 6
model = M6
data = [
{
"title": "in-code t1",
"description": "in-code d1"
},
{
"title": "in-code t2",
"description": "in-code d2"
},
]
Semeador lento um a um
Observe que as chaves da classe de data precisam corresponder aos nomes de campo no serializer
Este semeador é usado para injetar um serializador para implementar a lógica Create Create personalizada
models.py
class M7(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
serializer.py
class M7Serializer(serializers.ModelSerializer):
class Meta:
model = M7
fields = ['title', 'description']
def create(self, validated_data):
validated_data['title'] = '__' + validated_data['title'] + '__'
validated_data['description'] = '__' + validated_data['description'] + '__'
return super().create(validated_data)
semeres.py
@SeederRegistry.register
class M7Seeder(seeders.SerializerSeeder):
id = 'M7Seeder'
priority = 7
serializer_class = M7Serializer
data = [
{
"title": "in-code t1",
"description": "in-code d1"
},
{
"title": "in-code t2",
"description": "in-code d2"
},
]
Aqui você pode escrever sua lógica como quiser no método de semente
models.py
class Post(models.Model):
content = models.TextField()
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField()
semeres.py
@SeederRegistry.register
class CustomSeeder(seeders.Seeder):
id = 'CustomSeeder'
priority = 8
def seed(self):
post1 = Post.objects.create(content='post1')
post2 = Post.objects.create(content='post1')
comment1 = Comment.objects.create(post=post1, content='comment1')
comment2 = Comment.objects.create(post=post1, content='comment2')
comment3 = Comment.objects.create(post=post2, content='comment3')
comment4 = Comment.objects.create(post=post2, content='comment4')
Se você tiver sugestões de como a semeadura do Django pode ser melhorada ou deseja relatar um bug, abra um problema! Adoraríamos todas e quaisquer contribuições.
Para mais informações, confira o guia contribuinte.
Suliman Awad - [email protected] - LinkedIn
Link do projeto: https://github.com/suliman-99/django-seeding
MIT Licença
Copyright (C) 2023 Suliman Awad
Para saber mais, consulte o arquivo de licença.