Last active
May 22, 2020 21:33
-
-
Save alexa-infra/2bfb56e0ae79689433b0e365bc3f7926 to your computer and use it in GitHub Desktop.
Minimal flask-sqlalchemy integration, which allows you to keep models independent of flask
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import TYPE_CHECKING | |
from sqlalchemy import create_engine | |
if TYPE_CHECKING: | |
from flask import Flask | |
from sqlalchemy.orm import scoped_session | |
class FlaskSQLAlchemy: | |
def __init__(self, app: 'Flask' = None, db: 'scoped_session' = None) -> None: | |
self.engine = None | |
if app and db: | |
self.init_app(app, db) | |
def init_app(self, app: 'Flask', db: 'scoped_session') -> None: | |
if not app or not db: | |
raise ValueError | |
app.extensions['sqlalchemy'] = self | |
uri = app.config.setdefault('SQLALCHEMY_DATABASE_URI', 'sqlite:///:memory:') | |
options = app.config.setdefault('SQLALCHEMY_ENGINE_OPTIONS', {}) | |
self.engine = engine = create_engine(uri, **options) | |
db.configure(bind=engine) | |
# pylint: disable=unused-variable | |
@app.teardown_appcontext | |
def shutdown_session(response_or_exc): | |
db.remove() | |
return response_or_exc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sqlalchemy.orm import scoped_session | |
from sqlalchemy.orm import sessionmaker | |
from sqlalchemy.ext.declarative import declarative_base | |
session_factory = sessionmaker() | |
db = scoped_session(session_factory) | |
Model = declarative_base() | |
metadata = Model.metadata | |
from .mymodel import MyModel |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sqlalchemy import Column, Integer, Text | |
from .models import Model | |
class MyModel(Model): | |
__tablename__ = 'my_model' | |
id = Column(Integer, primary_key=True) | |
name = Column(Text, nullable=False) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pytest | |
from .models import db, metadata | |
from .mymodel import MyModel | |
@pytest.fixture | |
def with_flask(): | |
app = Flask(__name__) | |
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' | |
sa = FlaskSQLAlchemy() | |
sa.init_app(app, db) | |
with app.app_context() as ctx: | |
metadata.create_all(sa.engine) | |
yield | |
@pytest.fixture | |
def without_flask(): | |
engine = create_engine('sqlite:///:memory:') | |
db.configure(bind=engine) | |
try: | |
metadata.create_all(engine) | |
yield | |
finally: | |
db.remove() | |
@pytest.mark.usefixtures('with_flask') | |
def test_simple(): | |
item = MyModel(name='hello') | |
db.add(item) | |
db.commit() | |
item = db.query(MyModel).filter_by(name='hello').first() | |
assert item.name == 'hello' | |
@pytest.mark.usefixtures('without_flask') | |
def test_simple2(): | |
item = MyModel(name='world') | |
db.add(item) | |
db.commit() | |
item = db.query(MyModel).filter_by(name='world').first() | |
assert item.name == 'world' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment