![]() Instead of the prefix string, we dynamically generated a repo module and passed that down. This basic pattern seemed okay, but we came up with a slightly different approach that we liked better. We pulled it out of the URL and passed it down from the controller, through the relevant context and to the actual DB call site. Our first prototype nested every route in the app under a tenant identifier. Whew! Every function needed to have prefix appended as an option (i.e get_users(prefix: prefix)). So with this in place we now needed a way to tell every database call in our application which prefix to target. This tells Ecto to execute a query like SELECT * FROM acme_development.my_ers. There are a few different syntaxes for this, but the one we used most commonly looked like: We also referred to this blog post by Iván González and the sample code he shared.Įcto has a feature called "query prefixes" that lets you specify which schema a given query should be run against. His third post was the basis for our implementation. I came across the schema feature in a podcast interview with Lars Wikman who had just written a fantastic series of blog posts covering a few different approaches to multi-tenancy with Ecto. In our case we aren’t expecting a huge number of tenants, so the data isolation seemed worth any scaling difficulties. On the other hand, some devs have had difficulty scaling with schemas. This should reduce accidental data leakage between tenants, which is a huge concern. By default every query will already be scoped to a tenant and getting data across tenant schemas is an exceptional case that requires extra work. The appeal of using schemas is the very clear lines of separation between customer data. Based on the title of this post I bet you can figure out which one we chose! An alternative solution is to store each tenant’s data in a separate Postgres schema, and query against that. One solution for this would be to add a tenant_id column to every table in the database. After we finished, Acme Corp and all their existing data would be just one tenant amongst others. This problem calls for a multi-tenant architecture. The goal was to fully whitelabel the application, so that when Other Corp used Acme’s platform, their users would only see Other Corp branding and data. It was working so well for them that they wanted to license their platform to other companies that provide the same service they do. Our client, lets call them Acme Corp for the rest of this post, had an existing web application that we helped build a little while ago. ![]() For this project we used Elixir, Phoenix and Ecto, but these have nothing to do with Ecto’s schemas (which did lead to some confusion). Neat! Schemas can be used as a way to set up different permissions, to separate different customers, or to logically organize your tables. ![]() When you write a query like SELECT * FROM users Postgres will actually execute SELECT * FROM db_. By default, all of your tables live inside the public schema, but you can create other schemas. The official docs analogize them to directories on your filesystem. ![]() What is a “schema”? #Ī schema is a kind of Postgres object that sits in between the database and the tables. Exposure to new tech is one of the best parts of this job! I want to share a little bit about Postgres schemas, how to use them with Elixir’s Ecto library, and some challenges we faced while integrating them into an existing application. On a recent project, I learned and used a feature of Postgres that was new to me. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |