Run the store with PostgreSQL¶
This page uses a pure Dart application and the dorm_postgres_database engine.
The application supplies an opened Connection or Pool; the engine does
not open or close that object for you.
Add the engine package¶
From the Dart application directory, execute:
Add the PostgreSQL driver because the application creates and owns the
Connection or Pool:
The application imports postgres directly for connection setup. The dORM
engine barrel exports Engine, Filter, and Query, but does not re-export
all driver types.
Configure the connection¶
Read the PostgreSQL endpoint from the application configuration and open it
before constructing the generated Dorm:
final Connection connection = await Connection.open(
Endpoint(
host: host,
port: port,
database: database,
username: username,
password: password,
),
);
final Dorm<Query, OffsetPageRequest> dorm = Dorm(Engine(connection));
To use pooling, open a Pool instead. Connection and Pool both satisfy
the SessionExecutor boundary accepted by the engine.
Keep the executor open for as long as the generated repositories may issue operations. Close it from the application lifecycle after those operations are finished.
Create the tables¶
Create tables with PostgreSQL SQL before using the repositories. The package
does not infer migrations from generated schemas. Use PostgresMigrationAdapter with dorm_migrations for explicit, ordered SQL migrations.
For a generated model with a String identity and a String field, the table
contains a primary-key column and the mapped model columns. Foreign fields
must reference the corresponding target primary-key column when PostgreSQL
constraints are enabled.
For a database-generated identity, define the key column with PostgreSQL's
identity or sequence-backed syntax and annotate the model with
DatabaseGeneratedIdSpec. Do not include that column in the Data input. The
engine uses INSERT ... RETURNING to obtain the value before returning the
model.
Generate the model API¶
Declare the model source with part directives and run:
The generator writes the .dorm.dart and .g.dart parts from the annotated
source. Edit the annotated source and regenerate after changing fields,
relationships, or serialization declarations.
Execute CRUD, filters, and relationships¶
Use the generated repositories in the same way as other dORM engines:
final User user = await dorm.users.repository.put(
Creation.auto(
dependency: UserDependency(),
data: UserData(name: 'Ada'),
),
);
await dorm.posts.repository.push(
Post(id: 'post-1', title: 'First post', userId: user.id),
);
final List<User> users = await dorm.users.repository.peekAll(
Filter.text('Ad', field: UserEntity.fields.name),
);
final List<Join<User, Post>> posts =
await dorm.relations.users.posts.peekAll();
push and pushAll use PostgreSQL INSERT ... ON CONFLICT statements. The
conflict target contains all primary-key columns. patch, putAll, and
pushAll use an internal driver transaction. TransactionalDorm exposes a
transaction callback for composing repository operations without exposing the
driver transaction object.
Close the executor¶
Close the Connection or Pool from the application after the repositories
are no longer needed:
The complete pure Dart example is in the package's example/ directory and
uses POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DATABASE,
POSTGRES_USERNAME, and POSTGRES_PASSWORD for its endpoint values.
Configure credentials and query boundaries¶
The application owns the PostgreSQL endpoint credentials and supplies them to
Connection.open or Pool. Keep those values in deployment configuration.
The dORM engine does not provide an authentication, roles, or secrets-store
abstraction.
Filter values and model values are sent through the PostgreSQL driver's
parameterized execution path. Table and column identifiers come from the
generated schema metadata rather than from filter values.
Observe performance characteristics¶
The PostgreSQL engine builds parameterized SQL for direct operations. Its
putAll, pushAll, and patch paths use the driver's internal transaction
boundary described on this page. TransactionalDorm reuses the same driver
transaction for its callback.
Relationship reads can use direct relation plans or fall back to readable
operations. The fallback can perform additional repository reads. PostgreSQL
pull and pullAll emit the initial read only and do not maintain a database
subscription.