From 87b875d2934ba238a078c801aa8d9ff91ff619c7 Mon Sep 17 00:00:00 2001
From: Jakub Judiny <judiny@cesnet.cz>
Date: Tue, 9 May 2023 14:10:54 +0200
Subject: [PATCH] Replace flask-sqlalchemy with sqlalchemy in sqlstorage.py,
 upgrade both (Redmine issue: #7642)

---
 conf/requirements.pip             |  4 ++--
 lib/mentat/services/sqlstorage.py | 23 ++++++++---------------
 2 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/conf/requirements.pip b/conf/requirements.pip
index 853c1626..e671a2db 100644
--- a/conf/requirements.pip
+++ b/conf/requirements.pip
@@ -3,7 +3,7 @@ psycopg2>=2.9.6,<2.10.0
 babel>=2.12.1,<2.13.0
 wtforms[email]>=3.0.1,<4.0.0
 wtforms_sqlalchemy>=0.3,<1.0.0
-sqlalchemy>=1.4.47,<2.0.0
+sqlalchemy>=2.0.12,<=3.0.0
 alembic>=1.10.2,<2.0.0
 jinja2>=3.1.2,<3.2.0
 bsddb3>=6.2.9,<6.3.0
@@ -16,7 +16,7 @@ flask-babel>=3.0.1,<4.0.0
 flask-principal>=0.4.0,<1.0.0
 flask-wtf>=1.1.1,<2.0.0
 flask-script>=2.0.6,<3.0.0
-flask-sqlalchemy>=2.5.1,<3.0.0
+flask-sqlalchemy>=3.0.3,<4.0.0
 flask-debugtoolbar>=0.13.1,<1.0.0
 flask-jsglue>=0.3.1,<1.0.0
 dnspython>=2.3.0,<3.0.0
diff --git a/lib/mentat/services/sqlstorage.py b/lib/mentat/services/sqlstorage.py
index c029f4eb..eb4e7c95 100644
--- a/lib/mentat/services/sqlstorage.py
+++ b/lib/mentat/services/sqlstorage.py
@@ -10,8 +10,7 @@
 
 """
 Database storage abstraction layer. The current implementation is based on the
-awesome `SQLAlchemy <http://www.sqlalchemy.org/>`__ library accessed by
-`flask_sqlalchemy <https://flask-sqlalchemy.palletsprojects.com/>`__.
+awesome `SQLAlchemy <http://www.sqlalchemy.org/>`__ library.
 
 .. warning::
 
@@ -27,8 +26,7 @@ __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea
 
 
 import copy
-from flask import Flask
-import flask_sqlalchemy
+import sqlalchemy
 
 #
 # Custom libraries
@@ -40,7 +38,7 @@ from mentat.datatype.sqldb import MODEL
 _MANAGER = None
 
 
-class RetryingQuery(flask_sqlalchemy.orm.Query):
+class RetryingQuery(sqlalchemy.orm.Query):
     """
     An override of SQLAlchemy's Query class, allowing for recovery from a lost DB
     connection.
@@ -49,7 +47,7 @@ class RetryingQuery(flask_sqlalchemy.orm.Query):
         for _ in range(2):
             try:
                 return super()._execute_and_instances(querycontext)
-            except flask_sqlalchemy.orm.exc.sa_exc.OperationalError:
+            except sqlalchemy.exc.OperationalError:
                 self.session.close()
                 continue
 
@@ -68,14 +66,9 @@ class StorageService:
 
         :param enginecfg: Connection arguments.
         """
-        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)
+        self.dbengine     = sqlalchemy.engine_from_config(enginecfg, prefix = '')
+        self.sessionmaker = sqlalchemy.orm.scoped_session(sqlalchemy.orm.sessionmaker(bind = self.dbengine))
+        self._session     = self.sessionmaker(query_cls = RetryingQuery)
 
     def __del__(self):
         self.close()
@@ -101,7 +94,7 @@ class StorageService:
 
         """
         if self._session:
-            self._session.close()
+            self.sessionmaker.remove()
             self._session = None
 
     def session_new(self):
-- 
GitLab