Multiple drift databases vs one with multiple tables for packages

I’m looking for some insights when using drift in multiple private packages.

We have a mono-repo with 3 apps and multiple private packages to share code amongst them. As more packages are starting to arise (these apps used to have a lot of copied code :grimacing: ), we’re facing some new challenges.
We have a few packages that would have to persist data, for which we’d like to use drift. Drift is already being used in our apps.

Should we go down the route of creating separate databases for each private package (we’re expecting 5 or 6 at the moment) or should we leave that responsibility to the host app and have multiple tables there?

I’ve been looking at the modular generation capabilities of drift, which might allow us to define the tables and DAOs in the package, but still have a single database in the app.

My main concern is performance but it’s hard to measure ahead of time so I’m hoping somebody can share their experiences on this topic :slight_smile:
Thanks!

1 Like

We went with the approach of having multiple databases first but in hindsight it might have been better with one database. We have 2 dbs to be accessed mainly by native code, and one db to be written to by the Flutter side. They were also accessed by the workmanager (i.e. background isolate Flutter).

Pros for multiple dbs:

  • for longer writes from the native side, we don’t have to worry about locking on the Flutter side
  • for sensitive data easier to analyze just a single file
  • we can basically avoid migrating databases when the schema is fixed

Cons:

  • a lot of back-and-forth to initialize and access various databases
  • locking still occurs occasionally
  • in the end we had to get access to the 3rd database on the native side, so we could’ve just done it in the very beginning anyway; so now all are accessed everywhere
  • necessary to run drift_dev multiple times

This is from the point of view of app, not package. Perhaps for packages it may be worth having isolated databases anyway. This is how a lot of the SDKs is approaching their data storage.

3 Likes

Been there because of PowerSync (which forces a full database per user id).

Best thing you can do, since you already are using the best ORM out there, is to use Drift DAOs.

You can then use one single database, but have N modules for each of your app features (it also plays very nice with the amazing .drift files).

2 Likes

I’m currently using the modular generation, which allows me to keep create the package specific tables in the package and use them in the app’s generated database.

I’m still checking if it’s possible to create the DAO also in the package and use it in the @DriftDatabase annotation in the app. The app could then provide the instance of the package-specific DAO back to the package, allowing the package to only work on it’s own tables. Right now, I didn’t find a way to do this yet, since the DAO generation relies on the AppDatabase class.

As a workaround, I created a manual DAO which requires the instances of the generated tables in it’s constructor. I think it is basically the same. Just to summarize with a simplified example:

MyPackage:

  • has and exports MyPackageTable extends Table
  • exports a class MyPackageDao that requires a generated $MyPackageTable in it’s constructor.
  • Has an initialize method that requires an instance of MyPackageDao

MyApp:

  • has a database with @DriftDatabase(tables: [MyPackageTable, ...other])
  • calls my package’s initialize(MyPackageDao(database.myPackageTable))

Both have a build.yaml file that enables drift_dev:modular

Hopefully that makes sense.
I can follow up with a gist or github example later

That’s the price of code generation. The other alternative is to create the code that is generated in the DAOs and use’em as mixins or make them isolated, receiving the AppDatabase as an injected dependency? Oh boy, I miss introspection do much in Dart =(

I think the best shot is to expose your problem/thinking to Simon directly (drift author). He is a very nice guy and always listen to us. Maybe some kind of generic modularization is a good fit for Drift, and he can implement something in this regard.