Passed
Push — dev ( f6dceb...782bb6 )
by Uwe
01:13
created

db.connect   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 117
rs 10
c 0
b 0
f 0
wmc 6

3 Functions

Rating   Name   Duplication   Size   Complexity  
A connection() 0 10 1
A url() 0 62 4
A engine() 0 28 1
1
from configparser import NoOptionError, NoSectionError
2
import getpass
3
4
from sqlalchemy import create_engine
5
import keyring
6
7
from . import config as cfg
8
9
__version__ = '0.0.6'
10
11
12
def url(section="postGIS", config_file=None):
13
    """ Retrieve the URL used to connect to the database.
14
15
    Use this if you have your own means of accessing the database and do not
16
    want to use :func:`engine` or :func:`connection`.
17
18
    Parameters
19
    ----------
20
    section : str, optional
21
        The `config.ini` section corresponding to the targeted database.
22
        It should contain all the details that needed to set up a connection.
23
24
    Returns
25
    -------
26
    database URL : str
27
        The URL with which one can connect to the database. Be careful as this
28
        will probably contain sensitive data like the username/password
29
        combination.
30
    config_file : str, optional
31
        Relative of absolute of config.ini. If not specified, it tries to read
32
        from .oemof/config.ini in your HOME dir
33
34
    Notes
35
    -----
36
37
    For documentation on config.ini see the README section on
38
    :ref:`configuring <readme#configuration>` :mod:`oemof.db`.
39
    """
40
41
    cfg.load_config(config_file)
42
43
    try:
44
        pw = keyring.get_password(
45
            cfg.get(section, "database"), cfg.get(section, "username")
46
        )
47
    except NoSectionError:
48
        msg = (
49
            "There is no section {section} in your config file. Please "
50
            "choose one available section from your config file or "
51
            "specify a new one!".format(section=section)
52
        )
53
        raise NoSectionError(msg)
54
55
    if pw is None:
56
        try:
57
            pw = cfg.get(section, "pw")
58
        except NoOptionError:
59
            pw = getpass.getpass(
60
                prompt="No password available in your "
61
                "keyring for database {database}. "
62
                "\n\nEnter your password to "
63
                "store it in "
64
                "keyring:".format(database=section)
65
            )
66
            keyring.set_password(section, cfg.get(section, "username"), pw)
67
68
    return "postgresql+psycopg2://{user}:{passwd}@{host}:{port}/{db}".format(
69
        user=cfg.get(section, "username"),
70
        passwd=pw,
71
        host=cfg.get(section, "host"),
72
        db=cfg.get(section, "database"),
73
        port=int(cfg.get(section, "port")),
74
    )
75
76
77
def engine(section="postGIS", config_file=None):
78
    """Creates engine object for database access
79
80
    If keyword argument `section` is used it requires an existing config.ini
81
    file at the right location.
82
83
    Parameters
84
    ----------
85
    section : str, optional
86
        Section (in config.ini) of targeted database containing connection
87
        details that are used to set up connection
88
    config_file : str, optional
89
        Relative of absolute of config.ini. If not specified, it tries to read
90
        from .oemof/config.ini in your HOME dir
91
92
    Returns
93
    -------
94
    engine : :class:`sqlalchemy.engine.Engine`
95
        Engine for sqlalchemy
96
97
    Notes
98
    -----
99
100
    For documentation on config.ini see the README section on
101
    :ref:`configuring <readme#configuration>` :mod:`oemof.db`.
102
    """
103
104
    return create_engine(url(section, config_file=config_file))
105
106
107
def connection(section="postGIS", config_file=None):
108
    """Database connection method of sqlalchemy engine object
109
110
    This function purely calls the `connect()` method of the engine object
111
    returned by :py:func:`engine`.
112
113
    For description of parameters see :py:func:`engine`.
114
    """
115
116
    return engine(section=section, config_file=config_file).connect()
117