-
-
Notifications
You must be signed in to change notification settings - Fork 394
Description
Feature Request
Improvements to Loco's seed dump command
There are a few problems with the current way Loco dumps databases:
- When using SQLite, booleans aren't properly serialized and can't be imported later (see Dump and restore fail for booleans (and others) #1627)
- Database tables are fully loaded into memory
- Serialization of tables is done into memory before being written to disk, approximately doubling memory requirements
I'd like to be able to serialize directly to disk reliably by creating a custom async fn dump function that consumers create similar to the async fn seed function that exists now, or perhaps a macro that defines which ActiveModels should be dumped and restored?
Example:
async fn dump(ctx: &AppContext, base: &Path) -> Result<()> {
println!("Dumping Users");
db::dump::<users::ActiveModel>(&ctx.db, &base.join("users.yaml").display().to_string())
.await?;
}
// ... then within Loco
pub async fn dump<A>(db: &DatabaseConnection, path: &Path) -> crate::Result<()>
where
<<A as ActiveModelTrait>::Entity as EntityTrait>::Model: serde::Serialize,
A: ActiveModelTrait + Send + Sync,
<A as ActiveModelTrait>::Entity: EntityName,
{
let file = File::create(path)?;
let write_buffer = BufWriter::new(file);
let mut ser = serde_yaml::Serializer::new(write_buffer);
let mut seq = ser.serialize_seq(None)?;
let mut stream = A::Entity::find().stream(db).await?;
while let Some(item) = stream.try_next().await? {
seq.serialize_element(&item)?;
}
seq.end()?;
Ok(())
}Describe alternatives you've considered
I tried solving the issues with memory within the db::dump_tables() function and was able to serialize item by item (see #1690) but Sea ORM will only let you stream results from a Select result and not from the custom SQL that's being built in dump_tables.
I could use some feedback on this approach to make sure I'm doing it properly so it can be merged in one day. Thanks!