#12643 closed defect (fixed)
Check for table existence in DatabaseManager.upgrade_tables
| Reported by: | Ryan J Ollos | Owned by: | Ryan J Ollos |
|---|---|---|---|
| Priority: | normal | Milestone: | 1.3.2 |
| Component: | database backend | Version: | |
| Severity: | normal | Keywords: | |
| Cc: | Branch: | ||
| Release Notes: | |||
| API Changes: |
|
||
| Internal Changes: | |||
Description
If upgrade_tables checked for table existence before attempting to copy the data to a temporary table, then upgrade_tables could handle a mix of new and revised tables. This would make the upgrade function slightly similar for a case such as that demonstrated in db4.py for SpamFilter.
Attachments (0)
Change History (12)
comment:1 by , 9 years ago
| Summary: | Check for table existence in DatabaseManager.ugrade_tables → Check for table existence in DatabaseManager.upgrade_tables |
|---|
comment:2 by , 9 years ago
| Milestone: | next-stable-1.2.x → 1.2.1 |
|---|---|
| Owner: | set to |
| Status: | new → assigned |
comment:3 by , 9 years ago
| API Changes: | modified (diff) |
|---|
comment:4 by , 9 years ago
| Milestone: | 1.2.1 → 1.3.2 |
|---|
comment:5 by , 9 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
follow-up: 7 comment:6 by , 9 years ago
I think the table4 should be removed in ModifyTableTestCase.tearDown().
In addition, table names in MySQL on Windows are case-insensitive. The changes in [15316] may not work as expected.
.get_column_names() with non-existent table returns an empty list. We could check whether the returned value is empty.
-
trac/db/api.py
diff --git a/trac/db/api.py b/trac/db/api.py index 39dead193..68fd485c1 100644
a b class DatabaseManager(Component): 357 357 358 358 :since: version 1.2 359 359 """ 360 existing_table_names = self.get_table_names()361 360 for new_table in new_schema: 362 361 temp_table_name = new_table.name + '_old' 363 362 old_column_names = set(self.get_column_names(new_table)) 364 363 new_column_names = {col.name for col in new_table.columns} 365 364 cols_to_copy = ','.join(old_column_names & new_column_names) 366 365 with self.env.db_transaction as db: 367 has_table = new_table.name in existing_table_names366 has_table = bool(old_column_names) 368 367 if has_table: 369 368 cursor = db.cursor() 370 369 cursor.execute("""
I think .get_column_names() may be better to raise an exception if the given table is not existent….
follow-up: 8 comment:7 by , 9 years ago
Replying to Jun Omae:
I think the
table4should be removed inModifyTableTestCase.tearDown().
Make sense. I'm sure I had added this, so I'm stumped as to why it wasn't in my final changes.
In addition, table names in MySQL on Windows are case-insensitive. The changes in [15316] may not work as expected.
Perhaps we should add has_table(...) method to DatabaseManager and ConnectionBase?
I think
.get_column_names()may be better to raise an exception if the given table is not existent….
I agree with .get_column_names() raising exception when table doesn't exist.
comment:8 by , 9 years ago
Replying to Ryan J Ollos:
Replying to Jun Omae:
I think the
table4should be removed inModifyTableTestCase.tearDown().Make sense. I'm sure I had added this, so I'm stumped as to why it wasn't in my final changes.
In addition, table names in MySQL on Windows are case-insensitive. The changes in [15316] may not work as expected.
Perhaps we should add
has_table(...)method toDatabaseManagerandConnectionBase?
Sounds good. See [ead3a3383/jomae.git].
I think
.get_column_names()may be better to raise an exception if the given table is not existent….I agree with
.get_column_names()raising exception when table doesn't exist.
Thanks. I consider .drop_columns() also should raise an exception with missing table, [f03bc446c/jomae.git].
Proposed changes in jomae.git@t12643.1.
comment:9 by , 9 years ago
Looks good, thanks for fixing. I might suggest changing the error message to Table "blah" not found, consistent with tags/trac-1.2/trac/db/sqlite_backend.py@:302#L298.
comment:10 by , 9 years ago
| API Changes: | modified (diff) |
|---|
Thanks for the suggesting. Committed changes with your suggestions in [15322].
comment:11 by , 8 years ago
I saw a failure executing db44.py on teo (Postgres 9.4). I grabbed the database and reproduced locally.
[pid 38343 140737226027968] 19:30:27 Trac[console] ERROR: Exception in trac-admin command: u'upgrade' Traceback (most recent call last): File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/admin/console.py", line 112, in onecmd rv = cmd.Cmd.onecmd(self, line) or 0 File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cmd.py", line 220, in onecmd return self.default(line) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/admin/console.py", line 291, in default return self.cmd_mgr.execute_command(*args) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/admin/api.py", line 135, in execute_command return f(*fargs) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/env.py", line 999, in _do_upgrade self.env.upgrade(backup=no_backup is None) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/env.py", line 738, in upgrade participant.upgrade_environment() File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/env.py", line 779, in upgrade_environment pkg='trac.upgrades') File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/db/api.py", line 532, in upgrade script.do_upgrade(self.env, i, cursor) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/upgrades/db44.py", line 38, in do_upgrade DatabaseManager(env).upgrade_tables(new_schema) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/db/api.py", line 392, in upgrade_tables self.create_tables((new_table,)) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/db/api.py", line 302, in create_tables db(sql) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/db/util.py", line 129, in execute cursor.execute(query, params if params is not None else []) File "/Users/rjollos/Documents/Workspace/trac-dev/teo-rjollos.git/trac/db/util.py", line 74, in execute return self.cursor.execute(sql) ProgrammingError: relation "enum" already exists ProgrammingError: relation "enum" already exists
has_tables returns False and self.schema is None: trunk/trac/db/postgres_backend.py@15420:389#L385. It seems that self.schema should be public:
> SELECT * FROM information_schema.columns WHERE table_name='enum'; +-----------------+----------------+--------------+---------------+------------- | table_catalog | table_schema | table_name | column_name | ordinal_po |-----------------+----------------+--------------+---------------+------------- | teo | public | enum | type | | teo | public | enum | name | | teo | public | enum | value | +-----------------+----------------+--------------+---------------+------------- SELECT 3
The upgrade succeeds if I append ?schema=public to the database string. However, I think that teo has not used ?schema=public in the connection string and it has worked previous. TracEnvironment says:
Trac uses the
publicschema by default…



Committed to trunk in r15316.