Multi-Database Support
Relevant source files
The following files were used as context for generating this wiki page:
Multi-database support in Loco allows applications to connect to and manage multiple database instances simultaneously. This feature is primarily managed through the MultiDb structure, which serves as a container for various DatabaseConnection instances mapped to specific names. This architecture enables developers to separate data across different database providers or instances, such as using Postgres for primary application data and SQLite for local caching or specific microservices.
The framework leverages SeaORM for underlying database interactions, providing a consistent API for querying, migrating, and seeding data across all supported backends, including PostgreSQL, MySQL, and SQLite.
Sources: src/db.rs:48-75, README.md:46-51
Architecture and Components
The core of multi-database management is the MultiDb struct, which encapsulates a collection of named database connections.
The MultiDb Structure
The MultiDb struct utilizes a HashMap<String, DatabaseConnection> to store connections. It provides methods to initialize multiple connections from a configuration map and retrieve specific connections by their identifier.
The diagram shows how the MultiDb container manages multiple independent database connections.
Sources: src/db.rs:48-75
Connection Management Logic
Database connections are established using ConnectOptions, which configure parameters like connection pool size and timeouts. For SQLite connections, the framework automatically executes specific PRAGMA statements on startup (e.g., enabling WAL mode and foreign keys) to ensure optimal performance and safety.
| Component | Description |
|---|---|
MultiDb::new | Asynchronously creates database connections from a configuration map. |
MultiDb::get | Retrieves a connection by name; returns an error if the key is missing. |
connect | Low-level function to establish a single DbConn using ConnectOptions. |
extract_db_name | Utility to parse the database name from a connection URI. |
Sources: src/db.rs:56-75, src/db.rs:114-159, src/db.rs:166-173
Data Flow and Operations
Loco provides a set of operations that can be performed across the managed databases, including migrations, seeding, and schema dumping.
Database Initialization Flow
When an application starts, it resolves configurations and establishes connections. The converge function manages the lifecycle of the database schema based on configuration flags like auto_migrate or dangerously_recreate.
This flowchart illustrates the schema management logic applied during application bootstrap.
Sources: src/db.rs:90-112, src/cli.rs:555-560
Seeding and Truncation
The framework supports seeding databases from YAML files. The seed function deserializes files (typically found in src/fixtures) and inserts them into the database while automatically resetting auto-increment sequences (primary keys) to maintain data integrity.
Sources: src/db.rs:218-245, src/cli.rs:446-465
Configuration and CLI Integration
Multi-database support is integrated into the Loco CLI, allowing developers to manage multiple environments and perform DB-specific tasks.
CLI Commands
The CLI provides a db subcommand to interact with the configured databases.
- Migrate:
cargo loco db migrate- Applies pending migrations. - Reset:
cargo loco db reset- Drops all tables and reapplies migrations. - Entities:
cargo loco db entities- Generates SeaORM entity files from the database schema. - Seed:
cargo loco db seed- Populates the database with initial data from fixtures.
Sources: src/cli.rs:420-444, loco-new/tests/templates/db.rs:81-95
Database Configuration Options
Database settings are defined in environment-specific YAML files (e.g., config/development.yaml).
| Option | Type | Description |
|---|---|---|
uri | String | Connection string (e.g., postgres://user:pass@localhost/db). |
auto_migrate | Boolean | If true, migrations run automatically on startup. |
max_connections | Integer | Maximum size of the connection pool. |
dangerously_recreate | Boolean | If true, drops and recreates the schema on startup. |
run_on_start | String | Optional SQL to execute immediately after connecting. |
Sources: src/db.rs:114-135, loco-new/tests/templates/db.rs:12-40
Implementation Details
Postgres Database Creation
For PostgreSQL, the framework includes logic to check if a database exists and create it if necessary using CREATE DATABASE ... WITH ENCODING='UTF8'. This is handled by the create function which replaces the target DB name in the URI with /postgres to establish a maintenance connection for the creation process.
Sources: src/db.rs:180-197, src/db.rs:596-624
Schema Dumping
Multi-database support includes the ability to dump table contents or schema structures to files. The dump_tables function iterates through database tables, identifies column types (handling booleans specifically for cross-backend consistency), and writes data to YAML files.
Sources: src/db.rs:677-781, src/db.rs:786-848
Conclusion
Multi-database support in Loco provides a robust abstraction layer for managing complex data architectures. By centralizing connection management in MultiDb and providing integrated CLI tools for migrations and seeding, Loco ensures that handling multiple database backends remains productive and safe. This system allows for seamless transitions between development (often using SQLite) and production environments (using PostgreSQL or MySQL) while maintaining high performance through SeaORM integration.