Adopting an existing database
If you already have a database with an unmanaged schema, you don’t have to write your SQL from scratch. The
nschema import command reads a live schema and writes it out as NSQL source files, so
you can adopt an existing database and manage it going forward.
-
Declare the database. The import command reads from a live database, so it needs a
PLUGINdeclaration and aDATABASEstatement. Create a configuration file in your project directory with just those. The schema files themselves will come from the import:-- config.sqlPLUGIN postgres (source = 'NSchema.Postgres',version = '[5.0,6.0)');DATABASE postgres ();Then run
nschema initto install the plugins.Supply the connection string as an environment variable, so it stays out of source control (see Configuration):
Terminal window export NSCHEMA_DATABASE_CONNECTION_STRING="Host=localhost;Database=app;Username=postgres;Password=postgres" -
Import the database schema into a directory:
Terminal window nschema import --out-dir ./schemasThis writes the live database schema out as
.sqlfiles. To adopt only part of the database, you can use the same--scopeargument that works withplanandapply:Terminal window nschema import --out-dir ./schemas --scope app.orders --scope billingAs a safety measure,
importwon’t import into a directory that already contains.sqlfiles; pass--forceif you really mean to re-import over existing files. -
Review and commit. Read the generated files, tidy them if you like, and check them into source control.
-
Apply to adopt. NSchema diffs your project against the recorded state, so running
applywill first refresh your state with the latest database snapshot, before displaying any differences as a migration plan. This first plan should be empty, if you haven’t made any changes, but the output will show a number of objects to be “adopted” (see below).Terminal window nschema apply -
Manage changes from here. Edit the
.sqlfiles and use the normal plan / apply workflow from now on.
Adoption is gradual
Section titled “Adoption is gradual”The state store records what the entire database contains, for dependency resolution, but NSchema only controls what the project declares. In the state, this is referred to as the managed set. When you declare a new object, or adopt an existing one, it’s added to the managed set, and a drop is what happens when an object in the managed set no longer exists in the declared project. That way, NSchema won’t ever drop anything that it doesn’t manage, so importing a whole database and then declaring one schema at a time is safe: the parts you haven’t adopted yet are simply left alone.