Skip to main content

rjango is a tool that automatically generates up and down migration files for rust sqlx

Project description

Rjango


rjango is a tool that automatically generates up and down migration files for rust sqlx

Dependency


  • Python >= 3.10,<4

Advantage


  • Convenient: Automatically generate up and down migration files for Rust SQLx
  • Only development: Although Rjango depends on the Python environment and the Django framework, it is only used during development. Upon release, there is no need to depend on Rjango, and there is also no runtime overhead
  • Bidirectional: Rjango can not only convert Models into SQL TABLEs, but it can also reverse-engineer existing SQL TABLEs back into Models.
  • Multi-database support: Sqlite、Postgre、Mysql

Document


Quick Start


create new project

cargo new rjango_example
code rjango_example

create python virtual environment

rjango_example$ python -m venv venv
rjango_example$ source venv/bin/activate
rjango_example$ python --version
Python 3.10.11

install rjango

rjango_example$ pip install rjango

create .env file and set DATABASE_URL

rjango_example$ cat .env
DATABASE_URL=sqlite:////home/path/to/rjango_example/example.sqlite

rjango init

rjango_example$ rjango init --example

A migrations folder with example Model files will be created.

rjango_example$ tree migrations/
migrations/
├── __init__.py
├── migrations
│   └── __init__.py
└── models
    ├── author.py
    ├── book.py
    ├── __init__.py
    ├── reader.py
    └── relations.py

rjango add

rjango_example$ rjango add

generate up and down migration files for Rust SQLx

rjango_example$ tree migrations/
migrations/
├── 0001_created20250126.down.sql  # new
├── 0001_created20250126.up.sql    # new
├── __init__.py
├── migrations
│   ├── 0001_created20250126.py    # new   └── __init__.py
└── models
    ├── author.py
    ├── book.py
    ├── __init__.py
    ├── reader.py
    └── relations.py
