formatting

This commit is contained in:
2026-02-07 21:26:10 -05:00
parent 435fcc3b2e
commit 9d16c96490
4 changed files with 117 additions and 98 deletions

View File

@@ -14,6 +14,7 @@ Usage examples:
- Disable notifications: ./migrate_sqlite_to_pg.py --no-notify
- Force re-import: ./migrate_sqlite_to_pg.py --force
"""
from __future__ import annotations
import argparse
@@ -120,7 +121,7 @@ def clean_row(row: tuple, columns: list[tuple[str, str]]) -> tuple:
def escape_copy_value(value, pg_type: str) -> str:
"""Escape a value for PostgreSQL COPY format (tab-separated).\n
"""Escape a value for PostgreSQL COPY format (tab-separated).\n
This is much faster than INSERT for bulk loading.
"""
if value is None:
@@ -153,7 +154,7 @@ def create_table(
pg_conn, table: str, columns: list[tuple[str, str]], unlogged: bool = True
) -> None:
"""Create a table in PostgreSQL based on SQLite schema.
Uses UNLOGGED tables by default for faster bulk import (no WAL writes).
"""
cur = pg_conn.cursor()
@@ -336,16 +337,16 @@ def create_database(db_name: str) -> None:
def terminate_connections(db_name: str, max_wait: int = 10) -> bool:
"""Terminate all connections to a database.
Returns True if all connections were terminated, False if some remain.
Won't fail on permission errors (e.g., can't terminate superuser connections).
"""
import time
conn = pg_connect("postgres")
conn.autocommit = True
cur = conn.cursor()
for attempt in range(max_wait):
# Check how many connections exist
cur.execute(
@@ -354,14 +355,14 @@ def terminate_connections(db_name: str, max_wait: int = 10) -> bool:
)
row = cur.fetchone()
count = int(row[0]) if row else 0
if count == 0:
cur.close()
conn.close()
return True
print(f" Terminating {count} connection(s) to {db_name}...")
# Try to terminate - ignore errors for connections we can't kill
try:
cur.execute(
@@ -376,10 +377,10 @@ def terminate_connections(db_name: str, max_wait: int = 10) -> bool:
)
except Exception as e:
print(f" Warning: {e}")
# Brief wait for connections to close
time.sleep(1)
# Final check
cur.execute(
"SELECT COUNT(*) FROM pg_stat_activity WHERE datname = %s AND pid <> pg_backend_pid();",
@@ -389,9 +390,11 @@ def terminate_connections(db_name: str, max_wait: int = 10) -> bool:
remaining = int(row[0]) if row else 0
cur.close()
conn.close()
if remaining > 0:
print(f" Warning: {remaining} connection(s) still active (may be superuser sessions)")
print(
f" Warning: {remaining} connection(s) still active (may be superuser sessions)"
)
return False
return True
@@ -421,12 +424,12 @@ def rename_database(old_name: str, new_name: str) -> None:
def drop_database(db_name: str) -> bool:
"""Drop a PostgreSQL database.
Returns True if dropped, False if failed (e.g., active connections).
"""
# First try to terminate connections
terminate_connections(db_name)
conn = pg_connect("postgres")
conn.autocommit = True
cur = conn.cursor()
@@ -666,9 +669,7 @@ Examples:
print(f"New dump available: {dump_date_str}")
if notify_enabled:
asyncio.run(
notify_new_dump_found(latest["filename"], dump_date_str)
)
asyncio.run(notify_new_dump_found(latest["filename"], dump_date_str))
# Download
print(f"\nDownloading {latest['filename']}...")