Django 启动代码(如初始缓存)冲突 makemigrations。操作错误没有这样的列表
Posted
技术标签:
【中文标题】Django 启动代码(如初始缓存)冲突 makemigrations。操作错误没有这样的列表【英文标题】:Django start-up code (like initial caching) conflicts makemigrations. Operational Errors no such columns tables 【发布时间】:2020-05-04 22:30:49 【问题描述】:首先,我不喜欢“以 django 的方式做事”。在开发应用程序时,我更喜欢利用我的基本编程知识,而不是花费数小时学习 django 方式。 背景:
我正在开发的应用程序是一个 REST 后端,用于存储语言信息等本地化值。 我想获取存储在数据库中的语言信息,并在启动时将其加载到内存中,然后在请求到来时从内存中提供该数据。 我创建了我的模型
class Text(models.Model):
language = models.CharField()
key = models.CharField()
text = models.CharField()
然后按常规步骤运行 python manage.py makemigrations 和迁移命令
然后我跳过去,实现了我的缓存代码,直接放在admin.py下(可以是urls.py没关系,只需要运行一次)
cached_languages = models.Text.objects.all()
我继续运行我的应用程序,它运行良好。
然后我想在我的文本模型中添加一个字段,例如
class Text(models.Model):
language = models.CharField()
key = models.CharField()
text = models.CharField()
**dummy = models.CharField()**
然后点击 python manage.py makemigrations 命令和 boom 在 行
cached_languages = models.Text.objects.all()
我们收到一条错误消息 sqlite3.OperationalError:没有这样的列:app_text.dummy
我应该怎么做才能解决这个问题?
【问题讨论】:
【参考方案1】:问题在于,即使您调用 python manage.py makemigrations,django 也会执行编写的每一行代码。这意味着在 django 实际反映对数据库的更改之前,它会执行整个项目,当涉及到缓存行时,它会尝试从 Text 表中获取所有行,该表还没有列 dummy 但从 django 的角度来看(在代码中)表文本有一个虚拟列,这就是它抛出错误的原因。
解决方案一种解决方法是在说 settings.py 中放置一个标志
IS_RUNNING = False
并在 manage.py 中添加以下内容
from app import settings
if 'runserver' in sys.argv:
settings.IS_RUNNING = True
在标志检查之后放置你的缓存代码
if settings.IS_RUNNING:
cached_languages = models.Text.objects.all()
那么 django 在应用它们之前进行迁移时不会尝试获取记录。缓存算法只会在你实际调用 runserver 时执行。
【讨论】:
希望这可以帮助那些在基本缓存方面苦苦挣扎的人 在启动时执行查询是个坏主意,这个解决方案仍然存在一些问题。创建新的Text
对象时,您的缓存已过期。当您向模型添加字段并运行 makemigrations
时会发生什么?
1) 为什么在启动时执行查询是个坏主意? 2)你可以通过启动一个守护线程来更新你的缓存,它可以每隔 300 秒更新一次你的缓存,你可以从 settings.py 或其他配置文件中读取这个值。我从来没有提到过缓存的更新。那不是重点。 3)我真的不明白你的第三句话。您首先停止服务器并运行迁移,然后启动并刷新缓存。以上是关于Django 启动代码(如初始缓存)冲突 makemigrations。操作错误没有这样的列表的主要内容,如果未能解决你的问题,请参考以下文章