Releases: jubilee-works/sea-orm-spanner
v0.1.0
v0.1.0 — Initial Release
Google Cloud Spanner backend for SeaORM. Write Spanner applications using SeaORM's familiar ActiveRecord pattern.
Crates
| Crate | Version | Description |
|---|---|---|
sea-orm-spanner |
0.1.0 | SeaORM integration via ProxyDatabaseTrait |
sea-query-spanner |
0.1.0 | Spanner SQL dialect for SeaQuery (@p1, @p2 parameters, backtick quoting) |
sea-orm-migration-spanner |
0.1.0 | Migration CLI & library with Spanner-native DDL builders |
Highlights
Full SeaORM CRUD Support
Standard SeaORM operations work out of the box — insert, find, update, delete, find_by_id, and query builders. Uses MySQL backend internally because Spanner doesn't support RETURNING clause.
Connection Management
SpannerDatabase::connect()— auto-detects environment: emulator (viaSPANNER_EMULATOR_HOST) or GCP (via Application Default Credentials)connect_with_config()— full control with customClientConfigconnect_with_emulator()/connect_with_emulator_host()— explicit emulator connectionconnect_or_create_with_emulator()— auto-provisions instance and database on emulator for testing- TLS — automatic rustls crypto provider setup for GCP connections
Spanner Type System
Comprehensive mapping from SeaORM types to Spanner's native types:
| Spanner Type | Rust Type | Feature Flag |
|---|---|---|
INT64 |
i64 |
— |
FLOAT64 |
f64 |
— |
STRING |
String |
— |
BOOL |
bool |
— |
BYTES |
Vec<u8> |
— |
TIMESTAMP |
DateTimeUtc |
with-chrono |
DATE |
Date |
with-chrono |
UUID |
Uuid |
with-uuid |
JSON |
serde_json::Value |
with-json |
NUMERIC |
rust_decimal::Decimal |
with-rust_decimal |
ARRAY<T> |
Vec<T> |
with-array |
Migration System (sea-orm-migration-spanner)
Full migration CLI with Spanner-native DDL support:
- Commands:
init,generate,up,down,status,fresh,reset SpannerTableBuilder— fluent API forCREATE TABLEwith support for interleaved tables, row deletion policies, generated columns, and default expressionsSpannerIndexBuilder—CREATE INDEXwith unique, null-filtered, storing, and interleave optionsSpannerAlterTable—ADD COLUMN,DROP COLUMN,ALTER COLUMN,ADD FOREIGN KEY,DROP CONSTRAINT- MySQL DDL auto-conversion — SeaQuery's MySQL DDL output is automatically translated to Spanner DDL (type mappings, syntax adjustments)
--env-fileflag — load different.envfiles per environment (e.g.,.env.stg,.env.prod)- Migration tracking — uses
seaql_migrationstable
DML Execution in Migrations (#25)
SchemaManager now holds a DatabaseConnection internally, enabling DML (INSERT, UPDATE, DELETE) alongside DDL within migrations:
get_connection()— returns&DatabaseConnectionfor full SeaORM query accessexecute_unprepared(sql)— execute raw DML statements directly
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager.create_table(/* ... */).await?;
// Seed data within the same migration
manager.execute_unprepared(
"INSERT INTO config (`key`, `value`) VALUES ('version', '1')"
).await?;
// Or use full SeaORM queries via get_connection()
let db = manager.get_connection();
db.execute_unprepared("UPDATE config SET `value` = '2' WHERE `key` = 'version'").await?;
Ok(())
}Breaking change:
SchemaManager::new()is nowasyncand returnsResult<Self, DbErr>.
DEFAULT Clause Support (#26)
The DDL converter now properly converts MySQL DEFAULT clauses to Spanner's DEFAULT (value) syntax instead of stripping them:
| MySQL | Spanner |
|---|---|
DEFAULT 'hello' |
DEFAULT ('hello') |
DEFAULT 0 |
DEFAULT (0) |
DEFAULT -1 |
DEFAULT (-1) |
DEFAULT 3.14 |
DEFAULT (3.14) |
DEFAULT NULL |
DEFAULT (NULL) |
DEFAULT TRUE |
DEFAULT (TRUE) |
DEFAULT CURRENT_TIMESTAMP |
DEFAULT (CURRENT_TIMESTAMP()) |
MySQL backslash escaping (\') is automatically normalized to Spanner's double-quote escaping ('').
SQL Query Builder (sea-query-spanner)
Translates SeaQuery AST into Spanner-compatible SQL:
- Parameter placeholders:
?→@p1, @p2, ... - Identifier quoting with backticks (auto-quotes identifiers containing hyphens or special characters)
- Full SeaQuery ColumnType → Spanner type mapping
Feature Flags
| Feature | Description |
|---|---|
with-chrono |
TIMESTAMP / DATE support via chrono |
with-uuid |
Native UUID type support |
with-json |
JSON column support |
with-rust_decimal |
NUMERIC support via rust_decimal |
with-array |
ARRAY<INT64>, ARRAY<FLOAT64>, ARRAY<STRING>, ARRAY<BOOL> |
macros |
SeaORM derive macros (DeriveEntityModel, etc.) |
runtime-tokio-native-tls |
Tokio + native-tls runtime |
runtime-tokio-rustls |
Tokio + rustls runtime |
All type features are enabled by default.
Dependencies
sea-orm2.0.0-rc.37 (proxy backend)sea-query1.0.0-rc.31gcloud-spanner1.7.0 (official Rust SDK)- Rust 1.80+ (bumped from 1.75 for
LazyLock)
Known Limitations
- Integer types: Spanner only has
INT64— usei64for all integer fields - Float types: Spanner only has
FLOAT64— usef64, notf32 - TIMESTAMP: Returns
DateTimeUtc(DateTime<Utc>) — notNaiveDateTime - BYTES vs STRING: Distinguished via base64 heuristics; empty byte arrays may be misread as strings
- JSON primitives: Numeric JSON values (
42,3.14) may be indistinguishable fromINT64/FLOAT64— wrap in objects - Empty arrays: Cannot be reliably read back due to SDK type information loss — use
NULLinstead - NUMERIC edge cases: Zero values may be misinterpreted when coexisting with STRING columns
License
MIT OR Apache-2.0