Skip to content

Schema Definition ​

Define tables using Dart 3 Record syntax with the @PgTable annotation.

Schema File Location

Configure your schema file path in pubspec.yaml:

yaml
aim:
  database:
    schema: lib/schema  # default

See Code Generation for full setup.

Table Definition ​

dart
import 'package:aim_orm/aim_orm.dart';
import 'package:aim_orm_postgres/aim_orm_postgres.dart';
import 'package:aim_postgres/aim_postgres.dart';

part 'tables.g.dart';

@PgTable('users')
final users = (
  id: uuid('id').primaryKey(),
  name: varchar('name', length: 255),
  email: varchar('email', length: 255).unique(),
  createdAt: timestamp('created_at').withDefault(DateTime.now()),
);

Key points:

  • Use @PgTable('table_name') to specify the database table name
  • Define columns as Record fields
  • Add part 'filename.g.dart' for code generation

Column Types ​

Basic Types (aim_orm) ​

FunctionSQL TypeDart Type
integer(name)INTEGERint
varchar(name, length:)VARCHAR(n)String
text(name)TEXTString
timestamp(name)TIMESTAMPDateTime

DateTime values read back are always UTC (isUtc == true); call .toLocal() for display.

PostgreSQL Types (aim_orm_postgres) ​

FunctionPostgreSQL TypeDart Type
serial(name)SERIALint
uuid(name)UUIDString
jsonb<T>(name)JSONBT

Column Modifiers ​

Chain modifiers to add constraints:

dart
// Primary key
id: uuid('id').primaryKey(),

// Unique constraint
email: varchar('email', length: 255).unique(),

// Nullable
bio: text('bio').nullable(),

// Default value
createdAt: timestamp('created_at').withDefault(DateTime.now()),

// Timestamp with NOW() default
updatedAt: timestamp('updated_at').withDefaultNow(),

// Indexed (adds a plain index, not a uniqueness constraint)
email: varchar('email', length: 255).indexed(),

// Foreign key reference, with optional ON DELETE / ON UPDATE actions
userId: uuid('user_id').references(
  () => users.id,
  onDelete: OnDeleteAction.cascade,
  onUpdate: OnUpdateAction.restrict,
),

Available Modifiers ​

ModifierDescription
.primaryKey()Set as primary key
.unique()Add unique constraint
.nullable()Allow NULL values
.withDefault(value)Set default value (not on serial(): the sequence already provides one)
.withDefaultNow()Set default to NOW() (timestamp only)
.indexed()Add a database index on this column
.references(() => target, {onDelete, onUpdate})Add a foreign key reference to another table's column; onDelete/onUpdate take an OnDeleteAction/OnUpdateAction (cascade, setNull, restrict, setDefault)

Multiple Tables ​

Define multiple tables in the same file:

dart
part 'tables.g.dart';

@PgTable('users')
final users = (
  id: uuid('id').primaryKey(),
  name: varchar('name', length: 255),
  email: varchar('email', length: 255).unique(),
  createdAt: timestamp('created_at').withDefaultNow(),
);

@PgTable('posts')
final posts = (
  id: serial('id').primaryKey(),
  userId: uuid('user_id'),
  title: varchar('title', length: 255),
  content: text('content'),
  createdAt: timestamp('created_at').withDefaultNow(),
);

@PgTable('comments')
final comments = (
  id: serial('id').primaryKey(),
  postId: integer('post_id'),
  userId: uuid('user_id'),
  body: text('body'),
  createdAt: timestamp('created_at').withDefaultNow(),
);

Column Name Mapping ​

The first argument to column functions is the database column name:

dart
@PgTable('users')
final users = (
  // Dart field: createdAt
  // Database column: created_at
  createdAt: timestamp('created_at'),

  // Dart field: userId
  // Database column: user_id
  userId: uuid('user_id'),
);

Generated Types ​

After running dart run build_runner build, each table gets a Row type:

dart
// Generated from users table
typedef UsersRow = ({
  String id,
  String name,
  String email,
  DateTime createdAt,
});

// Generated from posts table
typedef PostsRow = ({
  int id,
  String userId,
  String title,
  String content,
  DateTime createdAt,
});

Next Steps ​

Released under the MIT License.