> A monolith is an organism-like distributed set of services with predictable behavior. That predictability makes it an ideal foundation for SaaS architecture. With your monolith in place...
Wat? Title should be: "How to do tenant isolation and audit logs"; this is in no way a sketch of how to build a SaaS application.
Cool, seems about right and that is similar to how I did multitenancy in Django years ago. If anyone reads this and has a good answer, I’m still curious on one question that I was never able to answer (due to my limited knowledge of Postgres and other databases).
Is there a good solution for automatically scoping a query to a tenant at the database-level (perhaps using a custom extension or PL/PgSQL to rewrite the queries), assuming the tenant_id is in the SQL request?
I guess I'm asking if it's possible to move this functionality to the database layer with something like PL/pgSQL or the Postgres rule system... both of which I know very little about.
@db.event.listens_for(TenantQuery, 'before_compile', retval=True)
def ensure_tenant_constrained(query):
for desc in query.column_descriptions:
if hasattr(desc['type'], 'tenant') and \
query.current_tenant_constrained:
query = query.filter_by(tenant=get_current_tenant())
return query
Of course the only point in asking such a question is if there's a good reason to do it, and I can't remember why I looked into this in the first place (it's been more than a couple of years).
I've used RLS and it works great for this. Make sure you have your tenant_id on all tables, which makes it easy to partition later. I think you can even do per-tenant backups/archives like this with pgdump, by using a specific user.
I have not thought more though this, but may be combining that with the PG 11s partitioning, would get me even closer to tenant-specific archiving/backup and other admin tasks beyond query.
Wat? Title should be: "How to do tenant isolation and audit logs"; this is in no way a sketch of how to build a SaaS application.