我刚刚从SQLite3迁移到了Postgres 12(使用pgloader)。
我无法删除某些模型对象,因为还有其他引用它的模型对象。
但是,我非常确定我的模型对象在引用模型对象中设置了“ on_delete = models.CASCADE”(在我的Django代码的models.py中)。
所以我得到了Postgres生成的错误:
...
django.db.utils.IntegrityError: update or delete on table "app_reply" violates foreign key constraint "app_replyimage_reply_id_fkey" on table "app_replyimage"
DetaIL: Key (id)=(SRB6Nf98) is still referenced from table "app_replyimage".
有没有一种方法(希望不用手动在Postgres中编辑表模式)来解决这个问题?
编辑:在下面添加一些代码...
models.py
class ReplyImage(models.Model):
id = models.CharField(default = make_id(),unique = True,primary_key = True,max_length = 8)
file = models.ImageField(upload_to = customer_images_directory_path)
reply = models.ForeignKey(Reply,on_delete = models.CASCADE,related_name = 'reply_images')
#Meta
created = models.DateTimeField(auto_now_add = True)
updated = models.DateTimeField(auto_now = True)
created_by = models.ForeignKey(User,related_name = '+',null = True)
updated_by = models.ForeignKey(User,null = True)
def __str__(self):
return str(self.id)
def delete(self,*args,**kwargs):
self.file.delete()
super(ReplyImage,self).delete(*args,**kwargs)
@receiver(post_delete,sender = ReplyImage)
def reply_image_delete(sender,instance,**kwargs):
instance.file.delete()
这是引用的模型,回复:
class Reply(models.Model):
id = models.CharField(default = make_id(),max_length = 8)
#Content
content = models.CharField(max_length = 560,blank = True,null = True)
replies = GenericRelation('self')
link = models.ForeignKey(Link,on_delete = models.SET_NULL,related_name = 'reply',null = True)
#Drip
drip_interval_quantity = models.IntegerField(default = 0,null = True) #Custom quantity
drip_interval_calendar_unit = models.CharField(default = 'minute',max_length = 6,choices = DRIP_INTERVAL_CALENDAR_UNIT_CHOICES,null = True) #Custom calendar unit
post_datetime = models.DateTimeField(blank = True,null = True) #Post datetime
#Twitter API
self_status_id_str = models.CharField(max_length = 19,null = True,blank = True) #status_id_str of self
in_reply_to_status_id_str = models.CharField(max_length = 19,blank = True) #status_id_str of tweet replied to
#Meta
created = models.DateTimeField(auto_now_add = True)
updated = models.DateTimeField(auto_now = True)
created_by = models.ForeignKey(User,null = True)
#Mandatory fields for generic relation
content_type = models.ForeignKey(ContentType,on_delete = models.CASCADE)
object_id = models.CharField(default = make_id(),max_length = 8)
content_object = GenericForeignKey()
customer = models.ForeignKey(Customer,related_name = 'postreplies')
def delete(self,**kwargs):
if self.reply_images.all():
for i in self.reply_images.all():
i.delete()
if self.link:
self.link.delete()
super(Reply,**kwargs)
def __str__(self):
return self.content
@receiver(post_save,sender = Reply)
def reply_model_save(sender,**kwargs):
if kwargs['raw']:
return
recursive_reply_save_mock_post(instance)
@receiver(post_delete,sender = Reply)
def reply_model_delete(sender,**kwargs):
if instance.reply_images.all():
for i in instance.reply_images.all():
i.delete()
views.py
...
post.replies.all().delete()
...
(我重新定义了delete()方法,还添加了post_delete()信号,但我认为它们不应该影响任何东西,因为它与SQLite完美配合。)
出了什么问题?
编辑2:
Postgres表架构
Table "public.app_replyimage"
Column | Type | Collation | Nullable | Default
---------------+--------------------------+-----------+----------+---------
file | text | | |
created | timestamp with time zone | | |
updated | timestamp with time zone | | |
created_by_id | bigint | | |
reply_id | text | | |
updated_by_id | bigint | | |
id | text | | not null |
Indexes:
"idx_85696_sqlite_autoindex_app_replyimage_1" PRIMARY KEY,btree (id)
"idx_85696_app_replyimage_created_by_id_a5974d1f" btree (created_by_id)
"idx_85696_app_replyimage_reply_id_7a8aff2c" btree (reply_id)
"idx_85696_app_replyimage_updated_by_id_d73f7446" btree (updated_by_id)
Foreign-key constraints:
"app_replyimage_created_by_id_fkey" FOREIGN KEY (created_by_id) REFERENCES auth_user(id)
"app_replyimage_reply_id_fkey" FOREIGN KEY (reply_id) REFERENCES app_reply(id)
"app_replyimage_updated_by_id_fkey" FOREIGN KEY (updated_by_id) REFERENCES auth_user(id)