![](/img/trans.png)
[英]Django keeps recreating foreign key field for legacy database with migrations command
[英]Django migrations foreign key mismatch with legacy database
嘿嘿,
我正在嘗試將 SQLite 舊數據庫與 Django v3.1.2 集成,到目前為止它非常痛苦(django 的新手,如果它很明顯,請道歉)。 我認為我的數據庫架構或遷移過程有問題。 所以這是我所做的和我的問題:
我已經在我的舊數據庫上運行了inspectdb
並清理了模型,留下了以下兩個模型(我的應用程序中有更多模型,但這些顯然是導致問題的模型):
class Integrons(models.Model):
arg = models.ForeignKey('Args', on_delete=models.CASCADE)
int_id = models.IntegerField(primary_key=True)
int_start = models.IntegerField()
int_stop = models.IntegerField()
int_complete = models.CharField(max_length=500)
class Meta:
managed = False
db_table = 'integrons'
class IntElements(models.Model):
int = models.ForeignKey('Integrons', on_delete=models.CASCADE)
el_id = models.IntegerField()
el_start = models.IntegerField()
el_stop = models.IntegerField()
el_name = models.CharField(blank=True, null=True, max_length=500)
el_strand = models.CharField(blank=True, null=True, max_length=500)
class Meta:
managed = False
db_table = 'int_elements'
我的舊數據庫中的相應字段是:
積分:arg_id、int_id、int_start、int_stop、int_complete IntElements:int_id、el_id、el_start、el-stop、el_name、el_strand
從模型中可以看出,IntElements.int_id 應指代 Integrons.int_id。
現在我正在嘗試遷移所有內容 - 運行python manage.py makemigrations
工作正常。 但是,在運行python manage.py migrate
,出現以下錯誤:
django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table (foreign key mismatch - "int_elements" referencing "integrons")
我不明白問題是什么。 我第一次跑這一點,我認為這個問題是我的模型秩序,因為我已經定義IntElements
之前Integrons
在models.py。 我更改了它,刪除了遷移文件夾中的.pyc
文件並重復了遷移過程,得到了同樣的錯誤。 當我刪除遷移文件並注釋掉 models.py 中的IntElements
模型並運行makemigrations
,我看到除IntElements
之外的所有模型都已創建。 但是當我然后運行python manage.py migrate
,我得到了同樣的錯誤,這讓我相信遷移過程出了問題。 或者它可能是我列名中的 _id 嗎?
真的會對此有任何幫助!
編輯_____
python manage.py showmigrations
產出
python manage.py showmigrations
System check identified some issues:
WARNINGS:
db_app.Lineages.taxon: (fields.W342) Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.
HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
admin
[ ] 0001_initial
[ ] 0002_logentry_remove_auto_add
[ ] 0003_logentry_add_action_flag_choices
auth
[ ] 0001_initial
[ ] 0002_alter_permission_name_max_length
[ ] 0003_alter_user_email_max_length
[ ] 0004_alter_user_username_opts
[ ] 0005_alter_user_last_login_null
[ ] 0006_require_contenttypes_0002
[ ] 0007_alter_validators_add_error_messages
[ ] 0008_alter_user_username_max_length
[ ] 0009_alter_user_last_name_max_length
[ ] 0010_alter_group_name_max_length
[ ] 0011_update_proxy_permissions
[ ] 0012_alter_user_first_name_max_length
contenttypes
[ ] 0001_initial
[ ] 0002_remove_content_type_name
db_app
[ ] 0001_initial
sessions
[ ] 0001_initial
這里有些不對勁,因為非托管模型 不會創建遷移:
默認情況下,inspectdb 創建非托管模型。 即模型的 Meta 類中的 managed = False 告訴 Django 不要管理每個表的創建、修改和刪除
[代碼示例剪切]
如果您確實想讓 Django 管理表的生命周期,則需要將上面的 managed 選項更改為 True(或將其刪除,因為 True 是其默認值)。
這是有意為之,因為遺留數據庫最突出的情況是只讀數據庫,它提供正在逐步淘汰的信息。 使用 Django 來管理它們會破壞遺留應用程序,如果為模式操作設置了適當的權限,甚至可能無法實現。
您還提到正在創建的表再次與非托管表沖突。
如果您的目標是導入架構,然后刪除 SQLite 數據庫並由 Django 正確填充和管理它,那么您必須通過從模型元類中刪除managed = False
來managed = False
模型。 這是您繼承數據庫並希望從該數據庫開始並使用遷移框架繼續前進的另一個常見用例。 Inspectdb 是一個一次性命令,可以讓您的樣板文件就位。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.