我正在为模型添加一个新字段,但无法进行迁移
sqlite3.OperationalError: no such column: main_language.iso639_1
我只能通过注释掉对代码中对新字段的所有引用来生成带有makemigration的迁移文件,但是现在我必须在不将字段注释掉的情况下运行迁移。
这是不可接受的,因为引用我的新字段显然需要最终出现在我的代码中,而其他任何使用最新版本代码库的人在尝试运行迁移时都将获得未注释的代码。
尽管多次向模型中添加新字段,但我没有遇到这个问题,不确定这次为什么会发生这种情况:
# iso639_1 is the new field
class Language(TranslatableMixin, models.Model):
ENGLISH = 1 # id for English should always be 1
ISO_HELP_TEXT = _("Please find the correct code at: https://www.loc.gov/standards/iso639-2/php/code_list.php")
title = models.ForeignKey('main.Sentence', on_delete=models.PROTECT, related_name='LanguageTitle')
iso639_2 = models.CharField(max_length=8, help_text=ISO_HELP_TEXT)
iso639_1 = models.CharField(max_length=8, blank=True, default='', help_text=ISO_HELP_TEXT)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
created = models.DateTimeField(auto_now_add=True)
objects = LanguageManager()
尝试运行“ python manage.py migration”时收到错误:
Traceback (most recent call last):
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\sqlite3\base.py", line 303, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such column: main_language.iso639_1
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Win7\OneDrive\Programming\Git\lang\manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
utility.execute()
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\management\__init__.py", line 365, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\management\base.py", line 288, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\management\base.py", line 332, in execute
self.check()
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\management\base.py", line 364, in check
include_deployment_checks=include_deployment_checks,
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\management\commands\migrate.py", line 58, in _run_checks
issues.extend(super()._run_checks(**kwargs))
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\management\base.py", line 351, in _run_checks
return checks.run_checks(**kwargs)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\checks\registry.py", line 73, in run_checks
new_errors = check(app_configs=app_configs)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
return check_resolver(resolver)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
return check_method()
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\urls\resolvers.py", line 399, in check
for pattern in self.url_patterns:
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\utils\functional.py", line 36, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\urls\resolvers.py", line 540, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\utils\functional.py", line 36, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\urls\resolvers.py", line 533, in urlconf_module
return import_module(self.urlconf_name)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\Users\Win7\OneDrive\Programming\Git\lang\lang\urls.py", line 3, in <module>
from lang import views as core_views
File "C:\Users\Win7\OneDrive\Programming\Git\lang\lang\views.py", line 9, in <module>
from main.views import background_tasks
File "C:\Users\Win7\OneDrive\Programming\Git\lang\main\views\__init__.py", line 1, in <module>
from .assess import *
File "C:\Users\Win7\OneDrive\Programming\Git\lang\main\views\assess.py", line 6, in <module>
from .main import move_to_next_mode
File "C:\Users\Win7\OneDrive\Programming\Git\lang\main\views\main.py", line 4, in <module>
from main.forms import SignUpCourseForm, SelectClassForm
File "C:\Users\Win7\OneDrive\Programming\Git\lang\main\forms.py", line 25, in <module>
class InviteDetailsForm(forms.Form):
File "C:\Users\Win7\OneDrive\Programming\Git\lang\main\forms.py", line 36, in InviteDetailsForm
label = _('Which language should the invitation email be sent in?'),
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\forms\fields.py", line 758, in __init__
self.choices = choices
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\forms\fields.py", line 775, in _set_choices
value = list(value)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\models\query.py", line 272, in __iter__
self._fetch_all()
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\models\query.py", line 1179, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\models\query.py", line 53, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\models\sql\compiler.py", line 1068, in execute_sql
cursor.execute(sql, params)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\utils.py", line 100, in execute
return super().execute(sql, params)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\db\backends\sqlite3\base.py", line 303, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such column: main_language.iso639_1
Finished "C:\Users\Win7\OneDrive\Programming\Git\lang\manage.py migrate" execution.
LanguageManager中存在引发错误的代码。
class LanguageManager(models.Manager):
def interface_language_choices(self):
localizations = [x[0] for x in settings.LANGUAGES]
return Language.objects.filter(iso639_1__in=localizations)
如果我注释掉 def interface_language_choices(self)的主体并替换为 pass ,则会收到与该函数有关的错误,这些错误均未提供返回值。为什么甚至坚持只运行我的代码来进行迁移?
我的迁移文件:
from django.db import migrations, models
def populate_iso(apps, schema_editor):
Language = apps.get_model('main', 'Language')
for x in (('eng','en'),('tur','tr'),('rus','ru'),('fra','fr'),('uzb','uz'),('spa','es')):
L = Language.objects.get(iso639_2=x[0])
L.iso639_1 = x[1]
L.save()
class Migration(migrations.Migration):
dependencies = [
('main', '0030_auto_20180620_1649'),
]
operations = [
migrations.AddField(
model_name='language',
name='iso639_1',
field=models.CharField(blank=True, default='', help_text='Please find the correct code at: https://www.loc.gov/standards/iso639-2/php/code_list.php', max_length=8),
),
migrations.RunPython(populate_iso),
]
答案 0 :(得分:1)
更改数据的迁移通常称为“数据迁移”; 最好将它们编写为单独的迁移,与模式迁移并列。
IOW:将您的迁移分为两部分-第一个添加字段,第二个添加相关数据。
但是这实际上不是您的问题。从您的追溯:
File "C:\Users\Win7\OneDrive\Programming\Git\lang\main\forms.py", line 25, in <module>
class InviteDetailsForm(forms.Form):
File "C:\Users\Win7\OneDrive\Programming\Git\lang\main\forms.py", line 36, in InviteDetailsForm
label = _('Which language should the invitation email be sent in?'),
File "C:\Users\Win7\OneDrive\Programming\Git\lang\.venv\lib\site-packages\django\forms\fields.py", line 758, in __init__
self.choices = choices
您的InviteDetailsForm
代码显然是在类顶层进行数据库查询 来填充字段的选择-我假设类似:
class InviteDetailsForm(forms.Form):
# ...
something = forms.ChoiceField(
choice= Language.objects.interface_languages_choices()
# ...
)
此代码在导入模块时执行(这是正常的Python操作-class
是可执行语句),这会导致问题。解决方法是pass the method itself instead of passing it's result:
something = forms.ChoiceField(
# notice the absence of parens !
choice= Language.objects.interface_languages_choices,
# ...
)
或者使用ModelChoiceField
代替ChoiceField
(前者不会强制执行查询集的评估,而后者会强制执行)。
为什么甚至要坚持运行我的代码只是为了进行迁移
因为“它”需要加载应用程序和模型以及url conf,这将导入视图,这将导入表单模块,并在您的表单类的顶层执行代码,从而调用您的方法。