Files
paper-atlas/paper_atlas/db/backend.py
codex-bot 6fa59c4d26
Metadata integrity checks / metadata (push) Successful in 1m9s
Audit public decisions against PostgreSQL and recheck imports
2026-11-07 16:01:27 +08:00

51 lines
2.2 KiB
Python

"""Prevent legacy writers from diverging after an explicit PostgreSQL cutover."""
from pathlib import Path
def database_arguments(parser):
target = parser.add_mutually_exclusive_group(required=True)
target.add_argument('--db', help='Writable SQLite sample; never the frozen production backup')
target.add_argument('--pg-service', help='Protected libpq service for the published PostgreSQL dataset')
parser.add_argument('--pg-schema', help='Optional schema; otherwise use the configured search_path')
def open_store(db=None, *, pg_service=None, pg_schema=None):
if bool(db) == bool(pg_service) or (pg_schema and not pg_service):
raise ValueError('Choose exactly one of SQLite db or PostgreSQL service; schema requires PostgreSQL')
if pg_service:
from paper_atlas.postgres.writer import PostgresStore
return PostgresStore(pg_service, pg_schema)
from paper_atlas.db.store import Store
return Store(db)
def open_read_connection(db=None, *, pg_service=None, pg_schema=None):
if bool(db) == bool(pg_service) or (pg_schema and not pg_service):
raise ValueError('Choose exactly one of SQLite db or PostgreSQL service; schema requires PostgreSQL')
if pg_service:
from paper_atlas.postgres.client import ReadConnection
return ReadConnection(pg_service, pg_schema)
import sqlite3
path = Path(db).resolve()
if not path.is_file():
raise ValueError('Existing database required for read-only audit')
connection = sqlite3.connect(path.as_uri() + '?mode=ro', uri=True)
try:
connection.execute('BEGIN')
except BaseException:
connection.close()
raise
return connection
def inserted_id(connection, sql, params=()):
if getattr(connection, 'postgres', False):
return connection.execute(sql + ' RETURNING id', params).fetchone()[0]
return connection.execute(sql, params).lastrowid
def require_sqlite_writable(path):
marker = Path(str(Path(path).resolve()) + '.postgresql-cutover.json')
if marker.exists():
raise RuntimeError('This SQLite source was cut over to PostgreSQL; use the configured PostgreSQL database. Marker: ' + str(marker))