74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
"""Проверка состояния миграции 028_matching_tables.sql на прод tradein-postgres."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import psycopg
|
|
|
|
dsn = os.environ["DATABASE_URL"].replace("postgresql+psycopg://", "postgresql://")
|
|
conn = psycopg.connect(dsn)
|
|
cur = conn.cursor()
|
|
|
|
EXPECTED_COLUMNS = [
|
|
("houses", "address_fingerprint"),
|
|
("listings", "canonical"),
|
|
("listings", "merged_into"),
|
|
]
|
|
EXPECTED_INDEXES = [
|
|
"houses_addr_fp_idx",
|
|
"listings_merged_into_idx",
|
|
"house_sources_house_idx",
|
|
"house_sources_low_conf_idx",
|
|
"listing_sources_listing_idx",
|
|
"listing_sources_low_conf_idx",
|
|
"listing_sources_scraped_idx",
|
|
"haa_house_idx",
|
|
"haa_fingerprint_idx",
|
|
]
|
|
EXPECTED_TABLES = ["house_sources", "listing_sources", "house_address_aliases"]
|
|
|
|
print("=== Columns ===")
|
|
for tbl, col in EXPECTED_COLUMNS:
|
|
cur.execute(
|
|
"SELECT 1 FROM information_schema.columns WHERE table_name=%s AND column_name=%s",
|
|
(tbl, col),
|
|
)
|
|
status = "✓" if cur.fetchone() else "✗ MISSING"
|
|
print(f" {tbl}.{col:<25} {status}")
|
|
|
|
print("\n=== Tables ===")
|
|
for tbl in EXPECTED_TABLES:
|
|
cur.execute(
|
|
"SELECT 1 FROM information_schema.tables WHERE table_name=%s AND table_schema='public'",
|
|
(tbl,),
|
|
)
|
|
status = "✓" if cur.fetchone() else "✗ MISSING"
|
|
print(f" {tbl:<30} {status}")
|
|
|
|
print("\n=== Indexes ===")
|
|
for idx in EXPECTED_INDEXES:
|
|
cur.execute(
|
|
"SELECT 1 FROM pg_indexes WHERE indexname=%s",
|
|
(idx,),
|
|
)
|
|
status = "✓" if cur.fetchone() else "✗ MISSING"
|
|
print(f" {idx:<35} {status}")
|
|
|
|
# Проверим есть ли активные транзакции/locks от deploy которые ещё висят
|
|
print("\n=== Active transactions (locks on relevant tables) ===")
|
|
cur.execute(
|
|
"""
|
|
SELECT pid, usename, application_name, state, wait_event_type, wait_event,
|
|
query_start, substring(query, 1, 80) AS query_head
|
|
FROM pg_stat_activity
|
|
WHERE state IS DISTINCT FROM 'idle'
|
|
AND pid != pg_backend_pid()
|
|
ORDER BY query_start NULLS LAST
|
|
"""
|
|
)
|
|
rows = cur.fetchall()
|
|
if not rows:
|
|
print(" (none — clean)")
|
|
else:
|
|
for r in rows:
|
|
print(f" pid={r[0]} user={r[1]} app={r[2]} state={r[3]} wait={r[4]}/{r[5]} started={r[6]}")
|
|
print(f" query: {r[7]!r}")
|