Este paquete ayuda a los desarrolladores a fill la base de datos con real data en lugar de llenarlo manualmente.
Los datos se pueden presentar como CSV File , JSON File o in-code .
Dependency-Injection también está disponible para inyectar su lógica especificando un serializer_class o escribiendo su método seed personalizada.
Instalación con PIP:
pip install django-seeding:
Agregue 'django_seeding' a su configuración INSTALLED_APPS :
INSTALLED_APPS = [
...
'django_seeding',
]
Echemos un vistazo a un ejemplo rápido del uso de CSVFileModelSeeder sembrador de django-seeding para construir un sembrador simple para insertar datos en la base de datos.
django_seeding_example/modelos.py:
from django.db import models
class M1(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
django_seeding_example/seders.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/seders_data/m1seeder.csv:
title,description
t1,d1
t2,d2
Ahora solo necesitas ejecutar este comando:
python manage.py seed
Ahora vamos a profundizar en los diferentes tipos de sembradores con sus detalles:
Modelo ... SEEDER necesita model de clase de clase
Serializer..Seeder necesita serializer_class class-attribute
Csvfile..seeder necesita csv_file_path class-attribute
Jsonfile..seeder necesita json_file_path class-attribute
id: str (así recomendado)
Esto es lo que se almacenará en la tabla AppliedSeeder para verificar si una sembradora ya está aplicada o no
Se recomienda establecerlo como el nombre del sembrador
Por lo tanto, configúrelo y no lo cambie porque cuando se cambia el valor se considerará como un nuevo sembrador y se aplicará nuevamente incluso que se aplica el antiguo sembrador con el nombre anterior.
Valor predeterminado: str(type(seeder))
priority: int|float
Las sembradoras se ordenarán dependiendo de este atributo (abajo primero)
Valor predeterminado: float('inf')
just_debug: bool
Este atributo especifica si el sembrador se aplicará cuando el servidor esté en el modo de producción o no dependiendo de la variable de depuración en el archivo de configuración
DEBUG=False & just_debug=True -> no aplique
DEBUG=False & just_debug=False -> aplicar
DEBUG=True & just_debug=False -> aplicar
DEBUG=True & just_debug=True -> aplicar
Valor predeterminado: False
@SeederRegistry.register es el decorador que registra el sembrador, por lo que, si este decorador no se aplica, el sembrador no se aplicará
Las sembradoras modelo usan el método bulk_create, por lo que son más rápidos que las sembradoras de serializador
Las sembradoras infantiles usan el método Bulk_Create con la búsqueda de caché para los objetos relacionados, por lo que son más rápidos que los sembradores de serializador
El lector de archivos CSV está utilizando pandas para un mejor rendimiento y menos errores
Usar sembradores de modelo significa que los nombres de campo deben coincidir con los campos que ha definido en su modelo
Usar sembradores de serializador significa que los nombres de campo deben coincidir con los campos que ha definido en su serializador
Puede definir los métodos de clase get_ en lugar de atributos de clase como se muestra a continuación:
python manage.py seed
python manage.py runserver --seed
SEEDING_ON_RUNSERVER = True
SEEDING_ON_RUNSERVER=True en su archivo de configuración, puede dejar de sembrar en un corredor utilizando --dont-seed python manage.py runserver --dont-seed
De manera predeterminada, el comando de semillas utilizará la configuración de depuración desde el settings.py de su proyecto django. Sin embargo, puede anular esto pasando explícitamente la opción --debug al ejecutar el comando.
Forzar la depuración a la verdadera:
python manage.py seed --debug=True
Forzar la depuración a falso:
python manage.py seed --debug=False
Si no se especifica ningún valor para --debug, el comando recurrirá a la configuración de depuración actual del proyecto.
Para administrar las sembradoras desde un tablero, proporcionamos API que ofrecen un control total sobre las operaciones de sembradores.
Route de las vistas de las sembradas en nuestras URL de la aplicación Seeder.
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
Enruta nuestra aplicación de sembradora en las URL del proyecto.
from django.urls import include
...
urlpatterns = [
...
path('seeder/', include('django_seeding_example.urls')),
...
]
...
Puede personalizar los permisos o cualquier otra lógica heredando los vistas proporcionados y anulando los métodos necesarios para cumplir con los requisitos específicos del proyecto.
Para que sea más fácil para usted probar las API, hemos proporcionado una colección de postman que contiene todos los puntos finales de la API. Puede descargar la colección e importarla a Postman para pruebas rápidas y fáciles.
Pasos para usar la colección Postman:
En este paquete, las clases de sembradora deben estar registradas para aplicarse. Este punto final te permite:
Lista de todos los sembradores registrados: esto incluye sembradores aplicados y no aplicados.
Get /registered-seeders/
Aplique sembradores específicos: puede aplicar todas las sembradoras o seleccionar las específicas.
Post /registered-seeders/seed-all/
Podemos especificar el modo de depuración para la siembra y los ID necesarios para sembrar en el cuerpo de la misma manera (ambos son opcionales, pueden ser nulos):
{
"debug": true,
"ids": [
"id1",
"id2"
]
}
Las sembradoras aplicadas se rastrean en un modelo dedicado para evitar que se apliquen varias veces. Los puntos finales de sembrador aplicados proporcionan una gestión completa sobre los registros de sembradores aplicados, lo que le permite:
Lista de todos los sembradores aplicados: vea todas las sembradoras que se han aplicado.
Get /applied-seeders/
Recupere un sembrador aplicado específico: vea los detalles de un sembrador en particular.
Get /applied-seeders/{id}/
Marque una sembradora aplicada: cree un registro en el modelo de sembrador aplicado para indicar que se ha aplicado.
Post /applied-seeders/
Solicitud de cuerpo:
{
"id": "id"
}
Actualizar un registro de sembrador: útil para cambiar la identificación de una sembradora.
Put /applied-seeders/{id}/
Solicitud de cuerpo:
{
"id": "new_id"
}
Elimine una semilla aplicada específica: elimina un registro para marcar el sembrador como no aplicado.
Eliminar /applied-seeders/{id}/
Eliminar todas las sembradoras aplicadas: esto permite que todos los sembradores se vuelvan a aplicar.
Eliminar /applied-seeders/delete-all/
ID: int (Primary Key)
creado_at: datetime
Actualated_at: datetime
Aquí profundizaremos en las clases de sembradores y sus detalles
Fast bulk_create Seeder
Observe que los títulos en el csv-file tienen que coincidir con los nombres de campo en el model
modelos.py
class M1(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
sembradores.py
@SeederRegistry.register
class M1Seeder(seeders.CSVFileModelSeeder):
id = 'M1Seeder'
priority = 1
model = M1
csv_file_path = 'django_seeding_example/seeders_data/M1Seeder.csv'
sembrado_data/m1seeder.csv
title,description
t1,d1
t2,d2
Fast bulk_create Seeder
Observe que las claves en el json-file deben coincidir con los nombres de campo en el model
modelos.py
class M2(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
sembradores.py
@SeederRegistry.register
class M2Seeder(seeders.JSONFileModelSeeder):
id = 'M2Seeder'
priority = 2
model = M2
json_file_path = 'django_seeding_example/seeders_data/M2Seeder.json'
sembrado_data/m2seeder.json
[
{
"title": "json t1",
"description": "json d1"
},
{
"title": "json t2",
"description": "json d2"
}
]
Sededer bulk-create parpadeante implementado con estrategia de almacenamiento en caché.
Este sembrador fue concebido para modelos de niños semillas, es decir, modelos que al menos un campo es una clave extranjera ( models.ForeignKey Key Foreign), pero también puede usarse en lugar de JSONFileModelSeeder para modelos generales.
Observe que las claves en el json-file deben coincidir con los nombres de campo en el model y también la estructura. Los modelos principales se representan como dicts internos.
modelos.py
class Father ( models . Model ):
name = models . TextField ()
class Son ( models . Model ):
name = models . TextField ()
father = models . ForeignKey ( Father , on_delete = models . CASCADE )sembradores.py
@ SeederRegistry . register
class SonSeeder ( seeders . JSONFileChildSeeder ):
id = 'SonSeeder'
model = Son
priority = 10
json_file_path = 'django_seeding_example/seeders_data/SonSeeder.json'sembradores_data/sonseeder.json
[
{
"name" : " json son 1 " ,
"father" : { "name" : " json father 1 " }
},
{
"name" : " json son 2 " ,
"father" : { "name" : " json father 2 " }
}
]Observe que la prioridad del niño debe ser mayor que la prioridad de los padres para que el modelo principal se sembra antes. ¡No sembrar a los padres antes generará errores! Cada campo que es un FK debe ser un diccionario con nombres de campo igual que su modelo relacionado.
Esta clase de sembradora puede manejar relaciones bastante complejas entre los modelos. Expandamos a la familia (juego de palabras):
modelos.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 )sembradores.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'sembradores_data/hijaSeeder.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 " }
}
]sembradora_data/nietoDer.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 " }
}
}
]Sembrador uno por uno lento
Observe que los títulos en el csv-file tienen que coincidir con los nombres de campo en el serializer
Este sembrador se utiliza para inyectar un serializador para implementar la lógica de creación personalizada
modelos.py
class M3(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
Serializers.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)
sembradores.py
@SeederRegistry.register
class M3Seeder(seeders.CSVFileSerializerSeeder):
id = 'M3Seeder'
priority = 3
serializer_class = M3Serializer
csv_file_path = 'django_seeding_example/seeders_data/M3Seeder.csv'
sembrado_data/m3seeder.csv
title,description
t1,d1
t2,d2
Sembrador uno por uno lento
Observe que las claves en el json-file tienen que coincidir con los nombres de campo en el serializer
Este sembrador se utiliza para inyectar un serializador para implementar la lógica de creación personalizada
modelos.py
class M4(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
Serializers.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)
sembradores.py
@SeederRegistry.register
class M4Seeder(seeders.JSONFileSerializerSeeder):
id = 'M4Seeder'
priority = 4
serializer_class = M4Serializer
json_file_path = 'django_seeding_example/seeders_data/M4Seeder.json'
sembradores_data/m4seeder.json
[
{
"title": "json t1",
"description": "json d1"
},
{
"title": "json t2",
"description": "json d2"
}
]
Fast bulk_create Seeder
modelos.py
class M5(models.Model):
title = models.CharField(max_length=100, null=True)
description = models.TextField(null=True)
sembradores.py
@SeederRegistry.register
class M5Seeder(seeders.EmptySeeder):
id = 'M5Seeder'
priority = 5
model = M5
records_count = 2
Fast bulk_create Seeder
Observe que las claves en el atributo de clase data tienen que coincidir con los nombres de campo en el model
modelos.py
class M6(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
sembradores.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"
},
]
Sembrador uno por uno lento
Observe que las claves en el atributo de clase data tienen que coincidir con los nombres de campo en el serializer
Este sembrador se utiliza para inyectar un serializador para implementar la lógica de creación personalizada
modelos.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)
sembradores.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"
},
]
Aquí puede escribir su lógica como desee en el método de semilla
modelos.py
class Post(models.Model):
content = models.TextField()
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField()
sembradores.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')
Si tiene sugerencias sobre cómo se podría mejorar la siembra de Django, o desea informar un error, ¡abra un problema! Nos encantaría todos y cualquier contribución.
Para obtener más información, consulte la guía contribuyente.
Suliman Awad - [email protected] - LinkedIn
Enlace del proyecto: https://github.com/suliman-99/django-seeding
Licencia de MIT
Copyright (c) 2023 Suliman Awad
Para obtener más información, consulte el archivo de licencia.