我正在使用我的第一個 Django 應用程式,請耐心等待...
它基于一些帶有現有 PostgreSQL 資料庫的舊腳本。因此,某些表的命名不遵循 Django 命名模式。
目前我正在重塑我的資料以遵循合理的資料建模原則。執行其中一個步驟的遷移給了我一個我不明白的外鍵例外:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 242, in _commit
return self.connection.commit()
psycopg2.errors.ForeignKeyViolation: insert or update on table "design_shopify_category" violates foreign key constraint "design_shopify_categ_shopifycollection_id_9f310876_fk_designs_s"
DETAIL: Key (shopifycollection_id)=([<ShopifyCollection: ShopifyCollection object (gid://shopify/Collection/263596736569)>]) is not present in table "designs_shopifycollection".
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/local/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/root/.vscode-server/extensions/ms-python.python-2021.11.1422169775/pythonFiles/lib/python/debugpy/__main__.py", line 45, in <module>
cli.main()
File "/root/.vscode-server/extensions/ms-python.python-2021.11.1422169775/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 444, in main
run()
File "/root/.vscode-server/extensions/ms-python.python-2021.11.1422169775/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 285, in run_file
runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
File "/usr/local/lib/python3.9/runpy.py", line 268, in run_path
return _run_module_code(code, init_globals, run_name,
File "/usr/local/lib/python3.9/runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "/usr/local/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/workspace/src/otaya_tool/manage.py", line 23, in <module>
main()
File "/workspace/src/otaya_tool/manage.py", line 19, in main
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 89, in wrapped
res = handle_func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/migrate.py", line 244, in handle
post_migrate_state = executor.migrate(
File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 230, in apply_migration
migration_recorded = True
File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/schema.py", line 120, in __exit__
self.atomic.__exit__(exc_type, exc_value, traceback)
File "/usr/local/lib/python3.9/site-packages/django/db/transaction.py", line 246, in __exit__
connection.commit()
File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 33, in inner
return func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 266, in commit
self._commit()
File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 242, in _commit
return self.connection.commit()
File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 242, in _commit
return self.connection.commit()
django.db.utils.IntegrityError: insert or update on table "design_shopify_category" violates foreign key constraint "design_shopify_categ_shopifycollection_id_9f310876_fk_designs_s"
DETAIL: Key (shopifycollection_id)=([<ShopifyCollection: ShopifyCollection object (gid://shopify/Collection/263596736569)>]) is not present in table "designs_shopifycollection".
有兩個模型,與錯誤相關:
class ShopifyCollection(models.Model):
graph_ql_id = models.CharField(max_length=250, primary_key=True,
validators=[validate_sy_graph_ql_id])
handle = models.CharField(max_length=250, blank=False, null=False,
validators=[validate_slug])
title = models.CharField(max_length=250, blank=False, null=False)
def pk_uuid_gen() -> str:
return str(uuid4())
class Design(models.Model):
uuid = models.CharField(primary_key=True, unique=True, default=pk_uuid_gen,
editable=False, max_length=36)
niche = models.CharField(blank=False, null=True, max_length=50)
id = models.CharField(blank=False, null=True, max_length=4)
variant = models.CharField(blank=False, null=True, max_length=1)
language = models.CharField(max_length=2, default=None)
# the new many 2 many relation to be filled by the migration.
shopify_category = models.ManyToManyField(ShopifyCollection, blank=True)
# the legacy field to get the values from...
shopify_category_tmp = models.JSONField(blank=True, default=empty_development_default)
class Meta:
db_table = 'design'
unique_together = ((niche', 'id', 'variant'),)
這是遷移代碼:
# Generated by Django 3.2.9 on 2021-11-27 18:00
from django.db import migrations
from django.core.exceptions import ObjectDoesNotExist
from designs.models import Design, ShopifyCollection
def convert_shopify_category_json_objects_to_m2m(apps, schema_editor):
# this doesn't give an error. It's the exact same key the FK exception
# complains about. It's also the first object it want's to add.
x = ShopifyCollection.objects.get(pk='gid://shopify/Collection/263596736569')
for design in Design.objects.all().iterator():
if len(design.shopify_category_tmp) == 0:
continue
# the legacy field holds a list of strings like: ["archery", "outdoor"]
for category in design.shopify_category_tmp:
if len(category) == 0:
continue
sy_col_handles = [
f'niche-de-{category}',
f'featured-de-{category}']
sy_collections = []
for handle in sy_col_handles:
try:
sy_collections.append(ShopifyCollection.objects.get(handle=handle))
except ObjectDoesNotExist:
pass
if len(sy_collections) < 1:
raise ValueError('There are no Shopify Collections for the handles '
f'{sy_col_handles}. We need at least one of them.')
design.shopify_category.add(sy_collections)
design.save()
class Migration(migrations.Migration):
dependencies = [
('designs', '0031_shopify_categories_link_them'),
]
operations = [
migrations.RunPython(convert_shopify_category_json_objects_to_m2m),
]
該表在遷移的資料庫事務開始之前designs_shopifycollection保存了gid://shopify/Collection/263596736569例外抱怨丟失的行。
該行還x = ShopifyCollection.objects.get(pk='gid://shopify/Collection/263596736569')證明該表包含遷移的 db 事務中請求的行。
該表還包含遷移后的“缺失”行。
我試圖通過 Django 框架代碼除錯問題,但一段時間后停止了。找不到比提交觸發的例外更多的東西...
此外,手動將行添加到 m2n 表中,沒有任何問題,并在 DesignFrom 視圖中顯示為所選。
我的想法用完了。問題出在哪里?
uj5u.com熱心網友回復:
您需要將專案作為單獨的引數傳遞,因此:
# asterisk ↓
design.shopify_category.add(*sy_collections)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/368330.html
標籤:姜戈 PostgreSQL的 django 模型 django-迁移
上一篇:Chisel:在撰寫簡單的組合邏輯時無法生成verilog
下一篇:使用Reportlab加密pdf
