Files
group_fqcd_jr/tools/schema_fingerprint.py
T

37 lines
1.4 KiB
Python

"""Read-only structural fingerprints; no credentials or row contents in the report."""
import hashlib
import json
import sys
from pathlib import Path
from sqlalchemy import create_engine, text
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from app.core.config import get_settings
def fingerprint():
engine = create_engine(get_settings().mysql_dsn.replace("mysql+asyncmy", "mysql+pymysql"))
result = {}
with engine.connect() as connection:
names = connection.execute(text("""
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()
""")).scalars().all()
for name in sorted(names):
if name == "alembic_version":
continue
columns = connection.execute(text("""
SELECT COLUMN_NAME,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,EXTRA,
CHARACTER_SET_NAME,COLLATION_NAME,GENERATION_EXPRESSION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:name ORDER BY ORDINAL_POSITION
"""), {"name": name}).all()
canonical = json.dumps([list(row) for row in columns], ensure_ascii=False, default=str)
result[name] = hashlib.sha256(canonical.encode()).hexdigest()
engine.dispose()
return result
if __name__ == "__main__":
print(json.dumps(fingerprint(), indent=2, ensure_ascii=False))