Repository navigation
feat(cli): v0.39.0 command line surreal-orm-lite (v0.39.0) - #382
Conversation
… codes The surreal-orm-lite console script and python -m surreal_orm_lite.cli, on argparse: the full ORM's nine commands and global options, SURREAL_* variables (option > environment > default, an empty variable unset), exit 2 for a missing namespace or database, 130 on Ctrl+C, a refusal inside a running event loop before the registry is touched, a stderr logging handler removed after main(), and the URL's userinfo scrubbed from stderr. The commands themselves follow in the next commits.
makemigrations --empty writes a file to fill in by hand; --no-from-db with --models imports the modules (the working directory put on sys.path when neither it nor "" is there), diffs every registered model of the connection against the migration files' state and lists the operations it wrote. sqlmigrate prints show_sql() for --line and --backwards, offline. The warning for the removals left out now names the --drop-missing flag too.
Each command registers its settings, resolves the connection class once and runs in one asyncio.run() that closes the connection in a finally. Failures are reported as '<Prefix> failed: <message>' on stderr (scrubbed, exit 1), Ctrl+C as 'Interrupted.' (exit 130). E2E tests on both server lines, over WebSocket and HTTP.
makemigrations diffs the models against the database's schema by default: the connection is configured once the models are found, and a failure to reach the database adds a hint towards --no-from-db (connection errors only). schemadiff prints the full ORM's report and refuses to compare with no registered model before configuring the connection.
inspectdb runs generate_models_from_db() on the command's connection: the source on stdout with one trailing newline, or written with -o (--no-overwrite refuses an existing file); --table limits the tables; failures are reported as 'Introspection failed: <message>', exit 1.
One asyncio.Runner per session; each line goes unchanged to query_raw() and every statement's outcome is shown in its own block, as the server line answers it (3.x and 2.x transaction envelopes, a missing table, parse errors from a server or the embedded engine). exit/quit, EOF and Ctrl+C at the prompt end with Goodbye! (exit 0); Ctrl+C during a query exits 130; a refused first connection is 'Shell failed: ...' (exit 1). The connection is closed once in every case and the banner drops the URL's user:password@.
… real entry point A surrealkv:// path keeps its data across makemigrations, migrate and status (AC-22); an ASYNC event migration is applied on 3.x and refused on 2.x with only the empty tracking table left (AC-24); the chain runs through python -m surreal_orm_lite.cli in a subprocess (AC-26).
README section 40 (install, connection options, commands, the SurrealQL shell, several databases, exit codes, security, server lines, differences from the full ORM's CLI), the 2.x/3.x and embedded-engine rows, the features, roadmap and comparison rows, and the two sentences that promised the CLI for v0.39.0 now point to section 40. tests/test_cli_docs.py pins all of it. The earlier doc tests follow the new text: section lists gain section 40, the roadmap and comparison rows, section 31's inspectdb clause and section 39's Limits phrase; test_migration_docs.py's link list of section 39 also gains the section 40 link (an unlisted dependency).
Runs the surreal-orm-lite command line in a subprocess from a temporary project: --help/--version, makemigrations, migrate, status, sqlmigrate, schemadiff with a model change, inspectdb, the SurrealQL shell with piped input, rollback and cleanup. Outputs saved from SurrealDB 3.x, free of ports, paths and version numbers.
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## main #382 +/- ##
==========================================
+ Coverage 98.49% 98.50% +0.01%
==========================================
Files 53 56 +3
Lines 17442 17843 +401
Branches 3143 3184 +41
==========================================
+ Hits 17179 17577 +398
- Misses 154 155 +1
- Partials 109 111 +2
🚀 New features to boost your workflow:
|
EulogySnowfall
left a comment
There was a problem hiding this comment.
Automated review — maintainer's agent team (round 1)
Reviewed the PR as it will be merged (head 6598059) against the v0.39.0 design: the nine commands, global options and SURREAL_* resolution, exit codes (0/1/2/130), connection lifecycle (one asyncio.run() per command, closed in a finally; one asyncio.Runner for the shell), credential scrubbing and --help without defaults, the [project.scripts] entry (checked in a built wheel: surreal_orm_lite/cli/* is packaged and entry_points.txt points at surreal_orm_lite.cli.commands:main), and the 2.x/3.x shell difference documented in README section 40 and the behaviour table.
Release: version 0.39.0 consistent in pyproject.toml, __init__.py, tests/test_v050.py and the uv.lock package line only; CHANGELOG.md ## [0.39.0]; SECURITY.md supports 0.39.x; docs/ROADMAP.md marks v0.39.0 done; the notebook is executed (15 code cells, sequential counts, no error output). Commits are the user's, no .github/ change. CI is green on both server lines and Python 3.11 to 3.15.
Verdict: no blocking findings. 0 blocking, 1 suggestion (inline).
| ) | ||
|
|
||
| try: | ||
| path = _run(generate, _configure(settings, args.command)) if from_db else asyncio.run(generate()) |
There was a problem hiding this comment.
[suggestion] In the default --from-db path, _configure() runs inside the try, so an add_connection() refusal (_ConfigureError) is caught by except Exception and reported as makemigrations failed: add_connection('default'): ... instead of Error: add_connection('default'): ..., which is what the design's error table prescribes for a refused configuration and what migrate, status, schemadiff, etc. print. Reproduced with python -m surreal_orm_lite.cli -n ns -d db --user= makemigrations --name x -m mymodels (exit 1 in both cases, only the text differs).
Suggested fix: resolve the manager before the try when from_db is set (e.g. manager = _configure(settings, args.command) if from_db else None), so main() reports the _ConfigureError like the other commands, and add the matching offline test next to the existing Error: add_connection('default') one.
|
Merged by the maintainer's automation: review approved, CI green, version 0.39.0 ready. |
Summary
Adds the
surreal-orm-litecommand line (v0.39.0): a console script andpython -m surreal_orm_lite.cliwith nine commands (shell,makemigrations,migrate,upgrade,rollback,status,sqlmigrate,schemadiff,inspectdb), built onargparsewith the full SurrealDB-ORM's options,SURREAL_*environment variables and output texts. Each command is a thin front end over the v0.38.0 migration system and the schema introspection; the CLI decides nothing about the schema.Closes #375
Changes
src/surreal_orm_lite/cli/(commands.py,__main__.py) and the[project.scripts]entry inpyproject.toml.--connectionpicks a named connection,--versionprints the version,sqlmigratetakes--backwards/--line,inspectdbtakes--table/--no-overwrite,makemigrationstakes--name,--models,--empty,--drop-missing,--from-db/--no-from-db.--helpnever shows the password and errors never carry the URL's credentials.shellruns each statement on its own (also from piped input); Ctrl+C during a query exits with 130 after closing the connection.makemigrations()logs for skipped removals now names--drop-missing.tests/test_cli.py(offline, E2E on both lines over WS and HTTP, embedded engine, real entry-point subprocess) andtests/test_cli_docs.py; the earlier README/ROADMAP doc tests follow the new section 40 and the released-roadmap state.CHANGELOG.md,SECURITY.md(supported0.39.x),docs/ROADMAP.md(v0.39.0 marked done, "Completed versions" block; prettier re-pads the tables, hence the wider diff), and the executed notebookexamples/v0.39.0_cli_entry_point.ipynb.SurrealDB 2.x vs 3.x
Every command runs on both lines and on the embedded engine. The one difference is the shell's layout for a transaction: on 3.x a
BEGIN ... COMMITblock shows one block per statement ([1/3]to[3/3]), on 2.x only the statements inside the transaction answer. README section 40 and the "ORM behaviour: SurrealDB 2.6.x vs 3.x" table record it.Validation
QA gate on 6056d98 (before the rebase onto
mainat 0.38.3 and the version bump),portes.sh completgreen in 34 min:src/andtests/typing_examples.py, pins, versions,uv.lock, commit identity.test_cli.py,test_cli_docs.py,test_migration_files.py,test_migration_docs.py): 509 passed each time on 3.x and on 2.x.surreal-orm-lite --help; 2.x full suite with seed 11 (15825 passed, 168 skipped); 3.x on Python 3.14 with seed 4242 (15899 passed, 94 skipped).mainat cc75646 (the 3.3.5 pin): no conflicts; 3.x with the retro container on 3.3.5: 15907 passed, 94 skipped; 2.x on Python 3.11: 15828 passed, 173 skipped (the extra skips are the multi-line tests that needSURREALDB_PORT_3X/_2X).After the rebase and the bump: lint, versions,
uv.lock, identity and the doc/ROADMAP/embedded/hybrid tests re-run green on both lines (1207 passed, 4 skipped); the last commit only touches the version files and the release docs.Version
0.38.3 -> 0.39.0 (new public API: a minor). No other open PR holds a version.