From cf98be503e600ff0f3f74dcbfd37950ab4155259 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jan 29 2019 13:30:07 +0000 Subject: Move the create_session function into pagure.lib.model_base This allows importing it without importing the whole stack from pagure. Signed-off-by: Pierre-Yves Chibon --- diff --git a/dev-data.py b/dev-data.py index 0197be1..6f0ef27 100644 --- a/dev-data.py +++ b/dev-data.py @@ -694,7 +694,7 @@ if __name__ == "__main__": empty_dev_db(meta, eng) if args.populate or args.all: - session = pagure.lib.query.create_session(_config['DB_URL']) + session = pagure.lib.model_base.create_session(_config['DB_URL']) invalid_option = ['pingou', 'bar@pingou.com', 'foo', 'foo@bar.com'] print("") user_name = six.moves.input( diff --git a/files/api_key_expire_mail.py b/files/api_key_expire_mail.py index 78600ff..d7bf8d8 100755 --- a/files/api_key_expire_mail.py +++ b/files/api_key_expire_mail.py @@ -8,9 +8,10 @@ from datetime import datetime, timedelta from sqlalchemy.exc import SQLAlchemyError import pagure.config -import pagure.lib.query -import pagure.lib.notify import pagure.lib.model as model +import pagure.lib.model_base +import pagure.lib.notify +import pagure.lib.query if 'PAGURE_CONFIG' not in os.environ \ and os.path.exists('/etc/pagure/pagure.cfg'): @@ -29,7 +30,7 @@ def main(check=False, debug=False): email_dates = [email_day.date() for email_day in \ [current_time + timedelta(days=i) for i in day_diff_for_mail]] - session = pagure.lib.query.create_session(_config['DB_URL']) + session = pagure.lib.model_base.create_session(_config['DB_URL']) tokens = session.query(model.Token).all() for token in tokens: diff --git a/files/mirror_project_in.py b/files/mirror_project_in.py index b6ff20d..cfca629 100644 --- a/files/mirror_project_in.py +++ b/files/mirror_project_in.py @@ -8,9 +8,10 @@ from datetime import datetime, timedelta from sqlalchemy.exc import SQLAlchemyError import pagure.config -import pagure.lib.query -import pagure.lib.notify import pagure.lib.model as model +import pagure.lib.model_base +import pagure.lib.notify +import pagure.lib.query if 'PAGURE_CONFIG' not in os.environ \ and os.path.exists('/etc/pagure/pagure.cfg'): @@ -23,7 +24,7 @@ _config = pagure.config.reload_config() def main(check=False, debug=False): ''' The function pulls in all the changes from upstream''' - session = pagure.lib.query.create_session(_config['DB_URL']) + session = pagure.lib.model_base.create_session(_config['DB_URL']) projects = session.query( model.Project ).filter( diff --git a/pagure-ev/pagure_stream_server.py b/pagure-ev/pagure_stream_server.py index f3c314d..0e4a99a 100644 --- a/pagure-ev/pagure_stream_server.py +++ b/pagure-ev/pagure_stream_server.py @@ -40,6 +40,7 @@ if 'PAGURE_CONFIG' not in os.environ \ import pagure # noqa: E402 +import pagure.lib.model_base # noqa: E402 import pagure.lib.query # noqa: E402 from pagure.exceptions import PagureException, PagureEvException # noqa: E402 @@ -55,7 +56,7 @@ def _get_session(): global SESSION if SESSION is None: print(pagure.config.config['DB_URL']) - SESSION = pagure.lib.query.create_session( + SESSION = pagure.lib.model_base.create_session( pagure.config.config['DB_URL']) return SESSION diff --git a/pagure-milters/comment_email_milter.py b/pagure-milters/comment_email_milter.py index 9c5d01f..175a553 100644 --- a/pagure-milters/comment_email_milter.py +++ b/pagure-milters/comment_email_milter.py @@ -22,6 +22,7 @@ import requests from Milter.utils import parse_addr import pagure.config +import pagure.lib.model_base import pagure.lib.query @@ -157,7 +158,7 @@ class PagureMilter(Milter.Base): # they are trying to forge their ID into someone else's salt = _config.get('SALT_EMAIL') from_email = clean_item(msg['From']) - session = pagure.lib.query.create_session(_config['DB_URL']) + session = pagure.lib.model_base.create_session(_config['DB_URL']) try: user = pagure.lib.query.get_user(session, from_email) except: diff --git a/pagure/cli/admin.py b/pagure/cli/admin.py index 99f368d..7afa5af 100644 --- a/pagure/cli/admin.py +++ b/pagure/cli/admin.py @@ -30,13 +30,14 @@ if "PAGURE_CONFIG" not in os.environ and os.path.exists( import pagure.config # noqa: E402 import pagure.exceptions # noqa: E402 import pagure.lib.git # noqa: E402 +import pagure.lib.model_base # noqa: E402 import pagure.lib.query # noqa: E402 import pagure.lib.tasks_utils # noqa: E402 from pagure.flask_app import generate_user_key_files # noqa: E402 _config = pagure.config.reload_config() -session = pagure.lib.query.create_session(_config["DB_URL"]) +session = pagure.lib.model_base.create_session(_config["DB_URL"]) _log = logging.getLogger(__name__) @@ -1021,7 +1022,7 @@ def main(): global session, _config _config = pagure.config.reload_config() - session = pagure.lib.query.create_session(_config["DB_URL"]) + session = pagure.lib.model_base.create_session(_config["DB_URL"]) logging.basicConfig() if args.debug: diff --git a/pagure/docs_server.py b/pagure/docs_server.py index 3c923c5..1706c05 100644 --- a/pagure/docs_server.py +++ b/pagure/docs_server.py @@ -21,8 +21,9 @@ from binaryornot.helpers import is_binary_string import pagure.config import pagure.doc_utils import pagure.exceptions -import pagure.lib.query import pagure.lib.mimetype +import pagure.lib.model_base +import pagure.lib.query import pagure.forms # Create the application. @@ -31,7 +32,7 @@ APP = flask.Flask(__name__) # set up FAS APP.config = pagure.config.reload_config() -SESSION = pagure.lib.query.create_session(APP.config["DB_URL"]) +SESSION = pagure.lib.model_base.create_session(APP.config["DB_URL"]) if not APP.debug: APP.logger.addHandler( diff --git a/pagure/flask_app.py b/pagure/flask_app.py index dafe585..3f24e46 100644 --- a/pagure/flask_app.py +++ b/pagure/flask_app.py @@ -237,7 +237,7 @@ def set_request(): """ Prepare every request. """ flask.session.permanent = True if not hasattr(flask.g, "session") or not flask.g.session: - flask.g.session = pagure.lib.query.create_session( + flask.g.session = pagure.lib.model_base.create_session( flask.current_app.config["DB_URL"] ) diff --git a/pagure/hooks/__init__.py b/pagure/hooks/__init__.py index 750391e..c43db65 100644 --- a/pagure/hooks/__init__.py +++ b/pagure/hooks/__init__.py @@ -499,7 +499,7 @@ def run_hook_file(hooktype): raise ValueError("Hook type %s not valid" % hooktype) changes = extract_changes(from_stdin=hooktype != "update") - session = pagure.lib.query.create_session(pagure_config["DB_URL"]) + session = pagure.lib.model_base.create_session(pagure_config["DB_URL"]) if not session: raise Exception("Unable to initialize db session") diff --git a/pagure/hooks/files/repospannerhook b/pagure/hooks/files/repospannerhook index f0aa8cd..bf7f00c 100755 --- a/pagure/hooks/files/repospannerhook +++ b/pagure/hooks/files/repospannerhook @@ -22,6 +22,7 @@ if PYPATH: sys.path.append(PYPATH) import pagure +import pagure.lib.model_base import pagure.lib.query from pagure.hooks import run_project_hooks, extract_changes from pagure.config import config as pagure_config @@ -40,7 +41,7 @@ pruid = os.environ.get("extra_pull_request_uid", None) changes = extract_changes(from_stdin=hooktype != "update") -session = pagure.lib.query.create_session(pagure_config["DB_URL"]) +session = pagure.lib.model_base.create_session(pagure_config["DB_URL"]) if not session: raise Exception("Unable to initialize db session") diff --git a/pagure/lib/git_auth.py b/pagure/lib/git_auth.py index abc6b70..4a194b2 100644 --- a/pagure/lib/git_auth.py +++ b/pagure/lib/git_auth.py @@ -23,6 +23,7 @@ from six import with_metaclass from six.moves import dbm_gnu import pagure.exceptions +import pagure.lib.model_base import pagure.lib.query from pagure.config import config as pagure_config from pagure.lib import model @@ -752,7 +753,8 @@ class Gitolite2Auth(GitAuthHelper): _log.info("Refresh gitolite configuration") if project is not None or group is not None: - session = pagure.lib.query.create_session(pagure_config["DB_URL"]) + session = pagure.lib.model_base.create_session( + pagure_config["DB_URL"]) cls.write_gitolite_acls( session, project=project, diff --git a/pagure/lib/model.py b/pagure/lib/model.py index 4aec468..a1c1927 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -1049,7 +1049,7 @@ class ProjectLocker(object): self.ltype = ltype def __enter__(self): - from pagure.lib.query import create_session + from pagure.lib.model_base import create_session self.session = create_session() diff --git a/pagure/lib/model_base.py b/pagure/lib/model_base.py index 97b8969..32a0ea2 100644 --- a/pagure/lib/model_base.py +++ b/pagure/lib/model_base.py @@ -10,8 +10,11 @@ from __future__ import unicode_literals, absolute_import -from sqlalchemy import MetaData +import sqlalchemy from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import scoped_session + CONVENTION = { "ix": "ix_%(table_name)s_%(column_0_label)s", @@ -22,4 +25,54 @@ CONVENTION = { "uq": "%(table_name)s_%(column_0_name)s_key", } -BASE = declarative_base(metadata=MetaData(naming_convention=CONVENTION)) +BASE = declarative_base( + metadata=sqlalchemy.MetaData(naming_convention=CONVENTION)) + + +SESSIONMAKER = None + + +def create_session(db_url=None, debug=False, pool_recycle=3600): + """ Create the Session object to use to query the database. + + :arg db_url: URL used to connect to the database. The URL contains + information with regards to the database engine, the host to connect + to, the user and password and the database name. + ie: ://:@/ + :kwarg debug: a boolean specifying whether we should have the verbose + output of sqlalchemy or not. + :return a Session that can be used to query the database. + + """ + global SESSIONMAKER + + if SESSIONMAKER is None or ( + db_url and db_url != ("%s" % SESSIONMAKER.kw["bind"].engine.url) + ): + if db_url is None: + raise ValueError("First call to create_session needs db_url") + if db_url.startswith("postgres"): # pragma: no cover + engine = sqlalchemy.create_engine( + db_url, + echo=debug, + pool_recycle=pool_recycle, + client_encoding="utf8", + ) + else: # pragma: no cover + engine = sqlalchemy.create_engine( + db_url, echo=debug, pool_recycle=pool_recycle + ) + + if db_url.startswith("sqlite:"): + # Ignore the warning about con_record + # pylint: disable=unused-argument + def _fk_pragma_on_connect(dbapi_con, _): # pragma: no cover + """ Tries to enforce referential constraints on sqlite. """ + dbapi_con.execute("pragma foreign_keys=ON") + + sqlalchemy.event.listen(engine, "connect", _fk_pragma_on_connect) + SESSIONMAKER = sessionmaker(bind=engine) + + scopedsession = scoped_session(SESSIONMAKER) + BASE.metadata.bind = scopedsession + return scopedsession diff --git a/pagure/lib/query.py b/pagure/lib/query.py index f84d387..07fd94d 100644 --- a/pagure/lib/query.py +++ b/pagure/lib/query.py @@ -48,8 +48,6 @@ from six.moves.urllib_parse import urlparse, urlencode, parse_qsl from sqlalchemy import func from sqlalchemy import asc, desc from sqlalchemy.orm import aliased -from sqlalchemy.orm import sessionmaker -from sqlalchemy.orm import scoped_session from flask import url_for import pagure.exceptions @@ -64,6 +62,8 @@ import pagure.pfmarkdown import pagure.utils from pagure.config import config as pagure_config from pagure.lib import model +# For backward compatibility since this function used to be in this file +from pagure.lib.model_base import create_session REDIS = None @@ -139,55 +139,6 @@ def get_user_by_id(session, userid): return query.first() -SESSIONMAKER = None - - -def create_session(db_url=None, debug=False, pool_recycle=3600): - """ Create the Session object to use to query the database. - - :arg db_url: URL used to connect to the database. The URL contains - information with regards to the database engine, the host to connect - to, the user and password and the database name. - ie: ://:@/ - :kwarg debug: a boolean specifying whether we should have the verbose - output of sqlalchemy or not. - :return a Session that can be used to query the database. - - """ - global SESSIONMAKER - - if SESSIONMAKER is None or ( - db_url and db_url != ("%s" % SESSIONMAKER.kw["bind"].engine.url) - ): - if db_url is None: - raise ValueError("First call to create_session needs db_url") - if db_url.startswith("postgres"): # pragma: no cover - engine = sqlalchemy.create_engine( - db_url, - echo=debug, - pool_recycle=pool_recycle, - client_encoding="utf8", - ) - else: # pragma: no cover - engine = sqlalchemy.create_engine( - db_url, echo=debug, pool_recycle=pool_recycle - ) - - if db_url.startswith("sqlite:"): - # Ignore the warning about con_record - # pylint: disable=unused-argument - def _fk_pragma_on_connect(dbapi_con, _): # pragma: no cover - """ Tries to enforce referential constraints on sqlite. """ - dbapi_con.execute("pragma foreign_keys=ON") - - sqlalchemy.event.listen(engine, "connect", _fk_pragma_on_connect) - SESSIONMAKER = sessionmaker(bind=engine) - - scopedsession = scoped_session(SESSIONMAKER) - model.BASE.metadata.bind = scopedsession - return scopedsession - - def get_next_id(session, projectid): """ Returns the next identifier of a project ticket or pull-request based on the identifier already in the database. diff --git a/pagure/lib/tasks_utils.py b/pagure/lib/tasks_utils.py index 9e224d9..7de20b2 100644 --- a/pagure/lib/tasks_utils.py +++ b/pagure/lib/tasks_utils.py @@ -13,7 +13,7 @@ from __future__ import unicode_literals, absolute_import import gc from functools import wraps -import pagure.lib.query +import pagure.lib.model_base from pagure.config import config as pagure_config @@ -31,7 +31,8 @@ def pagure_task(function): self.update_state(state="RUNNING") except TypeError: pass - session = pagure.lib.query.create_session(pagure_config["DB_URL"]) + session = pagure.lib.model_base.create_session( + pagure_config["DB_URL"]) try: return function(self, session, *args, **kwargs) except: # noqa: E722 diff --git a/pagure/ui/login.py b/pagure/ui/login.py index e5be27c..e70ba42 100644 --- a/pagure/ui/login.py +++ b/pagure/ui/login.py @@ -22,6 +22,7 @@ from six.moves.urllib.parse import urljoin import pagure.login_forms as forms import pagure.lib.login import pagure.lib.model as model +import pagure.lib.model_base import pagure.lib.notify import pagure.lib.query from pagure.utils import login_required @@ -435,7 +436,7 @@ def _check_session_cookie(): """ Set the user into flask.g if the user is logged in. """ if not hasattr(flask.g, "session") or not flask.g.session: - flask.g.session = pagure.lib.query.create_session( + flask.g.session = pagure.lib.model_base.create_session( flask.current_app.config["DB_URL"] )