使用南迁移时Django报错:“字段列表”中的未知列
使用 schemamigration 将列添加到数据库时遇到问题。有问题的字段“is_flaged”是一个布尔值,属于我的应用程序“上传”中的视频模型。运行迁移时,我得到以下信息:
....:~/..../webapp$ python manage.py schemamigration upload --auto
Traceback (most recent call last):
File "manage.py", line 14, in <module>
execute_manager(settings)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 219, in execute
self.validate()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 249, in validate
num_errors = get_validation_errors(s, app)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/validation.py", line 36, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 146, in get_app_errors
self._populate()
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 61, in _populate
self.load_app(app_name, True)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 78, in load_app
models = import_module('.models', app_name)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/..../score/models.py", line 43, in <module>
class Score(models.Model): # matches with one specific user and one specific video
File "/home/..../score/models.py", line 45, in Score
video = models.ForeignKey(Video, default=Video.objects.all()[0]) # default value shouldn't end up in real objects
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 190, in __getitem__
return list(qs)[0]
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 84, in __len__
self._result_cache.extend(self._iter)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 273, in iterator
for row in compiler.results_iter():
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 680, in results_iter
for rows in self.execute_sql(MULTI):
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/base.py", line 86, in execute
return self.cursor.execute(query, args)
File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 166, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/pymodules/python2.7/MySQLdb/connections.py", line 35, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1054, "Unknown column 'upload_video.is_flagged' in 'field list'")
知道为什么它不允许我迁移吗?当我专门使用 --add-field 时也会发生同样的情况。
我认为问题可能在于另一个应用程序中的外键(“分数”,正如您在回溯中看到的那样)引用了视频对象。如果是这种情况,迁移其他应用程序中的外键引用的模型的正确方法是什么?
更新
我找到了一个解决方法,即注释掉“score”中有问题的ForeignKey行,照常运行迁移,最后取消注释该行,而无需迁移“score”本身。这可行,但并不优雅,而且如果应用程序之间有很多外键,就会很麻烦。正如我之前问的,有什么方法可以自动避免这种情况,而不必将带有外键的模型编辑为带有新字段的模型?
I'm running into a problem when using schemamigration to add a column to my database. The field in question, 'is_flagged', is a boolean belonging to the Video model in my app 'upload'. When running the migration, I get the following:
....:~/..../webapp$ python manage.py schemamigration upload --auto
Traceback (most recent call last):
File "manage.py", line 14, in <module>
execute_manager(settings)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 219, in execute
self.validate()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 249, in validate
num_errors = get_validation_errors(s, app)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/validation.py", line 36, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 146, in get_app_errors
self._populate()
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 61, in _populate
self.load_app(app_name, True)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 78, in load_app
models = import_module('.models', app_name)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/..../score/models.py", line 43, in <module>
class Score(models.Model): # matches with one specific user and one specific video
File "/home/..../score/models.py", line 45, in Score
video = models.ForeignKey(Video, default=Video.objects.all()[0]) # default value shouldn't end up in real objects
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 190, in __getitem__
return list(qs)[0]
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 84, in __len__
self._result_cache.extend(self._iter)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 273, in iterator
for row in compiler.results_iter():
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 680, in results_iter
for rows in self.execute_sql(MULTI):
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/base.py", line 86, in execute
return self.cursor.execute(query, args)
File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 166, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/pymodules/python2.7/MySQLdb/connections.py", line 35, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1054, "Unknown column 'upload_video.is_flagged' in 'field list'")
Any idea why it won't let me migrate? The same happens when I specifically use --add-field too.
I think the problem might lie in a ForeignKey in another app ('score', as you can see in the traceback) which references the Video object. If that's the case, what is the proper way to migrate models which are referenced by ForeignKeys in other apps?
Update
I found a workaround, which is to comment out the offending ForeignKey line in 'score', run the migration as usual, and finally uncomment the line, without ever migrating 'score' itself. This works, but it's not elegant, and would be cumbersome if there were many ForeignKeys between apps. As I asked before, is there any way to avoid this automatically, without having to edit the model with the ForeignKey to the model with the new field?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题不在于您有一个
ForeignKey
指向您正在迁移的模型。这是一种非常常见的情况,South
绝对可以很好地处理这种情况。真正的问题是你在 FK 声明中做了一些非常非常糟糕的事情。
此默认声明将在导入时执行查询并获取它的第一个值。在导入时执行的事情是一个很大的禁忌(尤其是查询)。
因此,当
South
导入模型以便能够内省它们并生成架构迁移时,Video.objects.all()
就会被执行。但是,由于Video
模型已更改(您刚刚添加了一个新字段),而该模型在数据库中尚不存在,因此 Django 的 ORM 会引发错误。如果您确实想将其设置为默认值,请使用可调用
注意:虽然我一开始就想不出一个好的理由,但为了设置第一个
Video
记录为视频 FK 的默认值。你想做什么?The problem is not that you have a
ForeignKey
pointed to the model you are migrating. That is a very common situation, andSouth
definitely deals fine with that.The real problem is that you are doing something very very bad in that FK declaration.
This default declaration is going to execute the query at import time and take it's first value. Things that execute at import time are a big no-no (especially a query).
So what happens is, when
South
imports the models so that it can introspect them and generate the schemamigration,Video.objects.all()
is executed. But becauseVideo
model was changed (you've just added a new field), which doesn't exist yet in DB, Django's ORM raises an error.If you really want to set that as your default value, then use a callable instead
Note: Although I cannot think of a good reason in the first place, for setting the first
Video
record as default value for the video FK. What are you trying to do?不确定这是否正是您正在寻找的,但我遇到了类似的问题,这就是解决它的方法。如果您更改了模型并且没有正确更新数据库,那么您将收到相同的错误。运行syncdb不会更改已创建的表,因此在加载任何其他数据之前,必须重置数据库。
然后再次同步你的数据库,你应该就可以了。
Not sure if this is exactly what you are looking for but I ran into a similar problem and this is what fixed it. If you have changed you models and have not properly updated the database then you will get the same error. Running syncdb won't change tables that have already been created so before you can load any additional data you must reset the database.
Then sync your database again and you should be good.