caspian-db 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. caspian_db-0.0.1/AGENTS.md +22 -0
  2. caspian_db-0.0.1/LICENSE +9 -0
  3. caspian_db-0.0.1/MANIFEST.in +2 -0
  4. caspian_db-0.0.1/PKG-INFO +162 -0
  5. caspian_db-0.0.1/PORTING.md +25 -0
  6. caspian_db-0.0.1/README.md +130 -0
  7. caspian_db-0.0.1/pyproject.toml +50 -0
  8. caspian_db-0.0.1/setup.cfg +4 -0
  9. caspian_db-0.0.1/src/caspian_db/__init__.py +3 -0
  10. caspian_db-0.0.1/src/caspian_db/__main__.py +3 -0
  11. caspian_db-0.0.1/src/caspian_db/cli.py +95 -0
  12. caspian_db-0.0.1/src/caspian_db/emitter.py +513 -0
  13. caspian_db-0.0.1/src/caspian_db/generate.py +106 -0
  14. caspian_db-0.0.1/src/caspian_db/migrations.py +188 -0
  15. caspian_db-0.0.1/src/caspian_db/psl.py +281 -0
  16. caspian_db-0.0.1/src/caspian_db/schema.py +110 -0
  17. caspian_db-0.0.1/src/caspian_db/template_support.py +136 -0
  18. caspian_db-0.0.1/src/caspian_db/templates.py +7797 -0
  19. caspian_db-0.0.1/src/caspian_db.egg-info/PKG-INFO +162 -0
  20. caspian_db-0.0.1/src/caspian_db.egg-info/SOURCES.txt +28 -0
  21. caspian_db-0.0.1/src/caspian_db.egg-info/dependency_links.txt +1 -0
  22. caspian_db-0.0.1/src/caspian_db.egg-info/entry_points.txt +2 -0
  23. caspian_db-0.0.1/src/caspian_db.egg-info/requires.txt +14 -0
  24. caspian_db-0.0.1/src/caspian_db.egg-info/top_level.txt +1 -0
  25. caspian_db-0.0.1/tests/fixtures/app.json +283 -0
  26. caspian_db-0.0.1/tests/fixtures/features-parity.json +17 -0
  27. caspian_db-0.0.1/tests/fixtures/features.json +420 -0
  28. caspian_db-0.0.1/tests/fixtures/legacy-parity.json +17 -0
  29. caspian_db-0.0.1/tests/test_generate.py +189 -0
  30. caspian_db-0.0.1/tests/test_native_workflow.py +196 -0
