Skip to content

Introduce database export and import #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 10, 2025
Merged

Conversation

farost
Copy link
Member

@farost farost commented May 29, 2025

Usage and product changes

Add database export and database import operations.

Database export saves the database information (its schema and data) on the client machine as two files at provided locations:

# database export <name> <schema file location> <data file location>
database export my-database export/my-database.typeql export/my-database.typedb

Database import uses the exported files to create a new database with equivalent schema and data:

# database export <name> <schema file location> <data file location>
database import their-database export/my-database.typeql export/my-database.typedb

Implementation

Add new commands similar to other database interfaces. Prepare data to call the respective typedb-driver APIs.

remote = "https://github.com/typedb/typedb-driver",
tag = "3.2.0", # sync-marker: do not remove this comment, this is used for sync-dependencies by @typedb_driver
remote = "https://github.com/farost/typedb-driver",
commit = "e3b3ab1df21c7bbeef6b3bfd9b1a040343fbb54a", # sync-marker: do not remove this comment, this is used for sync-dependencies by @typedb_driver
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@farost
Copy link
Member Author

farost commented May 29, 2025

CI is red because there is no server artifact yet.

@farost farost marked this pull request as ready for review May 29, 2025 10:35
Copy link
Member

@dmitrii-ubskii dmitrii-ubskii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments are more general than this PR, which looks good to me.

Comment on lines +267 to 322
.add(CommandLeaf::new_with_inputs(
"import",
"Create a database with the given name based on another previously exported database.",
vec![
CommandInput::new("db", get_word, None, None),
CommandInput::new("schema file path", get_word, None, None),
CommandInput::new("data file path", get_word, None, None),
],
database_import,
))
.add(CommandLeaf::new_with_inputs(
"export",
"Export a database into a schema definition and a data files.",
vec![
CommandInput::new(
"db",
get_word,
None,
Some(database_name_completer_fn(driver.clone(), runtime.clone())),
),
CommandInput::new("schema file path", get_word, None, None),
CommandInput::new("data file path", get_word, None, None),
],
database_export,
));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is get_word really the correct parser for a file path? It looks like it just reads until whitespace.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's how files are parsed in source:

        .add(CommandLeaf::new_with_input(
            "source",
            "Execute a file containing a sequence of TypeQL queries. Queries may be split over multiple lines using backslash ('\\')",
            CommandInput::new("file", get_word, None, Some(Box::new(file_completer))),
            transaction_source,
        ))

Comment on lines 57 to 64
let db_name = input[0].clone();
let schema = read_to_string(input[1].clone()).map_err(|err| Box::new(err) as Box<dyn Error + Send>)?;
let data_file_path: PathBuf = input[2].clone().into();
context
.background_runtime
.run(async move { driver.databases().import_file(db_name, schema, data_file_path).await })
.map_err(|err| Box::new(err) as Box<dyn Error + Send>)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I take issue with this direct use of background_runtime, but this is not a problem with this PR.
@flyingsilverfin why aren't we using the blocking version of driver in console? It doesn't look like we're gaining anything from the async.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 'future' usage which we may want to leverage the async driver - for instance for bulk loading.

Comment on lines 58 to 59
let schema = read_to_string(input[1].clone()).map_err(|err| Box::new(err) as Box<dyn Error + Send>)?;
let data_file_path: PathBuf = input[2].clone().into();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use context.read_path or whatever it's called, to relativize the path correctly (for example, if this is running inside a script, it will relativize relative to the script location).

Basically doing that for all paths now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will test this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works fine, will preserve this

@farost farost force-pushed the 3.x-export-import branch from f776626 to 15cebea Compare June 9, 2025 16:50
@farost farost merged commit afd09d2 into typedb:master Jun 10, 2025
3 checks passed
@farost farost deleted the 3.x-export-import branch June 10, 2025 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants