SeaSchema

🌿 SQL schema management suite

[![crate](https://img.shields.io/crates/v/sea-schema.svg)](https://crates.io/crates/sea-schema) [![docs](https://docs.rs/sea-schema/badge.svg)](https://docs.rs/sea-schema) [![build status](https://github.com/SeaQL/sea-schema/actions/workflows/rust.yml/badge.svg)](https://github.com/SeaQL/sea-schema/actions/workflows/rust.yml)

About

SeaSchema is a library to help you manage database schema for MySQL, Postgres and SQLite. It provides a suite of tools, including schema definition, discovery and migration.

Architecture

The crate is divided into different modules:

JSON de/serialize on type definitions can be enabled with with-serde.

Schema Discovery

Take the MySQL Sakila Sample Database as example, given the following table:

``SQL CREATE TABLE film_actor ( actor_id SMALLINT UNSIGNED NOT NULL, film_id SMALLINT UNSIGNED NOT NULL, last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (actor_id,film_id), KEY idx_fk_film_id (filmid`), CONSTRAINT fkfilmactoractor FOREIGN KEY (actorid) REFERENCES actor (actorid) ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT fkfilmactorfilm FOREIGN KEY (filmid) REFERENCES film (film_id) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

```

The discovered schema result:

rust TableDef { info: TableInfo { name: "film_actor", engine: InnoDb, auto_increment: None, char_set: Utf8Mb4, collation: Utf8Mb40900AiCi, comment: "", }, columns: [ ColumnInfo { name: "actor_id", col_type: SmallInt( NumericAttr { maximum: None, decimal: None, unsigned: Some( true, ), zero_fill: None, }, ), null: false, key: Primary, default: None, extra: ColumnExtra { auto_increment: false, on_update_current_timestamp: false, generated: false, default_generated: false, }, expression: None, comment: "", }, ColumnInfo { name: "film_id", col_type: SmallInt( NumericAttr { maximum: None, decimal: None, unsigned: Some( true, ), zero_fill: None, }, ), null: false, key: Primary, default: None, extra: ColumnExtra { auto_increment: false, on_update_current_timestamp: false, generated: false, default_generated: false, }, expression: None, comment: "", }, ColumnInfo { name: "last_update", col_type: Timestamp( TimeAttr { fractional: None, }, ), null: false, key: NotKey, default: Some( ColumnDefault { expr: "CURRENT_TIMESTAMP", }, ), extra: ColumnExtra { auto_increment: false, on_update_current_timestamp: true, generated: false, default_generated: true, }, expression: None, comment: "", }, ], indexes: [ IndexInfo { unique: false, name: "idx_fk_film_id", parts: [ IndexPart { column: "film_id", order: Ascending, sub_part: None, }, ], nullable: false, idx_type: BTree, comment: "", functional: false, }, IndexInfo { unique: true, name: "PRIMARY", parts: [ IndexPart { column: "actor_id", order: Ascending, sub_part: None, }, IndexPart { column: "film_id", order: Ascending, sub_part: None, }, ], nullable: false, idx_type: BTree, comment: "", functional: false, }, ], foreign_keys: [ ForeignKeyInfo { name: "fk_film_actor_actor", columns: [ "actor_id", ], referenced_table: "actor", referenced_columns: [ "actor_id", ], on_update: Cascade, on_delete: Restrict, }, ForeignKeyInfo { name: "fk_film_actor_film", columns: [ "film_id", ], referenced_table: "film", referenced_columns: [ "film_id", ], on_update: Cascade, on_delete: Restrict, }, ], }