首页 > 解决方案 > psycopg2.errors.InvalidTextRepresentation 用于 Django 迁移到 PositiveSmallIntegerField

问题描述

使用 Postgres 数据库运行 Django 1.11 应用程序 (Python 3.6.5)。

我们最初在需要选择类型的模型上有一个 CharField,因此,在没有充分考虑其含义的情况下,我修改了:

foo = models.CharField(max_length=50, blank=True)

TYPE_1 = 1
TYPE_2 = 2
TYPE_3 = 3

MY_TYPES = (
        (TYPE_1, _('Foo')),
        (TYPE_2, _('Bar')),
        (TYPE_3, _('Etc')),
)

foo = models.PositiveSmallIntegerField(choices=MY_TYPES, default=TYPE_1, blank=True)

运行并生成迁移文件并将应用程序重新部署到我们在 Heroku 上的测试服务器:

remote: Running migrations:
remote:   Applying management.0084_auto_20210708_1730...Traceback (most recent call last):
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
remote:     return self.cursor.execute(sql, params)
remote: psycopg2.errors.InvalidTextRepresentation: invalid input syntax for integer: ""
remote: 
remote: 
remote: The above exception was the direct cause of the following exception:
remote: 
remote: Traceback (most recent call last):
remote:   File "manage.py", line 19, in <module>
remote:     execute_from_command_line(sys.argv)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
remote:     utility.execute()
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
remote:     self.fetch_command(subcommand).run_from_argv(self.argv)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
remote:     self.execute(*args, **cmd_options)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
remote:     output = self.handle(*args, **options)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
remote:     fake_initial=fake_initial,
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
remote:     state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
remote:     state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
remote:     state = migration.apply(state, schema_editor)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/migration.py", line 129, in apply
remote:     operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 221, in database_forwards
remote:     schema_editor.alter_field(from_model, from_field, to_field)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 531, in alter_field
remote:     old_db_params, new_db_params, strict)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/postgresql/schema.py", line 112, in _alter_field
remote:     new_db_params, strict,
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 706, in _alter_field
remote:     params,
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 136, in execute
remote:     cursor.execute(sql, params)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
remote:     return self.cursor.execute(sql, params)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
remote:     six.reraise(dj_exc_type, dj_exc_value, traceback)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
remote:     raise value.with_traceback(tb)
remote:   File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
remote:     return self.cursor.execute(sql, params)
remote: django.db.utils.DataError: invalid input syntax for integer: ""

我理解这个问题(原始 CharField 中的空字符串会引发语法错误,因为它现在是 IntegerField - 在这样做之前应该考虑到这一点)。

我尝试回滚到以前的迁移,但看起来这个 PSQL 实例的损坏已经完成,因为我的还原引发了相同的错误。我可以改变这个模型吗?最好完全删除原来的 CharField(迁移那个),然后引入一个新的 PositiveSmallIntegerField?

我可以删除数据库,因为它正在分期,但不希望这样做。谢谢

标签: djangopostgresqlherokudjango-modelsheroku-postgres

解决方案


推荐阅读