[英]Django MySQL Error (1146, "Table 'db_name.django_content_type' doesn't exist")
我收到错误
django.db.utils.ProgrammingError: (1146, "Table 'db_name.django_content_type' doesn't exist")
在尝试使用我第一次在生产服务器上部署的新数据库对 django 项目进行初始迁移时。
我怀疑这个问题可能是因为其中一个应用程序的目录充满了来自 SQLite3 开发环境的旧迁移; 我清除了这些,但没有帮助。 我还搜索并找到了对多个数据库有问题的人的引用,但我只有一个。
python 3.5.4、mysqlclient 1.3.12上的Django版本是1.11.6
一些考虑:
我最终创建了一个方法来检查表是否已创建,不确定它是否也会帮助您:
def get_content_type(cls):
from django.contrib.contenttypes.models import ContentType
from django.db import connection
if 'django_content_type' in connection.introspection.table_names():
return ContentType.objects.get_for_model(cls)
else:
return None
至于迁移,我的理解是它们应该始终属于您的版本控制仓库,但是您可以根据需要进行挤压或编辑,甚至重建它们,这个链接可以帮助我解决一些迁移问题: 重置迁移
回答我自己的问题:
UMDA的评论是正确的。 我有一些用于查看content_types的django-import-export
模块的初始化代码,显然我从未在新环境中从头开始部署应用程序,因为我编写了它。
经验教训/解决方案:
将包含有问题的代码包装在异常块中,因为在新环境中部署时我只应该有一次此异常
在更新的环境中更频繁地测试清洁部署。
migrations
目录是否属于.gitignore
。 为了我的目的,他们做到了 (相对较新的stackoverflow礼仪 - 我如何赞扬UMDA的评论让我走上正轨?)
在尝试创建通用ModelView时,我遇到了同样的问题(模型名称将作为urls.py
的变量传递)。 我是以一种愚蠢的方式处理这个问题:
views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.views.generic.edit import DeleteView
def get_generic_delete_view(model_name):
model_type = ContentType.objects.get(app_label='myapp', model=model_name)
class _GenericDelete(LoginRequiredMixin, DeleteView):
model = model_type.model_class()
template_name = "confirm_delete.html"
return _GenericDelete.as_view()
urls.py
from django.urls import path, include
from my_app import views
urlpatterns = [
path("mymodels/<name>/delete/", views.get_generic_delete_view("MyModel"),
]
无论如何。 我们不要忘记过去。
这可以通过适当地切换到基于类的视图来修复,而不是上面概述的任何地狱混合,因为(根据这个SO帖子 )基于类的视图直到请求时才被实例化。
views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.views.generic.edit import DeleteView
class GenericDelete(LoginRequiredMixin, DeleteView):
template_name = "confirm_delete.html"
def __init__(self, **kwargs):
model = kwargs.pop("model")
model_type = ContentType.objects.get(app_label='myapp', model=model)
self.model = model_type.model_class()
super().__init__()
urls.py
from django.urls import path, include
from my_app import views
urlpatterns = [
path("mymodels/<name>/delete/", views.GenericDelete.as_view(model="MyModel"),
]
愿你犯下新的更好的错误。
插手是因为在某些情况下,这个选项可能会更有吸引力。
大多数项目的导入通常从您的urls.py
级联下来。 我通常做的是将urls.py
导入包装在 try/except 语句中,并且仅在所有导入成功时才创建路由。
这样做的目的是仅在导入模块时创建项目/应用程序的路由。 如果由于表尚不存在而出现错误,则将忽略该错误,并完成迁移。 在下一次运行中,希望您的导入没有错误,并且一切都会顺利进行。 但是如果你这样做了,它很容易被发现,因为你没有任何 URL。 此外,我通常会添加一个错误日志来指导我解决这些情况下的问题。
简化版本如下所示:
# Workaround to avoid programming errors on greenfield migrations
register_routes = True
try:
from myapp.views import CoolViewSet
# More imports...
except Exception as e:
register_routes = False
logger.error("Avoiding creation of routes. Error on import: {}".format(e))
if register_routes:
# Add yout url paterns here
现在,也许您可以将 Omar 的答案结合起来,以获得更明智、更全面的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.