I'm thinking about how to best handle schema migrations
datomic transactions are idempotent so as a default one could install their schema on startup every time
but just because datomic will only transact new values does not mean that updating the schema without some sort of versioning system is harmless. specially, some attribute changes require altering data (e.g. changing the type of an attribute).
so along with an installs property that list the attributes to install, it's likely necessary to require a schema name and version to serve as metadata for tracking schema changes.
{:name :my-schema
:version "1.0"
:installs [#attr {:user/username :db.type/string]}
To reinstall schema attributes, the use just has to up the configured version.
now, regarding migrations, I considered requiring the prior version, i.e. :version-before "1.0" so that we can know whether it is necessary to run a migration. but that might be unnecessary given that Datomic encourages schema growth, and thus rollbacks are unnecessary. perhaps giving each migration a name will be sufficient and we can keep track of the ones we have/haven't ran, and always run them in order:
{:name :my-schema
:version "1.0"
:installs [...]
:migrations [{:name :change-foo :tx-fn 'myapp.migrations/change-foo}
{:name :change-bar :tx-fn 'myapp.migrations/change-bar}]}
Similar to attribute installs, the user has to change the database version so that we can know to recheck/rerun the necessary changes.
I'm thinking about how to best handle schema migrations
datomic transactions are idempotent so as a default one could install their schema on startup every time
but just because datomic will only transact new values does not mean that updating the schema without some sort of versioning system is harmless. specially, some attribute changes require altering data (e.g. changing the type of an attribute).
so along with an
installsproperty that list the attributes to install, it's likely necessary to require a schemanameandversionto serve as metadata for tracking schema changes.{:name :my-schema :version "1.0" :installs [#attr {:user/username :db.type/string]}To reinstall schema attributes, the use just has to up the configured version.
now, regarding migrations, I considered requiring the prior version, i.e.
:version-before "1.0"so that we can know whether it is necessary to run a migration. but that might be unnecessary given that Datomic encourages schema growth, and thus rollbacks are unnecessary. perhaps giving each migration anamewill be sufficient and we can keep track of the ones we have/haven't ran, and always run them in order:{:name :my-schema :version "1.0" :installs [...] :migrations [{:name :change-foo :tx-fn 'myapp.migrations/change-foo} {:name :change-bar :tx-fn 'myapp.migrations/change-bar}]}Similar to attribute installs, the user has to change the database version so that we can know to recheck/rerun the necessary changes.