Auto Migrations and Async Integration#86
Auto Migrations and Async Integration#86emiliano-gandini-outeda wants to merge 40 commits intojetbase-hq:mainfrom
Conversation
|
I would love to see this PR merged, as the only thing stopping me from using FastAPI instead of Django is alembic. I would also like to implement this tool in this amazing boilerplate |
|
I removed |
|
Thanks for the PR! This is a large change and I have some thoughts, so I'll set aside some time soon to do a proper review |
|
Cool! Feel free to AMA. |
After creating migrations, if you dont migrate and create another migrations, they would be duplicate.
The function only checked ASYNC env var, ignoring async_mode=True in env.py. Also fixed get_config call to include sqlalchemy_url in keys to avoid TypeError.
|
Hey! thanks a lot for putting the time into this and for the detailed PR! I can see the amount of work that went into it, and I appreciate you exploring new directions for Jetbase. I get that you hate SQL and automatic SQLAlchemy ORM migrations would be a great path to go down for in that case. That said, while I really appreciate the approach, I don’t think this PR is the right fit for Jetbase, since one of the project’s core goals is to by SQL only and intentionally not have anything to do with ORMs. One of the main reasons that Jetbase was created as an alternative to Alembic was to be SQL first and specifically avoid any ORM interaction. I started out using SQLAlchemy ORM a while back for building apps, but as things grew more complex it became friction instead of helpful. Plain SQL was often clearer and more efficient. I've laid out some reasons below: – Complex queries were easier to write and more efficient in plain SQL Jetbase was built with inspiration from other business focused database migration tools in the Java ecosystem such as Liquibase and Flyway, which are plain SQL only. But nothing like this existed for the Python ecosystem. So until I built Jetbase, I would have to jump into the Java ecosystem just for migrations when building out Python projects. This is intentionally different from ORM-centric migration tools such as Alembic or Prisma migrations, which were built and maintained alongside their respective ORMs. At the moment, Jetbase does have a SQLAlchemy dependency, but it is used only for database connections. That was a choice to move faster early on. Long-term, the goal is to remove SQLAlchemy entirely, as outlined in this issue: I think your approach could work really well as a fork or companion project that builds ORM-driven migration generation on top of Jetbase’s features that Alembic doesn't have, such as schema drift detection and a linear migration history. On the async portion of the PR: the current description mentions multiple sources of truth for async configuration, but That said, some of the other ideas you mentioned such as running Jetbase commands from any directory and improving logging are definitely aligned with the project direction and worth exploring further. Thanks again for the contribution! |
I hate alembic.
But I hate SQL more.
So this tools fits me to an extent, so I decided to do some upgrades to make it more useful (to me, at least).
TLDR: Django
make-migrationsandmigratecommands integrated to JetBase.What This PR Does
This PR adds two main features to Jetbase:
ASYNC=trueorASYNC=falseIt also lets you run Jetbase commands from anywhere in your project, not just the
jetbase/folder.Quick Example
Before (manual SQL):
After (auto-generate):
Feature 1: Auto-Generate Migrations
How It Works
Finding Your Models
Jetbase looks for models in three ways:
Option A: Put models in
models/folder (recommended)Option B: Environment variable
Option C: In env.py
What It Detects
CREATE TABLE/DROP TABLEALTER TABLE ADD COLUMN/DROP COLUMNCREATE INDEX/DROP INDEXADD CONSTRAINT/DROP CONSTRAINTExample Output
Input model:
Generated migration:
Feature 2: Simpler Async/Sync Mode
The Old Way (Confusing)
Before, async mode could come from:
ASYNCenvironment variableasync_modeinenv.pyasync_modein configIf these disagreed, things broke.
The New Way (Simple)
Just use one environment variable:
Values That Work
URL Handling
In sync mode, Jetbase automatically removes async suffixes:
postgresql+asyncpg://...postgresql://...sqlite+aiosqlite:///db.dbsqlite:///db.dbSo this works in both modes:
Feature 3: Run From Anywhere
Before: You had to be in the
jetbase/folderAfter: Run from anywhere in your project
Breaking Changes
1. Remove
async_modefrom configBefore:
After:
2. New config option
If you use auto-migrations, add this to
env.py:File Changes Summary
New Files (13 total)
jetbase/commands/make_migrations.pyjetbase/engine/model_discovery.pyjetbase/engine/schema_introspection.pyjetbase/engine/schema_diff.pyjetbase/engine/sql_generator.pyjetbase/engine/jetbase_locator.pytests/unit/commands/test_make_migrations.pyModified Files (24 total)
jetbase/cli/main.pyjetbase/config.pyjetbase/database/connection.pyREADME.mddocs/Migration Steps
If You Used Async Mode
async_mode = True/Falsefromenv.pyASYNC=trueorASYNC=falsein your environmentIf You Want Auto-Migrations
Add model paths to
env.py:Or set
JETBASE_MODELS=./models.pyenvironment variableOr put models in
models/folder as now Jetbase autodetects models inmodel/andmodels/folder.Testing
All 232 tests pass.
New tests cover:
Run tests:
Documentation
Updated files:
README.md- Complete rewritedocs/commands/make-migrations.md- New command docsdocs/getting-started.md- Added auto-migrations guidedocs/database-connections.md- Added async/sync modesdocs/index.md- Updated with new features