Skip to content

Repository files navigation

Dart ORM

A Dart 3.13 ORM with ordinary immutable Dart models, typed relationships, composable selections, and explicit database sessions. Declare a class once; generated queries return that class directly.

The implementation has separate real SQLite, PostgreSQL, MySQL, MariaDB, Chrome, Flutter Web and Android verification records. See current progress, capability limits and design acceptance for which revision and scenarios each record covers.

One package, independent modules and database adapters, no runtime reflection. This branch is unrelated to earlier ORM implementations.

For a new application with the orm dependency:

dart run orm init --database sqlite
dart run orm migrate create 0001_initial
# Review the generated Dart migration.
dart run orm migrate apply

Choose postgres, mysql or mariadb to initialize that engine's own history. The project CLI creates typed Dart configuration, a nominal model, the generated client and a static migration registry. Initialization and generation never connect or apply DDL.

Module Independent use
values.dart Codecs and precise domain values
driver.dart, drivers/*.dart Parameterized SQL contracts and database adapters
runtime.dart Raw SQL sessions, transactions and cursor lifetimes
schema_model.dart Physical table metadata
sql.dart Typed query construction and offline SQL compilation
orm.dart Typed execution and query subscriptions over SqlDatabase
migrate.dart Schema inspection, plans and immutable migration execution
schema.dart, generate.dart, cli.dart Declaration, static generation and project tools

These are separate Dart libraries with directed dependencies. Use a raw driver without the ORM, compile a typed query without a connection, or run migrations without current application models. See API boundaries.

The SQLite entry point works on native platforms and the web, with background execution and the same generated query API. Flutter Web bundles its worker/WASM resources automatically; plain Dart uses dart run orm web-assets. The native Flutter example verifies Android APK upgrades, background SQLite, persistence and commit-driven query subscriptions.

dart pub get
dart run orm generate example/schema.dart
dart run example/main.dart
dart run example/queries.dart
dart test

For incremental generation, enable orm:orm for explicit schema roots in build.yaml and run dart run build_runner watch. See generation and builds for setup, dependency tracking and reproducible generation measurements.

Declare data once in schema.dart:

final class User({
  @Id.generated() required final int id,
  @Unique() required final String email,
  required final String? nickname,
});
final users = entity<User>();

Import the generated client and a driver. The client exports User and the driver exports the portable query API:

import 'package:orm/migrate.dart';
import 'package:orm/sqlite.dart';
import 'schema.orm.dart';

Future<void> main() async {
  final db = await sqlite(const SqliteOptions.memory());
  try {
    await Migrator(db.sql).apply([
      Migration.create('0001_initial', appSchema, dialect: .sqlite),
    ]);
    final User user = await db.users.create(email: 'seven@example.com');
    await db.users.byId(user.id).patch(nickname: .set('Seven'));
    final List<String> emails = await db.users.select((u) => u.email).get();
    print(emails);
  } finally {
    await db.close();
  }
}

For PostgreSQL, import postgres.dart and use postgres(PostgresOptions(url: url)); TLS certificate verification is the default. MySQL and MariaDB use mysql.dart / mariadb.dart with await mysql(MysqlOptions(url: url)) / await mariadb(MariadbOptions(url: url)). Each backend has its own transaction options and migration history. Choose the engine when initializing that history, and keep its reviewed Dart migrations and static registry in version control. A connection change does not translate history.

The example above creates a temporary in-memory schema. The persistent migration entrypoint fixes SQLite: run dart run example/migrate.dart check, then set ORM_SQLITE_PATH before apply or verify. A PostgreSQL project creates its own PostgreSQL history and connection entrypoint. See migrations and resumable backfills.

Read API and mental model for imports, current declarations versus historical schemas, prepared versus executed operations, selection nullability, and transaction ownership. Inside a transaction, build every query from tx; subqueries, CTEs and UNION operands must share that same view.

For an existing database, import a model declaration, review its report, generate the client, and baseline the current schema without copying existing rows.

Declare row CHECK constraints with explicit SQL and optional backend overrides; generated snapshots support catalog verification, import and reviewed constraint migrations.

Use client defaults for typed Dart value factories and SQL defaults for database-generated values, with explicit omission/value/default inputs. Declare computed columns for database expressions with typed read-only results, explicit stored/virtual modes and reviewed migrations.

Model many-to-many memberships with an explicit association table, typed business fields and per-parent pagination. Run dart run example/teams/main.dart to see its selected records and SQL counts.

Use query.inspect() for SQL templates, selected columns, joins and conditional relation batches without connecting. Optional onAcquire, onQuery and onDecode callbacks measure execution phases. See plans and observations.

For complex SQL files, generate named queries with typed Record parameters/results, native database structure checks and the same query composition, transaction and streaming APIs.

Use query.stream(batchSize: 128) with await for to read through a database cursor. Reads and mutations accept ExecutionOptions for connection acquisition limits, statement deadlines and cancellation. See streaming and execution for connection lifetime, batch sizing, transaction-wide deadlines and failure outcomes.

The runtime cost report compares the same driver, SQL and result shapes across SQLite, local PostgreSQL and a controlled TCP delay. It separates normal timing from acquisition probes, live heap and allocation traces.

Single relationships use JOINs when declared keys prove uniqueness; collections load in parameter-aware batches. Both support typed nested selections. See relationship strategies for composite keys, per-parent pagination and explicit .join/.batch choices.

Domain IDs, custom classes, record values and enums retain their types in generated APIs. Declare public const codecs with @UseCodec; use @EnumValue for stable stored labels. See types and JSON for codec validation, nullable values and the distinction between SQL NULL and JSON null.

Use query.watch() for typed snapshots after relevant committed writes. Transactions merge notifications; rollbacks do not notify. See query subscriptions for relation dependencies, pause/cancellation, and explicit notifications for raw SQL or external writers.

The query cookbook runs filters, joined ordering, relation counts, grouped CTEs, windows, subqueries and cursor pagination. See query usage for the API and PostgreSQL example configuration.

Combine scalar or .row projections with union/unionAll, then map the result to a Record or DTO. Sets support typed exported columns, CTEs, streaming and subscriptions. See queries for scope, nullability and codec requirements.

Set ORM_TEST_POSTGRES to a disposable local PostgreSQL database to include PostgreSQL integration tests. The tests create and drop their own test tables. Set ORM_TEST_MYSQL and ORM_TEST_MARIADB for their live suites; migration recovery tests additionally create and drop isolated databases. Use dedicated test servers and credentials with the necessary privileges. Their TLS setting defaults to verifyFull; self-signed local fixtures can explicitly set ORM_TEST_MYSQL_TLS=require / ORM_TEST_MARIADB_TLS=require.

About

Prisma Client Dart is an auto-generated type-safe ORM. It uses Prisma Engine as the data access layer and is as consistent as possible with the Prisma Client JS/TS APIs.

Topics

Resources

Stars

478 stars

Watchers

8 watching

Forks

Releases

Used by

Contributors

Languages