Set up a project
You’ll create a console app that connects to PostgreSQL, applies its first migration and inserts and reads a row. The same layout works for a server app.
Prerequisites
Section titled “Prerequisites”- Dart SDK 3.3 or newer.
- PostgreSQL 13 or newer you can reach, or Docker to run one locally.
1. Create the project and add the package
Section titled “1. Create the project and add the package”dart create -t console blogcd blogdart pub add gisila_ormgisila_orm brings package:postgres with it. Add it explicitly as well if
you’ll use its types directly (TransactionSettings, Connection):
dart pub add postgres2. Start PostgreSQL
Section titled “2. Start PostgreSQL”docker-compose.yml:
services: db: image: postgres:16-alpine ports: - "5432:5432" environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: blogdocker compose up -d3. Configure the connection
Section titled “3. Configure the connection”Create database.yaml in the project root for local development:
default: mainconnections: main: host: localhost port: 5432 database: blog username: postgres password: postgres ssl_mode: disableIn deployed environments set DATABASE_URL instead; it takes precedence over
the file. Add database.yaml to .gitignore if it will ever hold real
credentials.
4. Write a schema
Section titled “4. Write a schema”lib/models/blog.gisila.yaml:
Author: columns: name: { type: varchar, is_null: false } email: { type: varchar, is_null: false, is_unique: true, allow_blank: false } created_at: { type: timestamp, is_null: false, default: now }5. Generate code and the first migration
Section titled “5. Generate code and the first migration”dart run gisila_orm:generateThis writes lib/models/blog.gisila.g.dart (the Author model, AuthorTable,
authors()), the full-schema SQL, lib/models/migrations/<millis>_initial_schema.up.sql
and .gisila/schema_snapshots/project.gisila.yaml. Commit all of them.
6. Apply the migration
Section titled “6. Apply the migration”dart run gisila_orm:migrate upDATABASE_URL not set — using database.yaml. Set DATABASE_URL for panel/production deploys.Applied 1 migration(s) in batch 1: - 1730000000000_initial_schema7. Query from Dart
Section titled “7. Query from Dart”bin/blog.dart:
import 'package:blog/models/blog.gisila.g.dart';import 'package:gisila_orm/gisila.dart';
Future<void> main() async { final db = await Database.connect(await DatabaseConfig.fromEnvironment()); try { await db.ping(); final ctx = db.context();
final ada = await authors() .insert({'name': 'Ada Lovelace', 'email': 'ada@example.com'}) .onConflictDoUpdate(['email']) .one(ctx); print('author #${ada.id} created at ${ada.createdAt}');
final all = await authors().orderBy(AuthorTable.name).all(ctx); print(all.map((a) => a.email).toList()); } finally { await db.close(); }}The import uses your package name (blog) because the generated file lives
under lib/.
Verify it works
Section titled “Verify it works”dart run bin/blog.dartauthor #1 created at 2026-11-01 10:00:00.000Z[ada@example.com]Run it twice: the upsert keeps one row, so the id stays 1.
Next steps
Section titled “Next steps”- Define a schema with relations, enums and indexes.
- Run migrations as the schema changes.
- CRUD operations.
- Use with the gisila framework.