rjango_example$ cat migrations/0001_created20250126.up.sql 
--
-- Create model Author
--
CREATE TABLE "example_author" ("author_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(64) NOT NULL UNIQUE);
--
-- Create model Reader
--
CREATE TABLE "example_reader" ("reader_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(64) NOT NULL UNIQUE);
--
-- Create model Book
--
CREATE TABLE "example_book" ("book_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(128) NOT NULL UNIQUE, "price" real NOT NULL, "description" text DEFAULT '' NULL, CONSTRAINT "example_book_check" CHECK ("price" >= 0.0));
--
-- Create model BookAuthorRelation
--
CREATE TABLE "example_book_author_relation" ("book_author_relation_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "publish_datetime" datetime NOT NULL, "author_id" bigint NOT NULL REFERENCES "example_author" ("author_id") DEFERRABLE INITIALLY DEFERRED, "book_id" bigint NOT NULL REFERENCES "example_book" ("book_id") DEFERRABLE INITIALLY DEFERRED);
--
-- Create model BookReaderRelation
--
CREATE TABLE "example_book_reader_relation" ("book_reader_relation_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "viewed_datetime" datetime NOT NULL, "book_id" bigint NOT NULL REFERENCES "example_book" ("book_id") DEFERRABLE INITIALLY DEFERRED, "reader_id" bigint NOT NULL REFERENCES "example_reader" ("reader_id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "example_book_author_relation_author_id_85d41095" ON "example_book_author_relation" ("author_id");
CREATE INDEX "example_book_author_relation_book_id_7d9100b8" ON "example_book_author_relation" ("book_id");
CREATE INDEX "example_book_reader_relation_book_id_3d79974d" ON "example_book_reader_relation" ("book_id");
CREATE INDEX "example_book_reader_relation_reader_id_646686e1" ON "example_book_reader_relation" ("reader_id");
rjango_example$ cat migrations/0001_created20250126.down.sql 
--
-- Create model BookReaderRelation
--
DROP TABLE "example_book_reader_relation";
--
-- Create model BookAuthorRelation
--
DROP TABLE "example_book_author_relation";
--
-- Create model Book
--
DROP TABLE "example_book";
--
-- Create model Reader
--
DROP TABLE "example_reader";
--
-- Create model Author
--

sqlx migrate run

rjango_example$ sqlx migrate run
Applied 1/migrate created20250126 (2.030776ms)

rjango_example$ tree -L 1 .
.
├── Cargo.lock
├── Cargo.toml
├── example.sqlite   # new
├── migrations
├── src
├── target
└── venv

change model

change migrations/models/book.py

# -*- coding:utf-8 -*-
from django.db import models


class Book(models.Model):
    """
    Book
    """
    book_id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=512, unique=True, db_index=True) # max_length=128 change max_length=512
    price = models.FloatField()
    description = models.TextField(null=True, db_default='')
    viewed_numbers = models.IntegerField(null=True, db_default=0) # add viewed_numbers

    class Meta:
        """
        table config
        """
        db_table = 'example_book'
        constraints = [
            models.CheckConstraint(name='example_book_check', condition=models.Q(price__gte=0)),
        ]

redo rjango add

rjango_example$ rjango add
rjango_example$ tree migrations/
migrations/
├── 0001_created20250126.down.sql
├── 0001_created20250126.up.sql
├── 0002_created20250126.down.sql     # new
├── 0002_created20250126.up.sql       # new
├── __init__.py
├── migrations
│   ├── 0001_created20250126.py
│   ├── 0002_created20250126.py       # new   └── __init__.py
└── models
    ├── author.py
    ├── book.py
    ├── __init__.py
    ├── reader.py
    └── relations.py
rjango_example$ cat migrations/0002_created20250126.up.sql 
--
-- Add field viewed_numbers to book
--
CREATE TABLE "new__example_book" ("viewed_numbers" integer DEFAULT 0 NULL, "book_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(128) NOT NULL UNIQUE, "price" real NOT NULL, "description" text DEFAULT '' NULL, CONSTRAINT "example_book_check" CHECK ("price" >= 0.0));
INSERT INTO "new__example_book" ("book_id", "name", "price", "description") SELECT "book_id", "name", "price", "description" FROM "example_book";
DROP TABLE "example_book";
ALTER TABLE "new__example_book" RENAME TO "example_book";
--
-- Alter field name on book
--
CREATE TABLE "new__example_book" ("book_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "price" real NOT NULL, "description" text DEFAULT '' NULL, "viewed_numbers" integer DEFAULT 0 NULL, "name" varchar(512) NOT NULL UNIQUE, CONSTRAINT "example_book_check" CHECK ("price" >= 0.0));
INSERT INTO "new__example_book" ("book_id", "price", "description", "viewed_numbers", "name") SELECT "book_id", "price", "description", "viewed_numbers", "name" FROM "example_book";
DROP TABLE "example_book";
ALTER TABLE "new__example_book" RENAME TO "example_book";
rjango_example$ cat migrations/0002_created20250126.down.sql 
--
-- Alter field name on book
--
CREATE TABLE "new__example_book" ("name" varchar(128) NOT NULL UNIQUE, "book_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "price" real NOT NULL, "description" text DEFAULT '' NULL, "viewed_numbers" integer DEFAULT 0 NULL, CONSTRAINT "example_book_check" CHECK ("price" >= 0.0));
INSERT INTO "new__example_book" ("book_id", "price", "description", "viewed_numbers", "name") SELECT "book_id", "price", "description", "viewed_numbers", "name" FROM "example_book";
DROP TABLE "example_book";
ALTER TABLE "new__example_book" RENAME TO "example_book";
--
-- Add field viewed_numbers to book
--
ALTER TABLE "example_book" DROP COLUMN "viewed_numbers";

redo sqlx migrate run

rjango_example$ sqlx migrate run
Applied 2/migrate created20250126 (3.570937ms)

sqlx migrate revert

rjango_example$ sqlx migrate revert --target-version 1
Applied 2/revert created20250126 (2.743494ms)
Skipped 1/revert created20250126 (0ns)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rjango-0.5.0.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rjango-0.5.0-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

File details

Details for the file rjango-0.5.0.tar.gz.

File metadata

  • Download URL: rjango-0.5.0.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.10.11 Linux/5.15.0-119-generic

File hashes

Hashes for rjango-0.5.0.tar.gz
Algorithm Hash digest
SHA256 6c115319d9ad30faab5834a1de91a3da19458f2958aee716cb15e1b62f156cf0
MD5 72ecfbd017de259c280a9527b356ed29
BLAKE2b-256 2d36af0329f60538c71273ca2d31f7a58b11c79be808eaa0c5210ffb44767048

See more details on using hashes here.

File details

Details for the file rjango-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: rjango-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 18.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.10.11 Linux/5.15.0-119-generic

File hashes

Hashes for rjango-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d8a9a009e737805123521888f4c9d3935a11780d25301fbc2b9eae2af3fad82f
MD5 c4a10d44e0b3c03ce34e4b40a902a0e9
BLAKE2b-256 c5aab833b9ed5f4e1654dbd11799eec4e5926e02de4d6bc5d066f0f8166f425d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page