Git Product home page Git Product logo

multialchemy's Introduction

MultiAlchemy

Build Status Coverage Status Dependency Status

MultiAlchemy is an experimental SQLAlchemy extension that makes it easy to write row-based multi-tenant applications without having to manually ensure data separation for every operation.

Usage

Here's an example schema, taken from the tests, that has a tenant table, one other global table (users), and one per-tenant table (posts).

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
import multialchemy

engine = create_engine("sqlite:///multi_blog.db")
Base = declarative_base(cls=multialchemy.Base)

@Base.tenant_class
class Tenant(Base):
    __tablename__ = 'tenants'
    __multitenant__ = False
    id = Column(Integer, primary_key=True)
    name = Column(String(200))

class User(Base):
    __tablename__ = 'users'
    __multitenant__ = False
    id = Column(Integer, primary_key=True)
    name = Column(String(200))

class Post(Base):
    __tablename__ = 'posts'
    id = Column(Integer, primary_key=True)
    title = Column(String(200))
    author_id = Column(Integer, ForeignKey('users.id'))
    author = relationship(User, backref='posts')

If we look at the SQL emitted when creating these tables, we see that a tenant_id foreign key was added automatically.

CREATE TABLE posts (
	id INTEGER NOT NULL, 
	title VARCHAR(200), 
	author_id INTEGER, 
	tenant_id INTEGER, 
	PRIMARY KEY (id), 
	FOREIGN KEY(author_id) REFERENCES users (id), 
	FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);

Now let's create a multitenant-enabled session:

>>> TenantSession = sessionmaker(bind=engine, class_=multialchemy.TenantSession)
>>> session = TenantSession()

Then we can find a tenant using an unsafe query that bypasses tenant checking, and bind it as the current session's tenant.

>>> tenant = session.query(Tenant, safe=False).first()
>>> session.tenant = tenant

If we do a query involving a multitenant model, a filter will automatically be added to limit the results to only those matching the current session's tenant.

>>> print(str(session.query(Post)))
SELECT posts.id AS posts_id, posts.title AS posts_title, posts.author_id AS posts_author_id, posts.tenant_id AS posts_tenant_id 
FROM posts 
WHERE posts.tenant_id = :tenant_id_1

This works for joins too.

>>> print(str(session.query(User).join(Post)))
SELECT users.id AS users_id, users.name AS users_name 
FROM users JOIN posts ON users.id = posts.author_id 
WHERE posts.tenant_id = :tenant_id_1

You can bypass the tenant checking by passing safe=False to session.query().

Instances also automatically get assigned the correct tenant_id when you add them to the session:

>>> post = Post(title='Baz', author_id=1)
>>> session.add(post)
>>> post.tenant_id
1

License

Copyright 2014 Michael White

Released under the MIT License. See LICENSE.txt.

multialchemy's People

Contributors

mwhite avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.