更新到1.4后的Django syncdb异常

时间:2012-04-18 18:53:48

标签: django updating django-syncdb

所以我在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 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,我的自定义字段的定义缺少连接参数。

from django.db import models

class BigIntegerField(models.IntegerField):
    def db_type(self, connection):
        return "bigint"

答案 1 :(得分:0)

虽然已经陈旧,回答并接受了问题,但我添加了我的理解,我添加了它,因为我没有使用自定义类型,它是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.

当我试图在DB中应用更改

时,试验是悬而未决的
$ 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)只支持模型和字符类型字段中的两个类似字段,即使我是得到这个错误!

然后我从@:Russell Keith-Magee-4 Reply读到。

  

您在这里遇到的是代码弃用周期的结束   不支持多个数据库。

     

在Django 1.2中,我们引入了多个数据库支持;为了   支持这个,get_db_preb_lookup()get_db_prep_value()的原型   connection已更改。

     

为了向后兼容,我们添加了一个透明的垫片   如果这些方法尚未被修复,则“修复”这些方法   开发商。

     

在Django 1.2中,这些垫片的使用提高了一个   PendingDeprecationWarning。在Django 1.3中,他们提出了一个   DeprecationWarning。

     

在Django 1.4下,shim代码已被删除 - 所以任何代码都可以   没有更新现在会引发你所描述的错误。

但由于更新版本的Django Evolution,我没有得到任何DeprecationWarning警告。

但是从上面引用我可以理解,为了支持多个数据库,添加了函数签名,需要额外的参数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): : : 签名,如下所示:

models.filed

我也参考了Django文档

  

Field.db_type(self, connection):

     

考虑连接,返回Field 的数据库列数据类型   对象以及与之关联的设置。

然后我可以理解,要解决此问题,我必须继承def db_type()类并覆盖'char(300)'函数。因为我使用PostgreSQL in which to create 300 chars type field,我需要返回class CharMaxlengthN(models.Field): def db_type(self, connection): return 'char(%d)' % self.max_length # because I am using postgresql 。在我的models.py中,我添加了:

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) 

如果您遇到类似问题,请检查您的下划线DB手册,了解您需要创建哪种类型的列并返回一个字符串。

并更改了新字段的定义(我需要添加)阅读评论:

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.

然后我执行了之前失败的相同命令:

models.Field

我还检查了我的数据库并测试了我新添加的功能它现在运行正常,没有数据库问题。

如果您想创建ENUM字段,请阅读Specifying a mySQL ENUM in a Django model

编辑:我意识到不是子类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

类似地,我需要创建十进制数据库字段,因此我在模型中添加了以下类:

{{1}}