SeaQL / SeaQL/sea-orm

Per-backend column type overrides, e.g. json on mysql / jsonb on postgres

Open
#3,205 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
9.9k
Forks
734
Avg merge
6h 36m
Merged PRs (30d)
8

Description

Motivation

Column types are not portable across databases, and today SeaORM/sea-query can only express a single fixed column type per column. Two concrete consequences:

  • The common "JSON" column needs json on mysql and jsonb on postgres. There is no single column definition that produces the native right type on both; you either pick one or work around it outside the entity.
  • Types that only some databases have (tinyint, longblob, postgres interval, ...) force either a custom ColumnType::Custom("...") string that is wrong on every other backend, or a bigger portable type. Long-standing issues #426 (interval), #631 (longblob), #213 (DATE) and the newer composite/domain type requests (#2895, #2863) all sit around this gap.

Proposed Solutions

I'd like to start a discussion on a per-backend column type override, roughly:

ColumnDef::new(Column::Payload)
    .string() // abstract fallback for backends without an override
    .per_backend(|backend| match backend {
        Backend::MySql => ColumnType::Json,
        Backend::Postgres => ColumnType::JsonB,
        _ => ColumnType::String(None),
    })

(or any equivalent shape — a map from backend to ColumnType, an extension of ColumnType::Custom, or derivable helpers; the ergonomics are for maintainers to steer).

The semantics that have proven themselves in other ORMs: the backend-specific type wins on that backend, other backends fall back to the abstract type, and columns without overrides render exactly as today.

  • ent (Go) has field.String("s").SchemaType(map[string]string{dialect.MySQL: "varchar(255)", dialect.Postgres: "text"}) as a built-in
  • SQLAlchemy has String(255).with_variant(VARCHAR(255, charset="utf8"), "mysql")
  • gorm recently merged dialect-qualified type tags (go-gorm/gorm#7867)

Happy to collaborate on a design and implementation if maintainers think this fits sea-query/SeaORM's direction.

Additional Information

The same need shows up across ecosystems; the ent and SQLAlchemy links above are the closest prior art. No behavior would change for existing entities — the fallback path is the current rendering.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue names ColumnDef, ColumnType, and Backend as the entry points; start by tracing their existing column rendering and fallback behavior. Once maintainers agree on the API, implement backend-specific precedence without changing columns that have no override, and verify MySQL, PostgreSQL, and fallback rendering.

Written by the indexing model from the issue text.

Assessment

Tech stack
mysql, postgresql, rust
Domain
backend-api-design, databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.