Fix table migration on non-exist-yet indexed columns. (#6666)

### What problem does this PR solve?

Fix #6334

Hello, I encountered the same problem in #6334. In the
`api/db/db_models.py`, it calls `obj.create_table()` unconditionally in
`init_database_tables`, before the `migrate_db()`. Specially for the
`permission` field of `user_canvas` table, it has `index=True`, which
causes `peewee` to issue a SQL trying to create the index when the field
does not exist (the `user_canvas` table already exists), so
`psycopg2.errors.UndefinedColumn: column "permission" does not exist`
occurred.

I've added a judgement in the code, to only call `create_table()` when
the table does not exist, delegate the migration process to
`migrate_db()`.

Then another problem occurs: the `migrate_db()` actually does nothing
because it failed on the first migration! The `playhouse` blindly issue
DDLs without things like `IF NOT EXISTS`, so it fails... even if the
exception is `pass`, the transaction is still rolled back. So I removed
the transaction in `migrate_db()` to make it work.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
- [ ] New Feature (non-breaking change which adds functionality)
- [ ] Documentation Update
- [ ] Refactoring
- [ ] Performance Improvement
- [ ] Other (please describe):
This commit is contained in:
Song Fuchang 2025-03-31 11:27:20 +08:00 committed by GitHub
parent ad4e59edb2
commit d4a3e9a7cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -424,6 +424,8 @@ def init_database_tables(alter_fields=[]):
for name, obj in members:
if obj != DataBaseModel and issubclass(obj, DataBaseModel):
table_objs.append(obj)
if not obj.table_exists():
logging.debug(f"start create table {obj.__name__}")
try:
obj.create_table()
@ -431,6 +433,9 @@ def init_database_tables(alter_fields=[]):
except Exception as e:
logging.exception(e)
create_failed_list.append(obj.__name__)
else:
logging.debug(f"table {obj.__name__} already exists, skip creation.")
if create_failed_list:
logging.error(f"create tables failed: {create_failed_list}")
raise Exception(f"create tables failed: {create_failed_list}")
@ -792,7 +797,6 @@ class UserCanvasVersion(DataBaseModel):
def migrate_db():
with DB.transaction():
migrator = DatabaseMigrator[settings.DATABASE_TYPE.upper()].value(DB)
try:
migrate(migrator.add_column("file", "source_type", CharField(max_length=128, null=False, default="", help_text="where dose this document come from", index=True)))