Извините за длинный вопрос. Я пытался сохранить его в хорошем формате.
Как мне структурировать свое приложение, чтобы иметь возможность использовать 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
(но на этом этапе мне придется взломать свой путь к переменным конфигурации) )