Dialect-dependent column types in sqlalchemy
Recently I was working on a system that uses postgres as the database storage choice. The system uses sqlalchemy core for database interactions, so it is almost agnostic to the particular choice of database backend. It is not completely agnostic because it is using an ARRAY column type in a few places, which is only supported by postgres.
I wanted to implement some light-weight testing against the database using sqlite instead of postgres. It turns out there are tools for doing this in sqlalchemy, using TypeDecorators.
SQLAlchemy’s TypeDecorator
We can implement a custom type that swaps to JSON when the backend dialect is sqlite and uses postgres’s native Array type otherwise. Note that you lose inner typing in the sqlite case, but it’s better than nothing!
Usage in Table definitions
You would use the MaybeArray
type decorator just as you would any other column type in your code.
For example, your table definition would change from..
to…
Conclusions
This turned out to work perfectly! However, in this particular system, there was another dialect-dependency hidden beneath the surface that prevented sqlite usage: there are many SQL RETURNING
statements used throughout the code. I was happy to see this already on the SQLAchemy developers’ radars. For now, we’ll continue testing against postgres, which is probably a better move in the long run anyhow :)