mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2026-10-30 16:20:04 -05:00
Use resolve_fks=False in migration reflect() so stale FKs don't crash startup (#9976)
An old configuration database (e.g. a pre-9.0 pgadmin4.db lingering in %appdata%) can carry a stale foreign key such as server.user_id -> user_old, a table removed long ago. SQLAlchemy's MetaData.reflect() defaults to resolve_fks=True, which auto-follows the reflected table's foreign keys and reflects their targets too; the orphan target trips NoSuchTableError and aborts the startup migration, surfacing in the GUI as the misleading "Server could not be contacted". None of the migrations use the FK-target tables -- each operates only on the explicitly requested table(s). Pass resolve_fks=False at all 14 meta.reflect() call sites across the 12 migration files so reflection no longer cascades into broken FK targets. Behaviour is unchanged for healthy databases. Adds a 9.16 release note.
This commit is contained in:
1 parent
8afe14ec36
commit
303f6a2dd8
13 files changed
+20
-15
No files matched your search
@@ -37,3 +37,4 @@ Bug fixes
|
||||
| `Issue #9935 <https://github.com/pgadmin-org/pgadmin4/issues/9935>`_ - Fix "Illegal instruction" crash on startup of the Linux DEB and RPM packages on older x86_64 CPUs by pinning the psycopg C extension build to the x86-64 baseline.
|
||||
| `Issue #9936 <https://github.com/pgadmin-org/pgadmin4/issues/9936>`_ - Fix the AI panel silently falling back to the default provider when a custom LLM API URL or key file was set, and allow self-hosted LLM endpoints on any loopback port.
|
||||
| `Issue #9939 <https://github.com/pgadmin-org/pgadmin4/issues/9939>`_ - Fix saving a newly-added row in the Query Tool failing when the result set includes expression or alias columns that are not real columns of the underlying table.
|
||||
| `Issue #9976 <https://github.com/pgadmin-org/pgadmin4/issues/9976>`_ - Fix a startup migration crash (NoSuchTableError) when an old configuration database contains a stale foreign-key reference.
|
||||
@@ -125,7 +125,7 @@ def upgrade():
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('role',))
|
||||
meta.reflect(op.get_bind(), only=('role',), resolve_fks=False)
|
||||
role_table = sa.Table('role', meta)
|
||||
|
||||
op.execute(
|
||||
@@ -168,7 +168,7 @@ def upgrade():
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('version',))
|
||||
meta.reflect(op.get_bind(), only=('version',), resolve_fks=False)
|
||||
version_table = sa.Table('version', meta)
|
||||
|
||||
op.execute(
|
||||
|
||||
@@ -36,7 +36,7 @@ def upgrade():
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('role',))
|
||||
meta.reflect(op.get_bind(), only=('role',), resolve_fks=False)
|
||||
role_table = sa.Table('role', meta)
|
||||
|
||||
from pgadmin.tools.user_management.PgAdminPermissions import (
|
||||
|
||||
@@ -39,7 +39,9 @@ def upgrade():
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('server', 'sharedserver'))
|
||||
meta.reflect(op.get_bind(),
|
||||
only=('server', 'sharedserver'),
|
||||
resolve_fks=False)
|
||||
table = sa.Table('server', meta)
|
||||
op.execute(
|
||||
table.update().values(prepare_threshold=5)
|
||||
|
||||
@@ -37,7 +37,7 @@ def upgrade():
|
||||
# For internal email is a user name, so update the existing records.
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('user',))
|
||||
meta.reflect(op.get_bind(), only=('user',), resolve_fks=False)
|
||||
user_table = sa.Table('user', meta)
|
||||
|
||||
op.execute(
|
||||
|
||||
@@ -33,7 +33,7 @@ def upgrade():
|
||||
session.commit()
|
||||
|
||||
meta = sa.MetaData()
|
||||
meta.reflect(op.get_bind(), only=('user_macros',))
|
||||
meta.reflect(op.get_bind(), only=('user_macros',), resolve_fks=False)
|
||||
user_macros_table = sa.Table('user_macros', meta)
|
||||
|
||||
# Create a select statement
|
||||
@@ -61,7 +61,7 @@ def upgrade():
|
||||
sa.PrimaryKeyConstraint('id',))
|
||||
|
||||
# Reflect the new table structure
|
||||
meta.reflect(op.get_bind(), only=('user_macros',))
|
||||
meta.reflect(op.get_bind(), only=('user_macros',), resolve_fks=False)
|
||||
new_user_macros_table = sa.Table('user_macros', meta)
|
||||
|
||||
# Bulk insert the fetched data into the new user_macros table
|
||||
|
||||
@@ -27,7 +27,7 @@ depends_on = None
|
||||
def upgrade():
|
||||
# Get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
meta.reflect(op.get_bind(), only=('role',))
|
||||
meta.reflect(op.get_bind(), only=('role',), resolve_fks=False)
|
||||
role_table = sa.Table('role', meta)
|
||||
|
||||
# Get all roles with permissions
|
||||
|
||||
@@ -29,7 +29,7 @@ def upgrade():
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('server',))
|
||||
meta.reflect(op.get_bind(), only=('server',), resolve_fks=False)
|
||||
server_table = sa.Table('server', meta)
|
||||
op.execute(
|
||||
server_table.update().where(server_table.c.connect_timeout == 0 or
|
||||
|
||||
@@ -31,7 +31,7 @@ def upgrade():
|
||||
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('user',))
|
||||
meta.reflect(op.get_bind(), only=('user',), resolve_fks=False)
|
||||
user_table = sa.Table('user', meta)
|
||||
|
||||
op.execute(
|
||||
|
||||
@@ -27,7 +27,7 @@ depends_on = None
|
||||
def upgrade():
|
||||
# Add 'change_password' permission to all roles except 'Administrator'.
|
||||
meta = sa.MetaData()
|
||||
meta.reflect(op.get_bind(), only=('role', 'setting'))
|
||||
meta.reflect(op.get_bind(), only=('role', 'setting'), resolve_fks=False)
|
||||
role_table = sa.Table('role', meta)
|
||||
|
||||
perm = role_table.c.permissions
|
||||
|
||||
@@ -32,7 +32,7 @@ def upgrade():
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('server',))
|
||||
meta.reflect(op.get_bind(), only=('server',), resolve_fks=False)
|
||||
server_table = sa.Table('server', meta)
|
||||
|
||||
op.execute(
|
||||
|
||||
@@ -66,8 +66,10 @@ def upgrade():
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('user_preferences', 'module_preference',
|
||||
'preference_category', 'preferences'))
|
||||
meta.reflect(op.get_bind(),
|
||||
only=('user_preferences', 'module_preference',
|
||||
'preference_category', 'preferences'),
|
||||
resolve_fks=False)
|
||||
module_pref_table = sa.Table('module_preference', meta)
|
||||
|
||||
module_id = session.query(ModulePreference).filter_by(
|
||||
|
||||
@@ -53,7 +53,7 @@ def migrate_connection_params(table_name):
|
||||
|
||||
# define table representation
|
||||
meta = sa.MetaData()
|
||||
meta.reflect(op.get_bind(), only=(table_name,))
|
||||
meta.reflect(op.get_bind(), only=(table_name,), resolve_fks=False)
|
||||
server_table = sa.Table(table_name, meta)
|
||||
|
||||
# Create a select statement
|
||||
|
||||
Reference in new issue
Block a user