Files
LangBot/tests/integration/persistence/fixtures/generate_schema_fixtures.py
T
RockChinQ 273b1ea3cf Merge master into dev/4.11.x and preserve plugin runner architecture
Reconcile migration branches without rewriting published revisions; retain additive Codex, monitoring, provider and platform fixes. Keep dynamic runner schemas and Host ownership, restore compatibility regressions, and preserve safe model-test error handling.
2026-09-16 08:13:07 +00:00

67 lines
2.6 KiB
Python

"""Reproduce immutable historical ORM DDL snapshots without a database."""
from __future__ import annotations
import importlib
import json
from pathlib import Path
import subprocess
import sys
import tempfile
import types
import sqlalchemy as sa
from langbot.pkg.utils import constants
ROOT = Path(__file__).resolve().parents[4]
OUTPUT = Path(__file__).resolve().parent
SOURCE = 'src/langbot/pkg/entity/persistence/'
REFS = {
'baseline': ('9cd3544d59600fcb88700d05e4b211f59ac00445', '0001_baseline'),
'master': ('9b7ba0d64708496ace30a82866f6dbc185f089dc', '0024_passkey_credentials'),
'beta': ('03854b5d33d8b66fec4c86a77714e0e7512a31bd', '0025_bot_plugin_processors'),
}
def git(*args: str) -> str:
return subprocess.check_output(['git', *args], cwd=ROOT, text=True)
def generate() -> None:
# Only the baseline module's initial_metadata seed list reads this removed
# constant. It does not affect any table, column, constraint or generated DDL.
constants.required_database_version = 25
for name, (commit, revision) in REFS.items():
paths = git('ls-tree', '-r', '--name-only', commit, SOURCE).splitlines()
with tempfile.TemporaryDirectory(prefix='langbot-historical-schema-') as directory:
package = Path(directory)
for path in paths:
if path.endswith('.py'):
(package / Path(path).name).write_text(git('show', f'{commit}:{path}'))
# Keep ...utils imports working but give each snapshot its own Base.
package_name = f'langbot.pkg.entity.historical_{name}'
module = types.ModuleType(package_name)
module.__path__ = [directory]
sys.modules[package_name] = module
for path in sorted(package.glob('*.py')):
importlib.import_module(f'{package_name}.{path.stem}')
metadata = importlib.import_module(f'{package_name}.base').Base.metadata
dialects = {}
for dialect in ('sqlite', 'postgresql'):
statements = []
engine = sa.create_mock_engine(
f'{dialect}://',
lambda sql, *args, **kwargs: statements.append(str(sql.compile(dialect=engine.dialect)).strip()),
)
metadata.create_all(engine)
dialects[dialect] = statements
payload = {'source_commit': commit, 'source_path': SOURCE, 'revision': revision, 'dialects': dialects}
(OUTPUT / f'{name}_schema.json').write_text(json.dumps(payload, indent=2) + '\n')
print(f'{name}: {commit}, {len(metadata.tables)} historical ORM tables')
if __name__ == '__main__':
generate()