"""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))