@@ -0,0 +1,22 @@
1
+ # Caspian DB agent instructions
2
+
3
+ Read README.md and PORTING.md before editing. This installable package is separate
4
+ from the sibling app's installed Caspian runtime; never vendor or edit that runtime
5
+ as part of database-tooling migration.
6
+
7
+ Edit src/caspian_db, not a consuming app's generated client. Preserve imports,
8
+ delegates, typed inputs, and errors unless a deliberate API migration is requested.
9
+ Use native --schema generation; --metadata is legacy input compatibility only.
10
+
11
+ Generation/validation must never connect to a database, invoke Node/subprocesses,
12
+ launch watchers, or run implicit migrations/seeds. migrate create only creates a
13
+ reviewable SQL template. Deploy and seed are intentional data operations within
14
+ the user's authorized scope. Preserve migration files, checksums, and ledger data;
15
+ do not auto-baseline, reset, resolve failures, or replay existing migrations.
16
+
17
+ Run uv run python -m pytest tests -q, uv run ruff check src tests, and uv build.
18
+ Database tests use disposable SQLite databases or session-local PostgreSQL temporary
19
+ tables with a verified temporary search_path. Never use app tables as test fixtures.
20
+
21
+ Document unsupported schema grammar and migration/provider features candidly.
22
+ MySQL client generation does not imply MySQL migration deployment support.
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 The Steel Ninja Code - Jefferson Abraham Omier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,2 @@
1
+ include README.md PORTING.md AGENTS.md LICENSE
2
+ recursive-include tests *.py *.json
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.4
2
+ Name: caspian-db
3
+ Version: 0.0.1
4
+ Summary: Caspian's native Python client generator for Prisma schema metadata
5
+ Author: Jefferson Abraham Omier
6
+ License-Expression: MIT
7
+ Keywords: prisma,orm,database,codegen,migrations,caspian
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Classifier: Topic :: Database
15
+ Classifier: Topic :: Software Development :: Code Generators
16
+ Classifier: Framework :: AsyncIO
17
+ Requires-Python: >=3.14
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: python-dotenv>=1.2.3
21
+ Requires-Dist: sqlparse>=0.6.0
22
+ Provides-Extra: postgresql
23
+ Requires-Dist: asyncpg>=0.31; extra == "postgresql"
24
+ Requires-Dist: python-dotenv>=1; extra == "postgresql"
25
+ Provides-Extra: mysql
26
+ Requires-Dist: aiomysql>=0.3; extra == "mysql"
27
+ Requires-Dist: python-dotenv>=1; extra == "mysql"
28
+ Provides-Extra: sqlite
29
+ Requires-Dist: aiosqlite>=0.22; extra == "sqlite"
30
+ Requires-Dist: python-dotenv>=1; extra == "sqlite"
31
+ Dynamic: license-file
32
+
33
+ # Caspian DB
34
+
35
+ Native Python tooling for Caspian's Prisma schema, generated client, reviewed SQL
36
+ migrations, and app-owned Python seed. Distribution: `caspian-db`; import:
37
+ `caspian_db`; command: `caspian-db`. Python 3.14 or newer. No Node/npm subprocess.
38
+
39
+ ## Install
40
+
41
+ From PyPI, with the driver extra for your provider (`postgresql`, `mysql`, or
42
+ `sqlite`):
43
+
44
+ ```powershell
45
+ uv add "caspian-db[postgresql]"
46
+ # or: pip install "caspian-db[postgresql]"
47
+ ```
48
+
49
+ Then, from your Caspian application:
50
+
51
+ ```powershell
52
+ uv run caspian-db validate
53
+ uv run caspian-db generate
54
+ uv run caspian-db generate --check
55
+ ```
56
+
57
+ By default the schema is read from `prisma/` and the client is generated into
58
+ `src/lib/prisma`. Use `--schema` and `--output` to choose other locations:
59
+
60
+ ```powershell
61
+ uv run caspian-db generate --schema path/to/schema.prisma --output path/to/client
62
+ ```
63
+
64
+ `uv run python -m caspian_db` provides the same interface. Commands use the current
65
+ project directory; pass explicit paths when running elsewhere. `uv build` produces
66
+ an installable wheel and source distribution.
67
+
68
+ ## Schema and client
69
+
70
+ `--schema` accepts a `.prisma` file or a directory containing multiple `.prisma`
71
+ files. Default: `prisma`. Generation reads source directly; no generated metadata
72
+ manifest is needed. `--metadata` remains an explicit legacy compatibility input.
73
+
74
+ Supported client providers: PostgreSQL, MySQL, and SQLite. The strict schema reader
75
+ supports models/enums, mappings, optional/list fields, defaults, updatedAt, named
76
+ relations and inverse relations, compound primary/unique keys, and native-type
77
+ annotations. It rejects unsupported declarations and attributes instead of
78
+ silently dropping models. Supported scalar types: String, Int, Boolean, DateTime,
79
+ Float, BigInt, Decimal, Json. Multi-schema, views, composite types, ignore/fulltext,
80
+ expression/sorted compound keys, and Bytes/Unsupported types are not implemented.
81
+ Mapped names currently accept letters/digits/underscores/spaces/periods/hyphens.
82
+ This is a Caspian schema reader, not the complete Prisma language validator.
83
+
84
+ Generated files remain `models.py`, `db.py`, and `__init__.py`. App imports such as
85
+ `from src.lib.prisma import prisma` and existing delegate/query APIs are preserved.
86
+ `validate` checks schema and generated syntax; `generate --check` checks the client
87
+ against source. Neither compares a live database's structure to the schema.
88
+ Native type, index, and foreign-key action annotations describe database structure;
89
+ the client generator does not apply them. Express those changes in migration SQL.
90
+
91
+ All outputs compile before publication. A process lock serializes writers; staged
92
+ per-file replacements roll back on write errors. Authored files and file symlinks
93
+ are refused. Unchanged output keeps timestamps. Publication is not a crash-atomic
94
+ directory swap: stop Python before generation and regenerate after an interrupted
95
+ publication. No watchers, automatic reloads, seeds, or migrations run implicitly.
96
+
97
+ ## Reviewed SQL migrations
98
+
99
+ ```powershell
100
+ uv run caspian-db migrate create --name add_profile
101
+ # Edit and review the created prisma/migrations/<timestamp>_add_profile/migration.sql.
102
+ uv run caspian-db migrate status
103
+ uv run caspian-db migrate deploy
104
+ ```
105
+
106
+ `create` writes a template only. It does not derive a schema diff, connect to the
107
+ DB, or apply SQL. `status` uses a read-only transaction and reports pending SQL.
108
+ `deploy` is an explicit database write operation. Review its target and SQL first.
109
+ Commands accept `--schema` and `--migrations`. DATABASE_URL loads from the current
110
+ project's `.env` unless already set in the environment; credentials are not printed.
111
+
112
+ Deployment supports PostgreSQL and SQLite. Provider mismatch, changed/missing
113
+ applied migrations, non-prefix history, and unresolved failures stop deployment.
114
+ Existing `_prisma_migrations` records and original SQL file checksums are reused;
115
+ there is no automatic baseline or replay. Local `migration_lock.toml` is preserved.
116
+ PostgreSQL uses a transaction advisory lock; SQLite uses BEGIN IMMEDIATE. Pending
117
+ SQL and ledger entries commit together as one batch; a failure rolls back the batch.
118
+ Transaction controls and nontransactional operations such as CONCURRENTLY are
119
+ refused. SQL is trusted, reviewed project source, not uploaded/untrusted input.
120
+
121
+ Failed existing Prisma migrations need deliberate recovery; this package does not
122
+ provide an automatic resolve/reset command. Recovery uses a reviewed follow-up
123
+ migration or explicit DBA intervention. It does not generate down migrations,
124
+ perform schema drift detection, db push/introspection, or provide Prisma Studio.
125
+ MySQL client generation remains supported; MySQL migration deployment is not
126
+ implemented because its DDL transaction semantics need a separate runner.
127
+
128
+ ## Python seed
129
+
130
+ ```powershell
131
+ uv run caspian-db seed
132
+ uv run caspian-db seed --demo-user
133
+ ```
134
+
135
+ `seed` loads `prisma/seed.py` (override with `--file`) and awaits its `run(demo_user=...)`
136
+ function. The consuming app owns the seed policy. Never execute seeds implicitly.
137
+ The migrated Caspian app seed creates missing Admin/User roles in a transaction,
138
+ keeps existing records unchanged, and never deletes users or resets counters.
139
+ The optional demo user requires CASPIAN_SEED_DEMO_PASSWORD, hashes it, and does not
140
+ replace an existing user's credentials. No built-in destructive reset is supplied.
141
+
142
+ ## Dependencies and verification
143
+
144
+ Generation/schema reading uses the standard library. Migration SQL classification
145
+ uses sqlparse; environment loading uses python-dotenv. Generated clients need the
146
+ provider driver; extras: `caspian-db[postgresql]`, `[mysql]`, `[sqlite]`. The app
147
+ already installs its drivers. For exact ID default formats, install `cuid2`,
148
+ `nanoid`, or `python-ulid`; the preserved client otherwise falls back to UUID.
149
+
150
+ ```powershell
151
+ uv sync --group dev
152
+ uv run python -m pytest tests -q
153
+ uv run ruff check src tests
154
+ uv build
155
+ ```
156
+
157
+ Tests include independent legacy-output AST parity for three client providers,
158
+ native multi-file parsing, no-Node execution, preservation on failure, concurrency,
159
+ and SQLite migration history/rollback plus generated-client CRUD. The consuming
160
+ app has an opt-in PostgreSQL test using only session-local temporary tables to
161
+ verify deployment, history, rollback, additive seeding, and client operations.
162
+ MySQL execution is still unverified. Read `PORTING.md` and `AGENTS.md` before edits.
@@ -0,0 +1,25 @@
1
+ # Generator and database-tooling migration
2
+
3
+ Original source: prisma-client-python-dev/src/generate-python-orm.ts, MIT licensed.
4
+ LICENSE preserves the upstream attribution. The pure emitter was ported to Python;
5
+ emitter.py contains generation logic, templates.py readable source fragments, and
6
+ template_support.py collection/string helpers preserving old output semantics.
7
+ One-time TypeScript AST extraction is not a build/runtime dependency. Fixture
8
+ hashes independently captured the old renderer without running its prebuild.
9
+
10
+ schema.py normalizes metadata. psl.py reads supported Prisma schema declarations
11
+ directly, validates named/implicit inverse relations, and rejects unsupported input.
12
+ generate.py validates all outputs and controls locking/publication. migrations.py
13
+ runs reviewed transactional SQL using existing Prisma history. cli.py exposes
14
+ separate generation, validation, migration, and Python-seed commands.
15
+
16
+ The current PostgreSQL application's full authoring/generation/migration/seed path
17
+ requires no Prisma Node CLI, TypeScript config, Node client, or metadata bridge.
18
+ The generated Python API stays compatible. SQLite deployment is also covered.
19
+
20
+ This package is not a reimplementation of all official Prisma CLI features:
21
+ automatic schema-to-SQL diffing, introspection/db push, Studio, automatic failure
22
+ resolution/down migrations, full Prisma grammar, and MySQL DDL deployment are
23
+ not supplied. Migration SQL is authored/reviewed explicitly. MySQL runtime tests
24
+ and gradual refactoring of numbered template fragments remain improvement work.
25
+ The legacy client's optional ID libraries still fall back to UUID when absent.
@@ -0,0 +1,130 @@
1
+ # Caspian DB
2
+
3
+ Native Python tooling for Caspian's Prisma schema, generated client, reviewed SQL
4
+ migrations, and app-owned Python seed. Distribution: `caspian-db`; import:
5
+ `caspian_db`; command: `caspian-db`. Python 3.14 or newer. No Node/npm subprocess.
6
+
7
+ ## Install
8
+
9
+ From PyPI, with the driver extra for your provider (`postgresql`, `mysql`, or
10
+ `sqlite`):
11
+
12
+ ```powershell
13
+ uv add "caspian-db[postgresql]"
14
+ # or: pip install "caspian-db[postgresql]"
15
+ ```
16
+
17
+ Then, from your Caspian application:
18
+
19
+ ```powershell
20
+ uv run caspian-db validate
21
+ uv run caspian-db generate
22
+ uv run caspian-db generate --check
23
+ ```
24
+
25
+ By default the schema is read from `prisma/` and the client is generated into
26
+ `src/lib/prisma`. Use `--schema` and `--output` to choose other locations:
27
+
28
+ ```powershell
29
+ uv run caspian-db generate --schema path/to/schema.prisma --output path/to/client
30
+ ```
31
+
32
+ `uv run python -m caspian_db` provides the same interface. Commands use the current
33
+ project directory; pass explicit paths when running elsewhere. `uv build` produces
34
+ an installable wheel and source distribution.
35
+
36
+ ## Schema and client
37
+
38
+ `--schema` accepts a `.prisma` file or a directory containing multiple `.prisma`
39
+ files. Default: `prisma`. Generation reads source directly; no generated metadata
40
+ manifest is needed. `--metadata` remains an explicit legacy compatibility input.
41
+
42
+ Supported client providers: PostgreSQL, MySQL, and SQLite. The strict schema reader
43
+ supports models/enums, mappings, optional/list fields, defaults, updatedAt, named
44
+ relations and inverse relations, compound primary/unique keys, and native-type
45
+ annotations. It rejects unsupported declarations and attributes instead of
46
+ silently dropping models. Supported scalar types: String, Int, Boolean, DateTime,
47
+ Float, BigInt, Decimal, Json. Multi-schema, views, composite types, ignore/fulltext,
48
+ expression/sorted compound keys, and Bytes/Unsupported types are not implemented.
49
+ Mapped names currently accept letters/digits/underscores/spaces/periods/hyphens.
50
+ This is a Caspian schema reader, not the complete Prisma language validator.
51
+
52
+ Generated files remain `models.py`, `db.py`, and `__init__.py`. App imports such as
53
+ `from src.lib.prisma import prisma` and existing delegate/query APIs are preserved.
54
+ `validate` checks schema and generated syntax; `generate --check` checks the client
55
+ against source. Neither compares a live database's structure to the schema.
56
+ Native type, index, and foreign-key action annotations describe database structure;
57
+ the client generator does not apply them. Express those changes in migration SQL.
58
+
59
+ All outputs compile before publication. A process lock serializes writers; staged
60
+ per-file replacements roll back on write errors. Authored files and file symlinks
61
+ are refused. Unchanged output keeps timestamps. Publication is not a crash-atomic
62
+ directory swap: stop Python before generation and regenerate after an interrupted
63
+ publication. No watchers, automatic reloads, seeds, or migrations run implicitly.
64
+
65
+ ## Reviewed SQL migrations
66
+
67
+ ```powershell
68
+ uv run caspian-db migrate create --name add_profile
69
+ # Edit and review the created prisma/migrations/<timestamp>_add_profile/migration.sql.
70
+ uv run caspian-db migrate status
71
+ uv run caspian-db migrate deploy
72
+ ```
73
+
74
+ `create` writes a template only. It does not derive a schema diff, connect to the
75
+ DB, or apply SQL. `status` uses a read-only transaction and reports pending SQL.
76
+ `deploy` is an explicit database write operation. Review its target and SQL first.
77
+ Commands accept `--schema` and `--migrations`. DATABASE_URL loads from the current
78
+ project's `.env` unless already set in the environment; credentials are not printed.
79
+
80
+ Deployment supports PostgreSQL and SQLite. Provider mismatch, changed/missing
81
+ applied migrations, non-prefix history, and unresolved failures stop deployment.
82
+ Existing `_prisma_migrations` records and original SQL file checksums are reused;
83
+ there is no automatic baseline or replay. Local `migration_lock.toml` is preserved.
84
+ PostgreSQL uses a transaction advisory lock; SQLite uses BEGIN IMMEDIATE. Pending
85
+ SQL and ledger entries commit together as one batch; a failure rolls back the batch.
86
+ Transaction controls and nontransactional operations such as CONCURRENTLY are
87
+ refused. SQL is trusted, reviewed project source, not uploaded/untrusted input.
88
+
89
+ Failed existing Prisma migrations need deliberate recovery; this package does not
90
+ provide an automatic resolve/reset command. Recovery uses a reviewed follow-up
91
+ migration or explicit DBA intervention. It does not generate down migrations,
92
+ perform schema drift detection, db push/introspection, or provide Prisma Studio.
93
+ MySQL client generation remains supported; MySQL migration deployment is not
94
+ implemented because its DDL transaction semantics need a separate runner.
95
+
96
+ ## Python seed
97
+
98
+ ```powershell
99
+ uv run caspian-db seed
100
+ uv run caspian-db seed --demo-user
101
+ ```
102
+
103
+ `seed` loads `prisma/seed.py` (override with `--file`) and awaits its `run(demo_user=...)`
104
+ function. The consuming app owns the seed policy. Never execute seeds implicitly.
105
+ The migrated Caspian app seed creates missing Admin/User roles in a transaction,
106
+ keeps existing records unchanged, and never deletes users or resets counters.
107
+ The optional demo user requires CASPIAN_SEED_DEMO_PASSWORD, hashes it, and does not
108
+ replace an existing user's credentials. No built-in destructive reset is supplied.
109
+
110
+ ## Dependencies and verification
111
+
112
+ Generation/schema reading uses the standard library. Migration SQL classification
113
+ uses sqlparse; environment loading uses python-dotenv. Generated clients need the
114
+ provider driver; extras: `caspian-db[postgresql]`, `[mysql]`, `[sqlite]`. The app
115
+ already installs its drivers. For exact ID default formats, install `cuid2`,
116
+ `nanoid`, or `python-ulid`; the preserved client otherwise falls back to UUID.
117
+
118
+ ```powershell
119
+ uv sync --group dev
120
+ uv run python -m pytest tests -q
121
+ uv run ruff check src tests
122
+ uv build
123
+ ```
124
+
125
+ Tests include independent legacy-output AST parity for three client providers,
126
+ native multi-file parsing, no-Node execution, preservation on failure, concurrency,
127
+ and SQLite migration history/rollback plus generated-client CRUD. The consuming
128
+ app has an opt-in PostgreSQL test using only session-local temporary tables to
129
+ verify deployment, history, rollback, additive seeding, and client operations.
130
+ MySQL execution is still unverified. Read `PORTING.md` and `AGENTS.md` before edits.
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "caspian-db"
7
+ version = "0.0.1"
8
+ description = "Caspian's native Python client generator for Prisma schema metadata"
9
+ readme = "README.md"
10
+ requires-python = ">=3.14"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Jefferson Abraham Omier" }]
14
+ keywords = ["prisma", "orm", "database", "codegen", "migrations", "caspian"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3.14",
22
+ "Topic :: Database",
23
+ "Topic :: Software Development :: Code Generators",
24
+ "Framework :: AsyncIO",
25
+ ]
26
+ dependencies = [
27
+ "python-dotenv>=1.2.3",
28
+ "sqlparse>=0.6.0",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ postgresql = ["asyncpg>=0.31", "python-dotenv>=1"]
33
+ mysql = ["aiomysql>=0.3", "python-dotenv>=1"]
34
+ sqlite = ["aiosqlite>=0.22", "python-dotenv>=1"]
35
+
36
+ [project.scripts]
37
+ caspian-db = "caspian_db.cli:main"
38
+
39
+ [dependency-groups]
40
+ dev = ["pytest>=9", "ruff>=0.16", "aiosqlite>=0.22", "python-dotenv>=1"]
41
+
42
+ [tool.setuptools.packages.find]
43
+ where = ["src"]
44
+
45
+ [tool.ruff]
46
+ line-length = 100
47
+
48
+ [tool.ruff.lint]
49
+ select = ["E", "F", "W"]
50
+ ignore = ["E501"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """Caspian database code generation. Generation does not connect to a database."""
2
+
3
+ __version__ = "0.0.1"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,95 @@
1
+ """Explicit code generation commands; no implicit schema/seed database changes."""
2
+
3
+ import argparse
4
+ import asyncio
5
+ import os
6
+ import runpy
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from .generate import generate, render
11
+ from .psl import read_schema
12
+
13
+
14
+ def main(argv=None):
15
+ parser = argparse.ArgumentParser(description=__doc__)
16
+ sub = parser.add_subparsers(dest="command", required=True)
17
+ for name in ("generate", "validate"):
18
+ command = sub.add_parser(name)
19
+ inputs = command.add_mutually_exclusive_group()
20
+ inputs.add_argument("--metadata", type=Path, help="Legacy parsed metadata JSON")
21
+ inputs.add_argument(
22
+ "--schema",
23
+ type=Path,
24
+ default=Path("prisma"),
25
+ help=".prisma file or schema directory (default: prisma)",
26
+ )
27
+ if name == "generate":
28
+ command.add_argument(
29
+ "--output",
30
+ type=Path,
31
+ default=Path("src/lib/prisma"),
32
+ help="generated client directory (default: src/lib/prisma)",
33
+ )
34
+ command.add_argument(
35
+ "--check", action="store_true", help="check freshness without writes"
36
+ )
37
+ migrate = sub.add_parser("migrate", help="Reviewed SQL migration workflow")
38
+ actions = migrate.add_subparsers(dest="action", required=True)
39
+ for name in ("status", "deploy", "create"):
40
+ action = actions.add_parser(name)
41
+ action.add_argument("--schema", type=Path, default=Path("prisma"))
42
+ action.add_argument("--migrations", type=Path, default=Path("prisma/migrations"))
43
+ if name == "create":
44
+ action.add_argument("--name", required=True)
45
+ seed = sub.add_parser("seed", help="Execute the app's Python seed (writes data)")
46
+ seed.add_argument("--file", type=Path, default=Path("prisma/seed.py"))
47
+ seed.add_argument("--demo-user", action="store_true")
48
+ args = parser.parse_args(argv)
49
+ try:
50
+ if args.command == "validate":
51
+ render(args.metadata or args.schema)
52
+ print("Schema metadata and generated Python syntax are valid.")
53
+ elif args.command == "generate":
54
+ changed = generate(args.metadata or args.schema, args.output, check=args.check)
55
+ print("Generated " + ", ".join(changed) if changed else "Client is current.")
56
+ elif args.command == "migrate":
57
+ from .migrations import create_migration, postgres_run, sqlite_run
58
+
59
+ provider = read_schema(args.schema)["datasources"][0]["provider"]
60
+ if provider not in {"postgresql", "sqlite"}:
61
+ raise ValueError(
62
+ "Native migration deployment currently supports PostgreSQL and SQLite only"
63
+ )
64
+ if args.action == "create":
65
+ print(create_migration(args.migrations, args.name, provider))
66
+ else:
67
+ from dotenv import load_dotenv
68
+
69
+ load_dotenv(Path.cwd() / ".env")
70
+ url = os.environ.get("DATABASE_URL")
71
+ if not url:
72
+ raise ValueError("DATABASE_URL is required")
73
+ deploy = args.action == "deploy"
74
+ pending = (
75
+ asyncio.run(postgres_run(args.migrations, url, deploy))
76
+ if provider == "postgresql"
77
+ else sqlite_run(args.migrations, url, deploy)
78
+ )
79
+ print(("Applied: " if deploy else "Pending: ") + (", ".join(pending) or "none"))
80
+ else:
81
+ from dotenv import load_dotenv
82
+
83
+ load_dotenv(Path.cwd() / ".env")
84
+ sys.path.insert(0, str(Path.cwd()))
85
+ namespace = runpy.run_path(str(args.file))
86
+ asyncio.run(namespace["run"](demo_user=args.demo_user))
87
+ print("Seed completed.")
88
+ return 0
89
+ except Exception as exc:
90
+ print(f"caspian-db: {exc}", file=sys.stderr)
91
+ return 1
92
+
93
+
94
+ if __name__ == "__main__":
95
+ raise SystemExit(main())