feat: Support for lazy database connections (#2268)
Add support for creating DB connection pools without establishing connections up front. This is already supported by SQLx via the [Pool::connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy) method. This PR adds a new `connect_lazy` option to `database::ConnectOptions`. If set to `true`, the SQLx `Pool` will be created using the `Pool::connect_lazy_with` method; otherwise, the `Pool::connect_with` method will be used (e.g., the existing behavior). This "lazy" behavior is implemented for each DB variant (Postgres/MySQL/SQLite). This was discussed previously [here](https://github.com/SeaQL/sea-orm/discussions/1645), but it appears support was never added to SEA ORM directly.
This commit is contained in:
parent
0b956dcd2b
commit
4553160685
@ -63,10 +63,15 @@ pub struct ConnectOptions {
|
|||||||
/// Schema search path (PostgreSQL only)
|
/// Schema search path (PostgreSQL only)
|
||||||
pub(crate) schema_search_path: Option<String>,
|
pub(crate) schema_search_path: Option<String>,
|
||||||
pub(crate) test_before_acquire: bool,
|
pub(crate) test_before_acquire: bool,
|
||||||
|
/// Only establish connections to the DB as needed. If set to `true`, the db connection will
|
||||||
|
/// be created using SQLx's [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy)
|
||||||
|
/// method.
|
||||||
|
pub(crate) connect_lazy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
/// Method to create a [DatabaseConnection] on a database
|
/// Method to create a [DatabaseConnection] on a database. This method will return an error
|
||||||
|
/// if the database is not available.
|
||||||
#[instrument(level = "trace", skip(opt))]
|
#[instrument(level = "trace", skip(opt))]
|
||||||
pub async fn connect<C>(opt: C) -> Result<DatabaseConnection, DbErr>
|
pub async fn connect<C>(opt: C) -> Result<DatabaseConnection, DbErr>
|
||||||
where
|
where
|
||||||
@ -157,6 +162,7 @@ impl ConnectOptions {
|
|||||||
sqlcipher_key: None,
|
sqlcipher_key: None,
|
||||||
schema_search_path: None,
|
schema_search_path: None,
|
||||||
test_before_acquire: true,
|
test_before_acquire: true,
|
||||||
|
connect_lazy: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,4 +303,16 @@ impl ConnectOptions {
|
|||||||
self.test_before_acquire = value;
|
self.test_before_acquire = value;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If set to `true`, the db connection pool will be created using SQLx's
|
||||||
|
/// [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy) method.
|
||||||
|
pub fn connect_lazy(&mut self, value: bool) -> &mut Self {
|
||||||
|
self.connect_lazy = value;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get whether DB connections will be established when the pool is created or only as needed.
|
||||||
|
pub fn get_connect_lazy(&self) -> bool {
|
||||||
|
self.connect_lazy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,15 +61,21 @@ impl SqlxMySqlConnector {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match options.sqlx_pool_options().connect_with(opt).await {
|
let pool = if options.connect_lazy {
|
||||||
Ok(pool) => Ok(DatabaseConnection::SqlxMySqlPoolConnection(
|
options.sqlx_pool_options().connect_lazy_with(opt)
|
||||||
|
} else {
|
||||||
|
options
|
||||||
|
.sqlx_pool_options()
|
||||||
|
.connect_with(opt)
|
||||||
|
.await
|
||||||
|
.map_err(sqlx_error_to_conn_err)?
|
||||||
|
};
|
||||||
|
Ok(DatabaseConnection::SqlxMySqlPoolConnection(
|
||||||
SqlxMySqlPoolConnection {
|
SqlxMySqlPoolConnection {
|
||||||
pool,
|
pool,
|
||||||
metric_callback: None,
|
metric_callback: None,
|
||||||
},
|
},
|
||||||
)),
|
))
|
||||||
Err(e) => Err(sqlx_error_to_conn_err(e)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ impl SqlxPostgresConnector {
|
|||||||
.schema_search_path
|
.schema_search_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|schema| format!("SET search_path = {schema}"));
|
.map(|schema| format!("SET search_path = {schema}"));
|
||||||
|
let lazy = options.connect_lazy;
|
||||||
let mut pool_options = options.sqlx_pool_options();
|
let mut pool_options = options.sqlx_pool_options();
|
||||||
if let Some(sql) = set_search_path_sql {
|
if let Some(sql) = set_search_path_sql {
|
||||||
pool_options = pool_options.after_connect(move |conn, _| {
|
pool_options = pool_options.after_connect(move |conn, _| {
|
||||||
@ -76,15 +77,20 @@ impl SqlxPostgresConnector {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
match pool_options.connect_with(opt).await {
|
let pool = if lazy {
|
||||||
Ok(pool) => Ok(DatabaseConnection::SqlxPostgresPoolConnection(
|
pool_options.connect_lazy_with(opt)
|
||||||
|
} else {
|
||||||
|
pool_options
|
||||||
|
.connect_with(opt)
|
||||||
|
.await
|
||||||
|
.map_err(sqlx_error_to_conn_err)?
|
||||||
|
};
|
||||||
|
Ok(DatabaseConnection::SqlxPostgresPoolConnection(
|
||||||
SqlxPostgresPoolConnection {
|
SqlxPostgresPoolConnection {
|
||||||
pool,
|
pool,
|
||||||
metric_callback: None,
|
metric_callback: None,
|
||||||
},
|
},
|
||||||
)),
|
))
|
||||||
Err(e) => Err(sqlx_error_to_conn_err(e)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,11 +66,21 @@ impl SqlxSqliteConnector {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.get_max_connections().is_none() {
|
if options.get_max_connections().is_none() {
|
||||||
options.max_connections(1);
|
options.max_connections(1);
|
||||||
}
|
}
|
||||||
match options.sqlx_pool_options().connect_with(opt).await {
|
|
||||||
Ok(pool) => {
|
let pool = if options.connect_lazy {
|
||||||
|
options.sqlx_pool_options().connect_lazy_with(opt)
|
||||||
|
} else {
|
||||||
|
options
|
||||||
|
.sqlx_pool_options()
|
||||||
|
.connect_with(opt)
|
||||||
|
.await
|
||||||
|
.map_err(sqlx_error_to_conn_err)?
|
||||||
|
};
|
||||||
|
|
||||||
let pool = SqlxSqlitePoolConnection {
|
let pool = SqlxSqlitePoolConnection {
|
||||||
pool,
|
pool,
|
||||||
metric_callback: None,
|
metric_callback: None,
|
||||||
@ -84,9 +94,6 @@ impl SqlxSqliteConnector {
|
|||||||
|
|
||||||
Ok(DatabaseConnection::SqlxSqlitePoolConnection(pool))
|
Ok(DatabaseConnection::SqlxSqlitePoolConnection(pool))
|
||||||
}
|
}
|
||||||
Err(e) => Err(sqlx_error_to_conn_err(e)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SqlxSqliteConnector {
|
impl SqlxSqliteConnector {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user