<commit_before>"""Database utilities."""

from contextlib import contextmanager

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

__all__ = ('Database',)


def connection_url(settings):
    """Return a SQLAlchemy database URI."""
    settings = from_settings(settings)
    template = \
        '{type}+{driver}://{username}:{password}@{host}:{port}/{database}'
    return template.format(**settings)


def from_settings(settings):
    """Return a dict created from application settings."""
    return {
        k.replace('DATABASE_', '', 1).lower(): v
        for k, v in settings.items()
        if k.startswith('DATABASE_')}


def to_settings(settings):
    """Return a dict of application settings."""
    return {'DATABASE_{}'.format(k.upper()): v for k, v in settings.items()}


class Database:

    """An interface to interact with a relational database.

    Args:
        app (optional): An application instance that has an attribute
          named settings that contains a mapping of settings to interact
          with a database.
    """

    def __init__(self, app=None):
        """Initialize an instance."""
        self._engine = None
        self._model_base = None
        self._sessionmaker = None

        self.app = app
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        """Initialize an application for use with the database.

        Args:
            app: Application instance that has an attribute named
              settings that contains a mapping of settings needed to
              interact with the database.
        """
        app.settings.setdefault('DATABASE_HOST', 'localhost')
        app.settings.setdefault('DATABASE_PORT', 1433)
        app.settings.setdefault('DATABASE_TYPE', 'mssql')
        app.settings.setdefault('DATABASE_DRIVER', 'pymssql')

        if 'DATABASE' in app.settings:
            app.settings.update(to_settings(app.settings['DATABASE']))

    @property
    def engine(self):
        """Return the SQLAlchemy engine."""
        if not self._engine:
            self._engine = create_engine(connection_url(self.app.settings))

        return self._engine

    @property
    def Model(self):  # NOQA, not really serving as a function
        """Return the SQLAlchemy base declarative model."""
        if not self._model_base:
            self._model_base = declarative_base(bind=self.engine)

        return self._model_base

    @contextmanager
    def session(self):
        """Return a context manager for a SQLAlchemy session.

        Yields:
            The session.
        """
        session = self.sessionmaker()
        try:
            yield session
        finally:
            session.close()

    @property
    def sessionmaker(self):
        """Return the SQLAlchemy session maker."""
        if not self._sessionmaker:
            self._sessionmaker = sessionmaker(bind=self.engine)

        return self._sessionmaker<commit_msg>Allow models to be defined without the engine<commit_after>"""Database utilities."""

from contextlib import contextmanager

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

__all__ = ('Database',)


def connection_url(settings):
    """Return a SQLAlchemy database URI."""
    settings = from_settings(settings)
    template = \
        '{type}+{driver}://{username}:{password}@{host}:{port}/{database}'
    return template.format(**settings)


def from_settings(settings):
    """Return a dict created from application settings."""
    return {
        k.replace('DATABASE_', '', 1).lower(): v
        for k, v in settings.items()
        if k.startswith('DATABASE_')}


def to_settings(settings):
    """Return a dict of application settings."""
    return {'DATABASE_{}'.format(k.upper()): v for k, v in settings.items()}


class Database:

    """An interface to interact with a relational database.

    Args:
        app (optional): An application instance that has an attribute
          named settings that contains a mapping of settings to interact
          with a database.
    """

    def __init__(self, app=None):
        """Initialize an instance."""
        self._engine = None
        self._model_base = None
        self._sessionmaker = None

        self.app = app
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        """Initialize an application for use with the database.

        Args:
            app: Application instance that has an attribute named
              settings that contains a mapping of settings needed to
              interact with the database.
        """
        app.settings.setdefault('DATABASE_HOST', 'localhost')
        app.settings.setdefault('DATABASE_PORT', 1433)
        app.settings.setdefault('DATABASE_TYPE', 'mssql')
        app.settings.setdefault('DATABASE_DRIVER', 'pymssql')

        if 'DATABASE' in app.settings:
            app.settings.update(to_settings(app.settings['DATABASE']))

    @property
    def engine(self):
        """Return the SQLAlchemy engine."""
        if not self._engine:
            self._engine = create_engine(connection_url(self.app.settings))

        return self._engine

    @property
    def Model(self):  # NOQA, not really serving as a function
        """Return the SQLAlchemy base declarative model."""
        if not self._model_base:
            self._model_base = declarative_base()

        return self._model_base

    @contextmanager
    def session(self):
        """Return a context manager for a SQLAlchemy session.

        Yields:
            The session.
        """
        session = self.sessionmaker()
        try:
            yield session
        finally:
            session.close()

    @property
    def sessionmaker(self):
        """Return the SQLAlchemy session maker."""
        if not self._sessionmaker:
            self._sessionmaker = sessionmaker(bind=self.engine)

        return self._sessionmaker
{'fraction_non_alphanumeric': 0.10147783251231528, 'fraction_numerical': 0.0016420361247947454, 'mean_word_length': 2.535113174695299, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '473391', 'n_tokens_mistral': 1650, 'n_tokens_neox': 1591, 'n_words': 488}