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
Другие вопросы по тегам