From ed1b8f239ee67b9af9899b2d4ebe35574e87de0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rajmund=20Hru=C5=A1ka?= <rajmund.hruska@cesnet.cz> Date: Tue, 19 Oct 2021 16:57:21 +0200 Subject: [PATCH] Feature: Use SQLAlchemy from flask_sqlalchemy. (Redmine issue: #6205) --- lib/mentat/services/sqlstorage.py | 23 +++++++++++++++-------- lib/mentat/services/whois.py | 5 +---- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/mentat/services/sqlstorage.py b/lib/mentat/services/sqlstorage.py index 31a23155b..59a8d1981 100644 --- a/lib/mentat/services/sqlstorage.py +++ b/lib/mentat/services/sqlstorage.py @@ -10,7 +10,8 @@ """ Database storage abstraction layer. The current implementation is based on the -awesome `SQLAlchemy <http://www.sqlalchemy.org/>`__ library. +awesome `SQLAlchemy <http://www.sqlalchemy.org/>`__ library accessed by +`flask_sqlalchemy <https://flask-sqlalchemy.palletsprojects.com/>`__. .. warning:: @@ -26,8 +27,9 @@ __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea import copy -import sqlalchemy -from sqlalchemy.orm import Query +from flask import Flask +import flask_sqlalchemy +from sqlalchemy.exc import OperationalError # # Custom libraries @@ -39,7 +41,7 @@ from mentat.datatype.sqldb import MODEL _MANAGER = None -class RetryingQuery(Query): +class RetryingQuery(flask_sqlalchemy.orm.Query): """ An override of SQLAlchemy's Query class, allowing for recovery from a lost DB connection. @@ -48,7 +50,7 @@ class RetryingQuery(Query): for _ in range(2): try: return super()._execute_and_instances(querycontext) - except sqlalchemy.exc.OperationalError: + except OperationalError: self.session.close() continue @@ -67,9 +69,14 @@ class StorageService: :param enginecfg: Connection arguments. """ - self.dbengine = sqlalchemy.engine_from_config(enginecfg, prefix = '') - self.sessionmaker = sqlalchemy.orm.sessionmaker(bind = self.dbengine) - self._session = self.sessionmaker(query_cls = RetryingQuery) + self.app = Flask(__name__) + self.app.config['SQLALCHEMY_DATABASE_URI'] = enginecfg['url'] + self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + + self.db = flask_sqlalchemy.SQLAlchemy(self.app) + self.dbengine = self.db.engine_from_config(enginecfg, prefix = '') + self.sessionmaker = flask_sqlalchemy.orm.sessionmaker(bind = self.dbengine) + self._session = self.sessionmaker(query_cls = RetryingQuery) def __del__(self): self.close() diff --git a/lib/mentat/services/whois.py b/lib/mentat/services/whois.py index 9fe799b7a..3a050ff07 100644 --- a/lib/mentat/services/whois.py +++ b/lib/mentat/services/whois.py @@ -270,10 +270,7 @@ class SqldbWhoisModule(WhoisModule): }) networks.append(netw) - # Use rollback to close transaction, please see issue #4251 for details. - # In short: In SQLAlchemy commit immediatelly opens new transaction, which - # then keeps hanging in "transaction-idle" state. - storage.session.rollback() + storage.session.commit() # Let the parent implementation take care of loading internal lookup table. return super().setup(networks) -- GitLab