Blame pagure/lib/model_base.py

Patrick Uiterwijk 4012dc
# -*- coding: utf-8 -*-
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
"""
Patrick Uiterwijk 4012dc
 (c) 2014-2018 - Copyright Red Hat Inc
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
 Authors:
Patrick Uiterwijk 4012dc
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
"""
Patrick Uiterwijk 4012dc
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Patrick Uiterwijk 4012dc
Pierre-Yves Chibon cf98be
import sqlalchemy
Patrick Uiterwijk 4012dc
from sqlalchemy.ext.declarative import declarative_base
Pierre-Yves Chibon cf98be
from sqlalchemy.orm import sessionmaker
Pierre-Yves Chibon cf98be
from sqlalchemy.orm import scoped_session
Pierre-Yves Chibon cf98be
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
CONVENTION = {
Patrick Uiterwijk 4012dc
    "ix": "ix_%(table_name)s_%(column_0_label)s",
Patrick Uiterwijk 4012dc
    # Checks are currently buggy and prevent us from naming them correctly
Patrick Uiterwijk 4012dc
    # "ck": "ck_%(table_name)s_%(constraint_name)s",
Patrick Uiterwijk 4012dc
    "fk": "%(table_name)s_%(column_0_name)s_fkey",
Patrick Uiterwijk 4012dc
    "pk": "%(table_name)s_pkey",
Patrick Uiterwijk 4012dc
    "uq": "%(table_name)s_%(column_0_name)s_key",
Patrick Uiterwijk 4012dc
}
Patrick Uiterwijk 4012dc
Pierre-Yves Chibon cf98be
BASE = declarative_base(
Pierre-Yves Chibon 8e9b7f
    metadata=sqlalchemy.MetaData(naming_convention=CONVENTION)
Pierre-Yves Chibon 8e9b7f
)
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
SESSIONMAKER = None
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
def create_session(db_url=None, debug=False, pool_recycle=3600):
Pierre-Yves Chibon cf98be
    """ Create the Session object to use to query the database.
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
    :arg db_url: URL used to connect to the database. The URL contains
Pierre-Yves Chibon cf98be
    information with regards to the database engine, the host to connect
Pierre-Yves Chibon cf98be
    to, the user and password and the database name.
Pierre-Yves Chibon cf98be
      ie: <engine>://<user>:<password>@<host>/<dbname></dbname></host></password></user></engine>
Pierre-Yves Chibon cf98be
    :kwarg debug: a boolean specifying whether we should have the verbose
Pierre-Yves Chibon cf98be
        output of sqlalchemy or not.
Pierre-Yves Chibon cf98be
    :return a Session that can be used to query the database.
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
    """
Pierre-Yves Chibon cf98be
    global SESSIONMAKER
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
    if SESSIONMAKER is None or (
Pierre-Yves Chibon cf98be
        db_url and db_url != ("%s" % SESSIONMAKER.kw["bind"].engine.url)
Pierre-Yves Chibon cf98be
    ):
Pierre-Yves Chibon cf98be
        if db_url is None:
Pierre-Yves Chibon cf98be
            raise ValueError("First call to create_session needs db_url")
Pierre-Yves Chibon cf98be
        if db_url.startswith("postgres"):  # pragma: no cover
Pierre-Yves Chibon cf98be
            engine = sqlalchemy.create_engine(
Pierre-Yves Chibon cf98be
                db_url,
Pierre-Yves Chibon cf98be
                echo=debug,
Pierre-Yves Chibon cf98be
                pool_recycle=pool_recycle,
Pierre-Yves Chibon cf98be
                client_encoding="utf8",
Pierre-Yves Chibon cf98be
            )
Pierre-Yves Chibon cf98be
        else:  # pragma: no cover
Pierre-Yves Chibon cf98be
            engine = sqlalchemy.create_engine(
Pierre-Yves Chibon cf98be
                db_url, echo=debug, pool_recycle=pool_recycle
Pierre-Yves Chibon cf98be
            )
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
        if db_url.startswith("sqlite:"):
Pierre-Yves Chibon cf98be
            # Ignore the warning about con_record
Pierre-Yves Chibon cf98be
            # pylint: disable=unused-argument
Pierre-Yves Chibon cf98be
            def _fk_pragma_on_connect(dbapi_con, _):  # pragma: no cover
Pierre-Yves Chibon cf98be
                """ Tries to enforce referential constraints on sqlite. """
Pierre-Yves Chibon cf98be
                dbapi_con.execute("pragma foreign_keys=ON")
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
            sqlalchemy.event.listen(engine, "connect", _fk_pragma_on_connect)
Pierre-Yves Chibon cf98be
        SESSIONMAKER = sessionmaker(bind=engine)
Pierre-Yves Chibon cf98be
Pierre-Yves Chibon cf98be
    scopedsession = scoped_session(SESSIONMAKER)
Pierre-Yves Chibon cf98be
    BASE.metadata.bind = scopedsession
Pierre-Yves Chibon cf98be
    return scopedsession