python - 向现有模型添加新字段 - django.db.utils.ProgrammingError : column {field} does not exist

标签 python django postgresql django-models database-migration

模型.py

我有一个 Scorecard 模型,它有一个 ManyToManyField 到另一个名为 Account 的模型:

class Scorecard(models.Model):

    ....
    name = models.CharField(max_length=100)
    accounts = models.ManyToManyField(Account)
    ...

    def __str__(self):
        return self.name

我的 Account 类目前有四个字段(account_name、adwords_account_id、bingads_account_id、label)。

class Account(models.Model):

    account_name = models.CharField(max_length=100)
    adwords_account_id = models.CharField(max_length=10, blank=True)
    bingads_account_id = models.CharField(max_length=15, blank=True)
    # gemini_account_id = models.CharField(max_length=15, blank=True)
    label = models.CharField(max_length=30, blank=True)

    def __str__(self):
        return self.account_name

请注意,字段 gemini_account_id 已被注释掉。 我想将这个字段添加到模型中。

如果我将 gemini_account_id 注释掉并运行服务器,一切正常。

如果我然后取消注释 gemini_account_id 并执行 python manage.py makemigrations

(venv) C:\Django\scorecard>python manage.py makemigrations

完全错误

Traceback (most recent call last):
  File "C:\Django\venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: column scorecards_account.gemini_account_id does not exist
LINE 1: ...t_id", "scorecards_account"."bingads_account_id", "scorecard...
                                                             ^


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Django\venv\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "C:\Django\venv\lib\site-packages\django\core\management\__init__.py", line 347, in execute
    django.setup()
  File "C:\Django\venv\lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Django\venv\lib\site-packages\django\apps\registry.py", line 120, in populate
    app_config.ready()
  File "C:\Django\venv\lib\site-packages\django\contrib\admin\apps.py", line 23, in ready
    self.module.autodiscover()
  File "C:\Django\venv\lib\site-packages\django\contrib\admin\__init__.py", line 26, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "C:\Django\venv\lib\site-packages\django\utils\module_loading.py", line 47, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "C:\Django\venv\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "C:\Django\scorecard\scorecards\admin.py", line 2, in <module>
    from scorecards.forms import (ScorecardAdminForm, AccountAdminForm, ReportTypeAdminForm,
  File "C:\Django\scorecard\scorecards\forms.py", line 5, in <module>
    class ScorecardAdminForm(forms.ModelForm):
  File "C:\Django\scorecard\scorecards\forms.py", line 7, in ScorecardAdminForm
    class Meta:
  File "C:\Django\scorecard\scorecards\forms.py", line 15, in Meta
    attrs={'class': 'wide-select'}),
  File "C:\Django\venv\lib\site-packages\django\forms\widgets.py", line 558, in __init__
    self.choices = list(choices)
  File "C:\Django\venv\lib\site-packages\django\db\models\query.py", line 272, in __iter__
    self._fetch_all()
  File "C:\Django\venv\lib\site-packages\django\db\models\query.py", line 1179, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "C:\Django\venv\lib\site-packages\django\db\models\query.py", line 54, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "C:\Django\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1063, in execute_sql
    cursor.execute(sql, params)
  File "C:\Django\venv\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "C:\Django\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:\Django\venv\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Django\venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Django\venv\lib\site-packages\django\db\utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Django\venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: column scorecards_account.gemini_account_id does not exist
LINE 1: ...t_id", "scorecards_account"."bingads_account_id", "scorecard...
                                                             ^

好的。所以这告诉我 gemini_account_id 列在数据库中不存在。我对此的 react 是“那是因为我正在尝试添加它!”。我认为 makemigrations 可以帮助我做到这一点?

将新字段添加到现有模型(Account)的适当操作步骤是什么,该模型是另一个模型(记分卡)的“ManyToManyField” >)?

Picture of PostGreSQL Table

我的数据库是 PostgrSQL。

我尝试了什么:

  1. python manage.py makemigrations scorecards : 与上面相同的错误
  2. 重命名了 migrations 文件夹,使用 init.py 创建了一个空文件夹:与上面相同的错误。
  3. 我经历了之前的每一次迁移,一次删除一个并运行 makemigrations:每次都出现与上面相同的错误

我看过的其他帖子:

This one似乎是最接近的,但建议是“迁移落后于该特定模型”。

更新: 这是 forms.py ScorecardAdminForm:

class ScorecardAdminForm(forms.ModelForm):

    class Meta:

        model = Scorecard
        fields = '__all__'
        #fields = ('name', 'accounts', 'report_type', 'date_range')
        widgets = {
            'name': forms.TextInput(attrs={'class': 'wide-select'}),
            'accounts': forms.SelectMultiple(choices=Account.objects.all(),
                                             attrs={'class': 'wide-select'}),
            'report_type': forms.Select(attrs={'class': 'wide-select'}),
            'date_range': forms.Select(attrs={'class': 'wide-select'}),
            'time_segment': forms.Select(attrs={'class': 'wide-select'})
        }

    def clean(self):
        cleaned_data = super().clean()
        date_range = cleaned_data.get('date_range')
        start_date = cleaned_data.get('start_date')
        end_date = cleaned_data.get('end_date')

        if date_range == 'CUSTOM_DATE':
            if start_date is None or end_date is None:
                raise ValidationError(
                    "Start or end can't be left blank "
                    "when report type is custom date range."
                )

我想我确实通过注释掉 admin.py 和 forms.py 中的所有内容,然后按照 this answer 来迁移所有内容. 原因在我的 ScorecardAdminForm 中吗?也许是 raise ValidationError 部分?对不起,我是一只迷路的小羊。

最佳答案

该字段是通过管理表单引用的。从 ScorecardAdminForm 中删除引用并首先进行迁移。

关于python - 向现有模型添加新字段 - django.db.utils.ProgrammingError : column {field} does not exist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48103203/

相关文章:

用于创建和操作列表的 Python 函数

python - 类似 Python 2.7 + Bottle 框架的 socket.io

python - sqlalchemy:停止长时间运行的查询

sql - Django - 在没有外键的情况下连接不同的模型

sql - 正则表达式字符串的最后一部分不一致的模式或长度

sql - 如何在 PostgreSQL 列中显示前导/尾随空格?

python - 使用 Django 设置参数化测试

python - 适用于 Python 2.7 (Ubuntu) 的 MySQLdb

python - 配置 Django 日志记录 - SQL 和其他消息

python - 如何使用 Django 和 Python 设置环境变量?