我收到错误
django.db.utils.ProgrammingError: (1146, "Table 'db_name.django_content_type' doesn't exist")
尝试使用我第一次在生产服务器上部署的新数据库为django项目进行初始迁移时。
我怀疑问题可能是因为其中一个应用程序的目录中充满了来自SQLite3开发环境的旧迁移;我清除了那些,但没有帮助。我还搜索并找到了对多个数据库存在问题的人的引用,但我只有一个。
Django版本在python 3.5.4上是1.11.6,mysqlclient 1.3.12
答案 0 :(得分:3)
一些注意事项:
我最终创建了一个方法来检查表格是否已创建,不确定它是否也会对您有所帮助:
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
至于迁移,我的理解是它们应该始终属于您的版本控制仓库,但是您可以根据需要进行挤压或编辑,甚至可以重建它们,这个链接可以帮助我解决一些迁移问题: Reset Migrations
答案 1 :(得分:1)
回答我自己的问题:
UMDA的评论是正确的。我有一些查看content_types的django-import-export
模块的初始化代码,显然我从来没有在新环境中从头开始部署应用程序。
经验教训/解决方案:
会将违规代码包装在异常块中,因为我应该这样做 在新环境中部署时只有一次此异常
更频繁地在新环境中测试干净部署。
migrations
目录是否属于.gitignore
。为了我的目的,他们这样做。(相对较新的stackoverflow礼仪 - 我如何赞扬UMDA的评论让我走上正轨?)
答案 2 :(得分:0)
在尝试创建通用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"),
]
无论如何。让我们不要过去。
通过适当地切换到基于类的视图(而不是上面概述的任何地狱杂种),可以解决此问题,因为(根据this SO post),直到请求时才实例化基于类的视图。 / p>
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"),
]
愿您犯下新的更好的错误。
答案 3 :(得分:0)
加入,因为此选项在某些情况下可能会更好地吸引人。
大多数项目的导入通常从您的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的答案,以获得更明智,更全面的解决方案。