Как сделать движок SQLAlchemy доступным в приложении flask? - PullRequest
0 голосов
/ 17 января 2020

Извините за длинный вопрос. Я пытался сохранить его в хорошем формате.

Как мне структурировать свое приложение, чтобы иметь возможность использовать SQLAlchemy engine во всем приложении, особенно когда я использую Mixins и пользовательский класс Base в моделях каталог. В настоящее время я использую что-то вроде этого:

application/
|── svc/
│  |── service/
│  | └─── service.py
│  | └─── service2.py
│  |── postgres/
│  | └─── models/
│  |  | └──── CustomBase.py
│  |  | └──── User.py
│  |──── connect.py
|── scripts/
│  |── mock_data/
│  | └───── postgres_mock_data.py
│  |──── db.py
│  |──── load_data.py
│  |──── commands.sh
|── wsgi.py

My connect.py выглядит так:

def connect_postgres(env_config=config['LOCAL']):
    """
    Function that sends host information to SQLAlchemy
    """

    # Omitted variables for brevity 
    connection_string = f'postgresql://{user}:{password}@{host}/{database}'
    engine = create_engine(connection_string, echo=True)

    return engine

service.py также содержит:

app = Flask(__name__)
app.register_blueprint(service2, url_prefix='/endpoint2')

wsgi.py выглядит так:

from svc.postgres.connect import connect_postgres
from svc.service.service import app as application
config = configparser.ConfigParser()

def startApp(env):
    connect_postgres(config[env])
    application.run(debug=True)

if __name__ == "__main__":
    startApp('LOCAL')

CustomBase.py выглядит так:

from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.declarative import declarative_base

class CustomBase(object):
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

    # Ommited for brevity

Base = declarative_base(cls=CustomBase)

User.py

from sqlalchemy import Column, String
from CustomBase import Base

class User(Base):
     name = Column(String)
     fullname = Column(String)
     nickname = Column(String)

Я запускаю свое приложение с команда python wsgi.py.

Вопрос:

Как мне импортировать engine и session в мои service.py, где будет выполнено большинство SQL запросов. Я хочу не делать следующее в service.py, потому что кажется, что это избыточно, так как я уже подключился к postgres в начале приложения.

from svc.postgres.connect import connect_postgres
engine = connect_postgres(config[env])

Я думаю, что я, очевидно, имею чтобы сделать это в service.py, как только engine станет доступным:

from CustomBase import Base
from sqlalchemy.orm import sessionmaker

# Create all schemas
Base.metadata.create_all(engine)

# create a configured "Session" class
Session = sessionmaker(bind=engine)

# create a Session
session = Session()

Я знаю, что довольно просто сделать то же самое с flask-sqlalchemy, но я обязан использовать библиотеку SQLAlchemy.

flask -sqlalchemy code:

db = SQLAlchemy(app)

Я могу использовать db во всех унаследованных проектах apis.


РЕДАКТИРОВАТЬ: Потенциальный ответ

Должен ли я просто включить engine в мой файл CustomBase.py и снова установить соединение?

CustomBase.py выглядит так:

from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.declarative import declarative_base
from svc.postgres.connect import connect_postgres

class CustomBase(object):
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

    # Ommited for brevity

Base = declarative_base(cls=CustomBase)
engine = connect_postgres(config[env])

service.py

from CustomBase import Base, engine
from User import User
from sqlalchemy.orm import sessionmaker

# Create all schemas
Base.metadata.create_all(engine)

# create a configured "Session" class
Session = sessionmaker(bind=engine)

# create a Session
session = Session()

Хотя все еще кажется избыточным вызов функции connect_postgres дважды, или я должен просто удалить ее из моего wsgi.py (но на этом этапе мне придется взломать свой путь к переменным конфигурации) )

1 Ответ

1 голос
/ 18 января 2020

Если вы хотите создать объект db, такой как Flask -SQLAlchemy, вы можете создать его с помощью scoped_session:

# database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))

Затем используйте его следующим образом:

>>> from yourapplication.database import db_session
>>> from yourapplication.models import User
>>> u = User('admin', 'admin@localhost')
>>> db_session.add(u)
>>> db_session.commit()

Также зарегистрируйте обработчик для удаления сеанса базы данных, когда завершится приложение:

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

Подробнее о документации Flask для поддержки SQLAlchemy .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...