我有一个多租户python猎鹰应用程序。每个租户都有自己的数据库。在传入请求时,我需要连接到租户数据库。
但这里有一种情况。数据库配置存储在另一个服务上,并且配置定期更改。
我在进程资源之前尝试了session create。但是在此更改之后sql查询会变慢。为了加快速度,我该怎么办?附: :我使用PostgreSQL
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
import config
import json
import requests
class DatabaseMiddleware:
def __init__(self):
pass
def process_resource(self, req, resp, resource, params):
engineConfig = requests.get('http://database:10003/v1/databases?loadOnly=config&appId=06535108-111a-11e9-ab14-d663bd873d93').text
engineConfig = json.loads(engineConfig)
engine = create_engine(
'{dms}://{user}:{password}@{host}:{port}/{dbName}'.format(
dms= engineConfig[0]['config']['dms'],
user= engineConfig[0]['config']['user'],
password= engineConfig[0]['config']['password'],
host= engineConfig[0]['config']['host'],
port= engineConfig[0]['config']['port'],
dbName= engineConfig[0]['config']['dbName']
))
session_factory = sessionmaker(bind=engine,autoflush=True)
databaseSession = scoped_session(session_factory)
resource.databaseSession = databaseSession
def process_response(self, req, resp, resource, req_succeeded):
if hasattr(resource, 'mainDatabase'):
if not req_succeeded:
resource.databaseSession.rollback()
self.databaseSession.remove()
您的方法可能是错误的,因为它违反了engine disposal中描述的引擎实例的预期使用模式。引擎实例的生命周期应与中间件实例的生命周期相同。
引擎引用连接池,这意味着在正常情况下,当Engine对象仍驻留在内存中时,存在打开的数据库连接。当一个Engine被垃圾收集时,该引擎不再引用它的连接池,并且假设它的所有连接都没有被检出,那么池及其连接也将被垃圾收集,这会产生关闭数据库连接也是如此。但是否则,引擎将保持打开的数据库连接,假设它使用QueuePool的正常默认池实现。
发动机通常是预先建立的永久固定装置,并在应用程序的整个生命周期内维护。它不打算在每个连接的基础上创建和处理;它是一个注册表,它既维护连接池,又维护有关正在使用的数据库和DBAPI的配置信息,以及每个数据库资源的某种程度的内部缓存。
结合SQLAlchemy,我使用SQLService作为SQLAlchemy的会话管理器和ORM层的接口层,它很好地集中了SQLAlchemy的核心功能。
这是我的中间件组件定义:
class DatabaseSessionComponent(object):
""" Initiates a new Session for incoming request and closes it in the end. """
def __init__(self, sqlalchemy_database_uri):
self.sqlalchemy_database_uri = sqlalchemy_database_uri
def process_resource(self, req, resp, resource, params):
resource.db = sqlservice.SQLClient(
{
"SQL_DATABASE_URI": self.sqlalchemy_database_uri,
"SQL_ISOLATION_LEVEL": "SERIALIZABLE",
"SQL_ECHO": False,
"SQL_ECHO_POOL": False,
"SQL_CONVERT_UNICODE": True,
"SQL_POOL_RECYCLE": 3600,
"SQL_AUTOCOMMIT": False,
"SQL_AUTOFLUSH": True,
"SQL_EXPIRE_ON_COMMIT": True,
},
model_class=BaseModel,
)
def process_response(self, req, resp, resource):
if hasattr(resource, "db"):
resource.db.disconnect()
通过它在API实例化中的实例化:
api = falcon.API(
middleware=[
DatabaseSessionComponent(os.environ["SQLALCHEMY_DATABASE_URI"]),
]
)