我在数据库模型中添加了一个包含日期字段格式的字段后遇到了问题。
像这样:
date_format = models.CharField(max_length=32, default='%B %Y')
然而,在同一次迁移中,出现了一些具有默认值的布尔值。深入研究问题,并多次重建测试数据库。。。。
问题是在表中的任何迁移中,默认值中有percentgae符号。所以不是在其elve中有这个字段的迁移,而是到同一个表的任何迁移(见我的第二个答案)
添加这样的字段:
show_category_name = models.BooleanField(default=True)
带有autoschemmigration,会给出一个带有以下行的迁移文件:
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'NewsItemCategory.show_category_name'
db.add_column('iamweb_newsitemcategory', 'show_category_name',
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
出现此问题:
bin/django migrate iamwebdjango.db.backends DEBUG (0.006) SELECT "south_migrationhistory"."id", "south_migrationhistory"."app_name", "south_migrationhistory"."migration", "south_migrationhistory"."applied" FROM "south_migrationhistory" WHERE "south_migrationhistory"."applied" IS NOT NULL ORDER BY "south_migrationhistory"."applied" ASC; args=()
Running migrations for iamweb:
- Migrating forwards to 0020_auto__add_field_newsitemcategory_show_category_name__add_field_weblink.
> iamweb:0020_auto__add_field_newsitemcategory_show_category_name__add_field_weblink
django.db.backends DEBUG (0.277) CREATE TABLE ROLLBACK_TEST (X INT); args=()
django.db.backends DEBUG (0.008) INSERT INTO ROLLBACK_TEST (X) VALUES (8); args=()
django.db.backends DEBUG (0.001) SELECT COUNT(X) FROM ROLLBACK_TEST; args=()
django.db.backends DEBUG (0.273) DROP TABLE ROLLBACK_TEST; args=()
django.db.backends DEBUG (0.177) CREATE TABLE STDDEV_TEST (X INT); args=()
django.db.backends DEBUG (0.000) SELECT STDDEV(*) FROM STDDEV_TEST; args=()
django.db.backends DEBUG (0.160) DROP TABLE STDDEV_TEST; args=()
django.db.backends DEBUG (0.151) CREATE TABLE DDL_TRANSACTION_TEST (X INT); args=()
django.db.backends DEBUG (0.000) CREATE TABLE DDL_TRANSACTION_TEST (X INT); args=()
django.db.backends DEBUG (0.155) DROP TABLE DDL_TRANSACTION_TEST; args=()
django.db.backends DEBUG (0.000) PRAGMA table_info("iamweb_newsitemcategory"); args=()
django.db.backends DEBUG (0.000) PRAGMA index_list("iamweb_newsitemcategory"); args=()
django.db.backends DEBUG (0.000) PRAGMA index_info("sqlite_autoindex_iamweb_newsitemcategory_1"); args=()
django.db.backends DEBUG (0.000) PRAGMA index_list("iamweb_newsitemcategory"); args=()
django.db.backends DEBUG (0.000) PRAGMA index_info("sqlite_autoindex_iamweb_newsitemcategory_1"); args=()
django.db.backends DEBUG (0.000) PRAGMA table_info("iamweb_newsitemcategory"); args=()
south DEBUG execute "CREATE TABLE "_south_new_iamweb_newsitemcategory" ("date_format" varchar(32) DEFAULT '%B %Y', "show_category_name" bool NOT NULL DEFAULT 1, "id" integer PRIMARY KEY, "menu_index" integer NOT NULL UNIQUE, "name" varchar(64) NOT NULL)" with params "[]"
! Error found during real run of migration! Aborting.
! Since you have a database that does not support running
! schema-altering statements in transactions, we have had
! to leave it in an interim state between migrations.
! You *might* be able to recover with:
! The South developers regret this has happened, and would
! like to gently persuade you to consider a slightly
! easier-to-deal-with DBMS (one that supports DDL transactions)
! NOTE: The error which caused the migration to fail is further up.
Error in migration: iamweb:0020_auto__add_field_newsitemcategory_show_category_name__add_field_weblink
Traceback (most recent call last):
File "bin/django", line 33, in <module>
djangorecipe.manage.main('palmrif.developmentsettings')
File "/media/storage/django/sites/palmrif/eggs/djangorecipe-0.20-py2.7.egg/djangorecipe/manage.py", line 16, in main
management.execute_manager(mod)
File "/media/storage/django/sites/palmrif/parts/django/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/media/storage/django/sites/palmrif/parts/django/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/media/storage/django/sites/palmrif/parts/django/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/media/storage/django/sites/palmrif/parts/django/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/management/commands/migrate.py", line 108, in handle
ignore_ghosts = ignore_ghosts,
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/migration/__init__.py", line 213, in migrate_app
success = migrator.migrate_many(target, workplan, database)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 235, in migrate_many
result = migrator.__class__.migrate_many(migrator, target, migrations, database)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 310, in migrate_many
result = self.migrate(migration, database)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 133, in migrate
result = self.run(migration)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 107, in run
return self.run_migration(migration)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 81, in run_migration
migration_function()
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 57, in <lambda>
return (lambda: direction(orm))
File "/media/storage/django/sites/palmrif/local_checkouts_dev/iamweb/iamweb/migrations/0020_auto__add_field_newsitemcategory_show_category_name__add_field_weblink.py", line 14, in forwards
keep_default=False)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/sqlite3.py", line 31, in add_column
field.column: self._column_sql_for_create(table_name, name, field, False),
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/generic.py", line 44, in _cache_clear
return func(self, table, *args, **opts)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/sqlite3.py", line 103, in _remake_table
", ".join(["%s %s" % (self.quote_name(cname), ctype) for cname, ctype in definitions.items()]),
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/generic.py", line 273, in execute
cursor.execute(sql, params)
File "/media/storage/django/sites/palmrif/parts/django/django/db/backends/util.py", line 38, in execute
sql = self.db.ops.last_executed_query(self.cursor, sql, params)
File "/media/storage/django/sites/palmrif/parts/django/django/db/backends/__init__.py", line 505, in last_executed_query
return smart_unicode(sql) % u_params
TypeError: not enough arguments for format string
我用的是南方0.7.6。奇怪的是,这个版本应该已经修复了这个错误,请参阅:发布说明0.7.6。修复sqlite 中默认布尔值的错误
使用sqlite3、python 2.7.2、django 1.3.1(顺便说一句,在生产中使用mySql,但sqlite中的测试数据库非常方便)
请注意,问题涉及迁移文件中的第14行,即这一行:
db.add_column('iamweb_newsitemcategory', 'show_category_name',
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
没有足够的论据。。。。首先:我没有创建这条线,South创建了:)
堆栈跟踪有点令人困惑,因为调试行的最后一行(在堆栈跟踪之前)是:
south DEBUG execute "CREATE TABLE "_south_new_iamweb_newsitemcategory" ("date_format" varchar(32) DEFAULT '%B %Y', "show_category_name" bool NOT NULL DEFAULT 1, "id" integer PRIMARY KEY, "menu_index" integer NOT NULL UNIQUE, "name" varchar(64) NOT NULL)" with params "[]"
因此,这可能与South仍然希望解析字符串有关,因为该执行命令中有"%B%Y"。。。。
在与这个问题斗争了4天后(当然不是全职),我开始怀疑南方的道路。。。。然而,没有找到更好的替代方案。
我刚刚在南方邮件列表上回复了。总结一下:布尔值是无辜的,百分比是有罪的,Sqlite是一个玩具,因此它的South后端有点疯狂,显然有一个bug。一个新的、即将推出的South版本应该避免在数据库中存储默认值,这可能会解决您的问题(至少在测试中是这样)。
317号票据无关紧要。目前,票证#1192应该由当前拉取请求中的代码修复(或者你可以从我的分叉中提取,https://bitbucket.org/shaib/south)。
Ah问题可能不在"%B%Y"默认值中。(因此我编辑了问题和标题)sqlite中的默认布尔值似乎存在一些问题。请参阅问题中我的编辑。还有一些布尔值不支持True和false的默认值。参见南票
迁移文件中建议的解决方案是:
if db.backend_name == "sqlite3":
default = 1
else:
default = True
db.add_column('node_entry', 'visible', self.gf('django.db.models.fields.BooleanField')(default=default), keep_default=False)
但这不起作用,进一步阅读,它应该在我使用的南方版本中得到解决。。。
很确定问题出现在默认值"%B%Y"中。那一次的迁移进行得还可以,但在这之后,新的迁移出现了问题。我发现,因为我有3个布尔值字段,所以我希望默认值为true。其中2人在另一个领域的表格中有这个百分比。我标出了这两次迁移,剩下的一次还可以。
问题是用百分比符号重新创建表格
参见轨道:
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/sqlite3.py", line 31, in add_column
field.column: self._column_sql_for_create(table_name, name, field, False),
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/generic.py", line 44, in _cache_clear
return func(self, table, *args, **opts)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/sqlite3.py", line 103, in _remake_table
", ".join(["%s %s" % (self.quote_name(cname), ctype) for cname, ctype in definitions.items()]),
所以我想我会尝试重新开放南方的门票,并将他们介绍到这个网站。并更改这张票的标题。
我在票上加了一条评论:http://south.aeracode.org/ticket/317