Команда пользовательского управления Django для заполнения таблицы "многие ко многим
Я изучаю python и Django. Я загрузил довольно большой объем данных из csv файлов в мою базу данных. Один из файлов csv описывает отношение "многие ко многим".
# models.py
class Provider:
name = models.CharField(max_length=25)
product = models.ManyToManyField("Product", related_name="vendor_products")
class Product:
name = models.CharField(max_length=25)
Сгенерированные таблицы базы данных - core_provider
, core_product
и core_provider_product
.
У меня уже есть данные для core_provider_product
| provider_id | product_id |
|-------------|------------|
| 3 | 1001 |
| 1 | 1003 |
| 3 | 1007 |
| 2 | 1001 |
| 1 | 1002 |
| 1 | 1001 |
# etc
и я передаю их в базу данных с помощью этой пользовательской команды управления:
class Command(BaseCommand):
# add_arguments snip
def handle(self, *args, **options):
for file in options["csvfile"]:
with open(file) as f:
reader = csv.reader(f)
for row in reader:
myprovider = row[0]
myprovider_obj = Provider.objects.get(pk=myprovider)
myproduct = row[1]
myproduct_obj = Product.objects.get(pk=myproduct)
myprovider_obj.product.add(myproduct_obj)
который работает нормально. (занимает около 6 минут для файла размером ~6000 строк)
Но это кажется ужасно неаккуратным и неэффективным. Какой способ сделать это лучше? Я подозреваю, что в Django уже есть способ достичь этого, но мои навыки поиска подводят меня, и я не могу понять, как сделать это эффективно.
Вы можете использовать команду loaddata для загрузки файла .json из оболочки:
python3 manage.py loaddata /your_project_path/dummydata.json
Не уверен насчет производительности по сравнению с вашим текущим методом, но 6 минут звучит ужасно долго для сброса 6k объектов в базу данных.
Один из способов создания файла .json
заключается в том, чтобы взять дамп из вашей базы данных after
вы заполнили базу данных, используя ваш текущий метод. Для этого вы можете использовать команду dumpdata:
python3 manage.py dumpdata > dummydata.json
Результирующий формат .json
автоматически должен быть в правильном формате, как ожидается командой loaddata