我上周将新版本推送到服务器,其中包括新表的数据库迁移。这已按预期完成,并且可以正常运行,但现在在服务器运行它的每次部署时,我都看不到要应用的迁移,但是内容类型也存在唯一的密钥错误;
Running migrations:
No migrations to apply.
...
File "/var/www/django/myproj/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
django.db.utils.IntegrityError
(1062, "Duplicate entry 'djangocms_newsletter-signup' for key 'django_content_type_app_label_45f3b1d93ec8c61c_uniq'")
该表位于数据库中,Signup
模型的内容类型位于内容类型表中,迁移位于迁移表中......所以为什么Django仍尝试创建新的内容类型?
迁移是作为我用于所有项目的简单部署后脚本的一部分运行的;
#!/bin/bash
set -e
PROJ_PATH=/var/www/django/myproj
cd $PROJ_PATH
echo 'clear-out...'
find $PROJ_PATH -name "*.pyc" -exec rm -rf '{}' ';'
find $PROJ_PATH -name "*.pyo" -exec rm -rf '{}' ';'
echo 'set DJANGO_SETTINGS_MODULE'
export DJANGO_SETTINGS_MODULE="project.settings.local_override"
echo 'activating...'
source ../bin/activate
echo 'pip install...'
pip install -r requirements.txt --no-deps
echo 'migrate...'
python manage.py migrate --noinput
echo 'collectstatic...'
python manage.py collectstatic --noinput
echo 'restart apache...'
sudo service apache2 restart
deactivate
目前,我一直在从现有内容类型中清除应用名称,以便部署成功,但现在我只是想了解问题是什么,以便我以后可以解决它
完全追溯;
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 165, in handle
emit_post_migrate_signal(created_models, self.verbosity, self.interactive, connection.alias)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/sql.py", line 268, in emit_post_migrate_signal
using=db)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 198, in send
response = receiver(signal=self, sender=sender, **named)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/contrib/contenttypes/management.py", line 56, in update_contenttypes
ContentType.objects.using(using).bulk_create(cts)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/query.py", line 409, in bulk_create
self._batched_insert(objs_without_pk, fields, batch_size)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/query.py", line 938, in _batched_insert
using=self.db)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/query.py", line 921, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 921, in execute_sql
cursor.execute(sql, params)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 129, in execute
return self.cursor.execute(query, args)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File "/var/www/django/myproj/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
django.db.utils.
IntegrityError: (1062, "Duplicate entry 'djangocms_newsletter-signup' for key 'django_content_type_app_label_45f3b1d93ec8c61c_uniq'")
execute bash /var/www/django/myproj/myproj/shell_scripts/production_post_deployment.sh
答案 0 :(得分:0)
再次遇到这个问题后,我已经使用服务器上的shell对其进行了调试,因为它无法重现&amp;发现问题是由缓存的ContentType对象引起的。
让我说明一下;
>>> content_types = dict((ct.model, ct) for ct in ContentType.objects.filter(app_label='consoles'))
>>> content_types
{}
>>> content_types = dict((ct.model, ct) for ct in ContentType.objects.filter(app_label='news'))
>>> content_types
{u'latestnews': <ContentType: latest news>}
>>> from django.core.cache import cache
>>> cache.clear()
>>> content_types = dict((ct.model, ct) for ct in ContentType.objects.filter(app_label='consoles'))
>>> content_types
{u'runner': <ContentType: runner>, u'importedclient': <ContentType: imported client>, u'placetype': <ContentType: place type>, u'invoice': <ContentType: invoice>, u'placetypetotal': <ContentType: place type total>, u'clientconsoles': <ContentType: client consoles>, u'emailtemplate': <ContentType: email template>, u'event': <ContentType: event>, u'occupation': <ContentType: occupation>, u'console': <ContentType: console>, u'meettheexperts': <ContentType: meet the experts>, u'auditlog': <ContentType: audit log entry>, u'proxyuser': <ContentType: user>, u'consoleuser': <ContentType: Console User>, u'paidby': <ContentType: paid by>, u'meettheexpertstransaction': <ContentType: Meet the experts Transaction>, u'clientuserconsole': <ContentType: client user console>, u'paymentmethod': <ContentType: payment method>, u'transaction': <ContentType: transaction>, u'country': <ContentType: Country>, u'client': <ContentType: client>, u'place': <ContentType: place>, u'consoletotal': <ContentType: console total>}
因此,对缓存所有内容类型的缓存管理器的修复解决了这个问题。