Django Syncdb исключение после обновления до 1.4
Поэтому я разрабатывал приложение в Django, и мне была нужна функция из версии 1.4, поэтому я решил обновить.
Но затем появилась странная ошибка, когда я хотел сделать syncdb
Я использую новый manage.py
и, как вы можете видеть, он создает некоторые таблицы, но затем терпит неудачу:
./manage.py syncdb
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site
Traceback (most recent call last):
File "./manage.py", line 9, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/__init__.py", line 443, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/__init__.py", line 382, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/base.py", line 196, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/base.py", line 232, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/base.py", line 371, in handle
return self.handle_noargs(**options)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/commands/syncdb.py", line 91, in handle_noargs
sql, references = connection.creation.sql_create_model(model, self.style, seen_models)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/backends/creation.py", line 44, in sql_create_model
col_type = f.db_type(connection=self.connection)
TypeError: db_type() got an unexpected keyword argument 'connection'
2 ответа
У меня была та же проблема, в определении моего настраиваемого поля отсутствовал параметр соединения.
from django.db import models
class BigIntegerField(models.IntegerField):
def db_type(self, connection):
return "bigint"
Хотя этот вопрос уже устарел, я ответил на него и принял его, но я добавляю свое понимание, но добавил его, потому что я не использую настроенный тип, и это ошибка Django Evolution (но не syncdb) evolve --hint --execute
, Я думаю, что это может быть полезно для кого-то в будущем. ,
Я средний в Python и новичок в Django. Я также столкнулся с той же проблемой, когда добавил некоторые новые функции в свой существующий проект. Чтобы добавить новую функцию, мне пришлось добавить несколько новых полей models.CharField()
типа, следующим образом.
included_domains = models.CharField(
"set of comma(,) seprated list of domains in target emails",
default="",
max_length=it_len.EMAIL_LEN*5)
excluded_domains = models.CharField(
"set of comma(,) seprated list of domains NOT in target emails",
default="",
max_length=it_len.EMAIL_LEN*5)
Я использую версию Django 1.3.1:
$ python -c "import django; print django.get_version()"
1.3.1 <--------# version
$python manage.py syncdb
Project signature has changed - an evolution is required
Django Evolution: Django Evolution - это расширение для Django, которое позволяет вам отслеживать изменения в ваших моделях с течением времени и обновлять базу данных, чтобы отражать эти изменения.
$ python manage.py evolve --hint
#----- Evolution for messagingframework
from django_evolution.mutations import AddField
from django.db import models
MUTATIONS = [
AddField('MessageConfiguration', 'excluded_domains', models.CharField, initial=u'', max_length=300),
AddField('MessageConfiguration', 'included_domains', models.CharField, initial=u'', max_length=300)
]
#----------------------
Trial evolution successful.
Run './manage.py evolve --hint --execute' to apply evolution.
Испытание было подозрительным, и когда я пытался применить изменения в БД
$ python manage.py evolve --hint --execute
Traceback (most recent call last):
File "manage.py", line 25, in <module>
execute_manager(settings)
File "/var/www/sites/www.taxspanner.com/django/core/management/__init__.py", line 362, in execute_manager
utility.execute()
File "/var/www/sites/www.taxspanner.com/django/core/management/__init__.py", line 303, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/var/www/sites/www.taxspanner.com/django/core/management/base.py", line 195, in run_from_argv
self.execute(*args, **options.__dict__)
File "/var/www/sites/www.taxspanner.com/django/core/management/base.py", line 222, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/management/commands/evolve.py", line 60, in handle
self.evolve(*app_labels, **options)
File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/management/commands/evolve.py", line 140, in evolve
database))
File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/mutations.py", line 426, in mutate
return self.add_column(app_label, proj_sig, database)
File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/mutations.py", line 438, in add_column
sql_statements = evolver.add_column(model, field, self.initial)
File "/usr/local/lib/python2.7/dist-packages/django_evolution-0.6.9.dev_r225-py2.7.egg/django_evolution/db/common.py", line 142, in add_column
f.db_type(connection=self.connection), # <=== here f is field class object
TypeError: db_type() got an unexpected keyword argument 'connection'
Чтобы понять это исключение, я проверяю, что это исключение похоже на:
>>> def f(a):
... print a
...
>>> f('b', b='a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() got an unexpected keyword argument 'b'
>>>
Таким образом, подпись функции была изменена.
Поскольку я не добавил никаких новых настраиваемых или перечислимых полей, а только два похожих поля, которые уже были в модели и поле типа символа, поддерживаются большинством баз данных (я использую PostgreSQL), даже когда я получал эту ошибку!
Тогда я прочитал от @: Рассел Кит-Маги-4 Ответить.
Здесь вы попали в конец цикла устаревания кода, который не поддерживает несколько баз данных.
В Django 1.2 мы представили поддержку нескольких баз данных; чтобы поддержать это, прототип для
get_db_preb_lookup()
а такжеget_db_prep_value()
был изменен.Для обратной совместимости мы добавили прокладку, которая прозрачно "исправит" эти методы, если они еще не были исправлены разработчиком.
В Django 1.2 использование этих прокладок вызвало предупреждение PendingDeprecationWarning. В Django 1.3 они подняли предупреждение об устаревании.
В Django 1.4 код shim был удален, поэтому любой код, который не был обновлен, теперь будет вызывать ошибки, подобные той, которую вы описали.
Но я не получаю предупреждения о предупреждении об устаревании из-за более новой версии Django Evolution.
Но из приведенной выше цитаты я мог понять, что для поддержки нескольких баз данных добавлена функция подписи и дополнительный аргумент connection
нужно. Я также проверяю db_type()
Подпись в моей установке Django выглядит следующим образом:
/django$ grep --exclude-dir=".svn" -n 'def db_type(' * -R
contrib/localflavor/us/models.py:8: def db_type(self):
contrib/localflavor/us/models.py:24: def db_type(self):
:
:
Также ссылаюсь на документацию Django
Field.db_type (self, connection):
Возвращает тип данных столбца базы данных для поля с учетом объекта подключения и параметров, связанных с ним.
И тогда я мог понять, что для решения этой проблемы я должен унаследовать models.filed
класс и перезаписать def db_type()
функция. И потому что я использую PostgreSQL, в котором для создания поля типа 300 символов мне нужно вернуть 'char(300)'
, В моем models.py я добавил:
class CharMaxlengthN(models.Field):
def db_type(self, connection):
return 'char(%d)' % self.max_length # because I am using postgresql
Если вы столкнулись с подобной проблемой, пожалуйста, проверьте в руководстве по вашей подчеркнутой БД, какой тип столбца вам нужно создать, и верните строку.
И изменил определение новых полей (которые мне нужно добавить) прочитав комментарии:
included_domains = CharMaxlengthN( # <--Notice change
"set of comma(,) seprated list of domains in target emails",
default="",
max_length=it_len.EMAIL_LEN*5)
excluded_domains = CharMaxlengthN( # <-- Notice change
"set of comma(,) seprated list of domains NOT in target emails",
default="",
max_length=it_len.EMAIL_LEN*5)
Затем я выполнил ту же команду, которая ранее не работала:
t$ python manage.py evolve --hint --execute
You have requested a database evolution. This will alter tables
and data currently in the None database, and may result in
IRREVERSABLE DATA LOSS. Evolutions should be *thoroughly* reviewed
prior to execution.
Are you sure you want to execute the evolutions?
Type 'yes' to continue, or 'no' to cancel: yes
Evolution successful.
Я также проверяю свою БД и проверяю свои новые добавленные функции. Теперь она работает отлично, и проблем с БД нет.
Если вы хотите создать поле ENUM, прочитайте Specifying a mySQL ENUM in a Django model
,
Редактировать: я понял, вместо подкласса models.Field
Я должен был унаследовать более конкретный подкласс, который models.CharField
,
Точно так же мне нужно создать поля десятичной БД, поэтому я добавил в модель следующий класс:
class DecimalField(models.DecimalField):
def db_type(self, connection):
d = {
'max_digits': self.max_digits,
'decimal_places': self.decimal_places,
}
return 'numeric(%(max_digits)s, %(decimal_places)s)' % d