gpt4 book ai didi

django - Django从模型CharField引入外键

转载 作者:行者123 更新时间:2023-12-03 18:34:23 25 4
gpt4 key购买 nike

我已经将超过10,000条记录从旧的mySQL数据库迁移到Django / sqlite。在我的旧mysql模式的Song表中,artist字段不是1对多的字段,而仅仅是mysql varchar字段。在新的Django模型中,我将artist字段转换为ForeignKey,并使用temp_artist临时存储了旧数据库中的artist姓名。

如何基于temp_artist字段创建每个Song实例的艺术家外键?我假设我应该使用管理器的get_or_create方法,但是在哪里以及如何编写代码?

我的模型如下:

class Artist (models.Model):
name = models.CharField(max_length=100)

class Song (models.Model):
artist = models.ForeignKey(Artist, blank=True, null=True, on_delete=models.CASCADE, verbose_name="Artist")
temp_artist = models.CharField(null=True, blank=True, max_length=100)
title = models.CharField(max_length=100, verbose_name="Title")
duration = models.DurationField(null=True, blank=True, verbose_name="Duration")

最佳答案

由于您目前没有可用的外键,因此您必须深入到raw_sql。如果您仍在使用mysql,则可以使用UPDATE JOIN语法。但是很遗憾,Sqlite不支持UPDATE JOIN。

幸运的是,您只有数千行,因此可以遍历它们并分别更新每一行。

raw_query = '''SELECT s.*, a.id as fkid 
FROM myapp_song s
INNER JOIN myapp_artist a on s.temp_artist = a.name'''
for song in Song.objects.raw(raw_query)
song.artist_id = s.fkid
song.save()


这可能需要几分钟才能完成,因为您没有temp_artist和name的索引。请注意将myapp替换为您的应用程序的实际名称。

编辑1:

尽管Sqlite没有更新JOIN,但它确实允许您使用子查询来设置值。因此这也将起作用。

UPDATE myapp_song set artist_id = 
(SELECT id from myapp_artist WHERE name = myapp_song.temp_artist)


在sqlite控制台或GUI中键入它。确保用您自己的应用名称替换myapp。这将非常快,因为它是一个查询。所有其他解决方案,包括此答案中的替代解决方案,都涉及10,000个查询。

编辑2

如果您的Artist表目前为空,则在执行所有操作之前,必须先填充它,这是一个简单的查询

INSERT INTO stackoverflow_artist(name)
SELECT distinct temp_artist from stackoverflow_song


请注意,您应该在Artist.name上具有唯一索引

关于django - Django从模型CharField引入外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37358120/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com