[QUESTION] Use multiple DB schemas in SQLAlchemy
See original GitHub issueFirst check
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
Description
I need to use several schemas for a project. I’m using MySQL but any RDBMS should be compatible with this as long as SQLAlchemy supports it.
Currently I’m seeing two ways to do it:
From Flask-SQLAlchemy:
SQLALCHEMY_DATABASE_URI = 'postgres://localhost/main'
SQLALCHEMY_BINDS = {
'users': 'mysqldb://localhost/users',
'appmeta': 'sqlite:////path/to/appmeta.db'
}
from sqlalchemy import String, Integer, Column
from sqlalchemy.ext.declarative import declarative_base
class BindMetaMixin(object):
def __init__(cls, name, bases, d):
bind_key = (
d.pop('__bind_key__', None)
or getattr(cls, '__bind_key__', None)
)
super(BindMetaMixin, cls).__init__(name, bases, d)
if bind_key is not None and getattr(cls, '__table__', None) is not None:
cls.__table__.info['bind_key'] = bind_key
class DefaultMeta(BindMetaMixin):
pass
Base = declarative_base(metaclass=DefaultMeta)
class User(Base):
__bind_key__ = 'users'
__tablename__ = "users"
id = Column('id', Integer, primary_key=True)
username = Column('username', String(255), unique=True)
from SQLAlchemy docs, Multi-Tenancy way
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
__table_args__ = {'schema': 'per_user'}
session = Session()
session.connection(execution_options={
"schema_translate_map": {"per_user": "account_one"}})
# will query from the ``account_one.user`` table
session.query(User).get(5)
from SQLAlchemy docs, “raw/simpler way”
class User(Base):
__table_name__ = "users"
__table_args__ = {"schema": "yet_another_schema"}
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100))
Additional context
Although all these ways work, I’m wondering what could be the “better” approach. Specifically which way will:
- Still support transactions (if the DB supports them of course)
- Would cause less strain (or none, for the the non-default schemas) when the session loads the metadata
- Would not mess with the connection pool
Issue Analytics
- State:
- Created 4 years ago
- Reactions:5
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Multi-schema Postgres database handling through SQLAlchemy
Represent a multischema Postgres db through use of the SQLAlchemy ORM · Dynamically query tables with the same name in different schemas ·...
Read more >SQLAlchemy multi-schema support - python - Stack Overflow
The problem with making it multi-platform, is that each database has a slightly different understanding of the word 'schema'. Basically, if I am ......
Read more >Using Database Schemas in Flask-SQLAlchemy - YouTube
If you have a database with multiple schemas and you want to use SQLAlchemy, this video is for you. I'll show you how...
Read more >Dynamically Set ORM Schemas via Sqlalchemy - mayn.es
I recently stumbled on such a problem when trying to configure a set of Object Relational Mappings (ORM) to support an application with...
Read more >Frequently Asked Questions — SQLAlchemy 1.4 Documentation
Why does SQLAlchemy issue so many ROLLBACKs? I am using multiple connections with a SQLite database (typically to test transaction operation), and my...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
You’re welcome! Great work!
Not really FastAPI-related, but binding is to work with database engines, which correspond with connections, not schemas.
Binding to schemas (with the ORM) is done by assigning schemas to your model classes, like so: