Alter column with added default results in invalid PSQL query
cbautista1002 opened this issue · comments
If you have a model with some field that does not have a default value, and you then modify that model to include a default value, the generated migration for that will fail.
It fails because the resulting PSQL query is an invalid ALTER
statement.
Following the formatting in #87
Steps
- Example model in
models.py
:
class Test(Model):
class Meta:
database = DB
only_save_dirty = True
id = AutoField()
name = CharField(max_length=123, index=True)
- Create initial migration, and migrate it
$ pw_migrate create --auto --directory test/migrations --database $DATABASE_URL --auto-source test test1
$ pw_migrate migrate --directory test/migrations --database $DATABASE_URL --name 001_test1
- Change the model in
models.py
so that the name field now has a default:
name = CharField(max_length=123, index=True, default='D')
- Repeat step 2 to create a new migration and then attempt to migrate it.
Result: the generated PSQL query will be this invalid statement:
ALTER TABLE "test" ALTER COLUMN "name" VARCHAR(123) TYPE DEFAULT 'D'
Something like this PSQL statement would work and is would be more appropriate.
ALTER TABLE "test" ALTER COLUMN "name" SET DEFAULT 'D';
Version:
$ pip list | grep peewee
peewee 3.9.3
peewee-migrate 1.1.5
Thanks!
Here are the tracebacks in case thats helpful:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/peewee_migrate/router.py", line 152, in run_one
migrator.run()
File "/usr/local/lib/python3.6/site-packages/peewee_migrate/migrator.py", line 129, in run
op.run()
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 160, in run
self._handle_result(method(*self.args, **kwargs))
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 154, in _handle_result
self._handle_result(item)
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 149, in _handle_result
self.execute(result)
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 145, in execute
self.migrator.database.execute(node)
File "/usr/local/lib/python3.6/site-packages/playhouse/postgres_ext.py", line 464, in execute
cursor = self.execute_sql(sql, params, commit=commit)
File "/usr/local/lib/python3.6/site-packages/peewee.py", line 2876, in execute_sql
cursor.execute(sql, params or ())
psycopg2.errors.SyntaxError: syntax error at or near "VARCHAR"
LINE 1: ALTER TABLE "pgtest2" ALTER COLUMN "name" VARCHAR(123) TYPE ...
^
Traceback (most recent call last):
File "/usr/local/bin/pw_migrate", line 11, in <module>
sys.exit(cli())
File "/usr/local/lib/python3.6/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.6/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/peewee_migrate/cli.py", line 63, in migrate
migrations = router.run(name, fake=fake)
File "/usr/local/lib/python3.6/site-packages/peewee_migrate/router.py", line 180, in run
self.run_one(mname, migrator, fake=fake, force=fake)
File "/usr/local/lib/python3.6/site-packages/peewee_migrate/router.py", line 152, in run_one
migrator.run()
File "/usr/local/lib/python3.6/site-packages/peewee_migrate/migrator.py", line 129, in run
op.run()
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 160, in run
self._handle_result(method(*self.args, **kwargs))
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 154, in _handle_result
self._handle_result(item)
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 149, in _handle_result
self.execute(result)
File "/usr/local/lib/python3.6/site-packages/playhouse/migrate.py", line 145, in execute
self.migrator.database.execute(node)
File "/usr/local/lib/python3.6/site-packages/playhouse/postgres_ext.py", line 464, in execute
cursor = self.execute_sql(sql, params, commit=commit)
File "/usr/local/lib/python3.6/site-packages/peewee.py", line 2876, in execute_sql
cursor.execute(sql, params or ())
psycopg2.errors.SyntaxError: syntax error at or near "VARCHAR"
LINE 1: ALTER TABLE "pgtest2" ALTER COLUMN "name" VARCHAR(123) TYPE ...
^
The SQL that is being created is:
"ALTER TABLE "table_name" ALTER COLUMN "table_column" NUMERIC(24, 12) TYPE DEFAULT 0"
The word TYPE is being attached in the wrong place. (see this part of the code for Postgres.)
The DEFAULT clause shouldn't be included in the context._sql. I've made a (really ugly) workaround that removes the space and the DEFAULT clause and I could successfully apply the migrations
I can still reproduce this issue with peewee-migrate==1.1.6