Passed
Push — master ( a78ba8...963f51 )
by Dominik
14:35
created

OSMAlchemy.import_osm_file()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 2
ccs 2
cts 2
cp 1
rs 10
cc 1
crap 1
1
# ~*~ coding: utf-8 ~*~
2
#-
3
# OSMAlchemy - OpenStreetMap to SQLAlchemy bridge
4
# Copyright (c) 2016 Dominik George <[email protected]>
5
#
6
# Permission is hereby granted, free of charge, to any person obtaining a copy
7
# of this software and associated documentation files (the "Software"), to deal
8
# in the Software without restriction, including without limitation the rights
9
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
# copies of the Software, and to permit persons to whom the Software is
11
# furnished to do so, subject to the following conditions:
12
#
13
# The above copyright notice and this permission notice shall be included in all
14
# copies or substantial portions of the Software.
15
#
16
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
# SOFTWARE.
23
#
24
# Alternatively, you are free to use OSMAlchemy under Simplified BSD, The
25
# MirOS Licence, GPL-2+, LGPL-2.1+, AGPL-3+ or the same terms as Python
26
# itself.
27
28 1
""" Module that holds the main OSMAlchemy class.
29
30
The classe encapsulates the model and accompanying logic.
31
"""
32
33 1
from sqlalchemy.engine import Engine
34 1
from sqlalchemy.orm import sessionmaker, scoped_session
35 1
try:
36 1
    from flask_sqlalchemy import SQLAlchemy as FlaskSQLAlchemy
37
except ImportError:
38
    # non-fatal, Flask-SQLAlchemy support is optional
39
    # Create stub to avoid bad code later on
40
    class FlaskSQLAlchemy(object):
0 ignored issues
show
Coding Style introduced by
This class should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
41
        pass
42
43 1
from .model import _generate_model
44 1
from .online import _generate_overpass_api
45 1
from .util import _import_osm_file
46 1
from .triggers import _generate_triggers
47
48 1
class OSMAlchemy(object):
0 ignored issues
show
best-practice introduced by
Too many instance attributes (12/7)
Loading history...
49
    """ Wrapper class for the OSMAlchemy model and logic
50
51
    This class holds all the SQLAlchemy classes and logic that make up
52
    OSMAlchemy. It is contained in a separate class because it is a
53
    template that can be modified as needed by users, e.g. by using a
54
    different table prefix or a different declarative base.
55
    """
56
57 1
    def __init__(self, sa, prefix="osm_", overpass=None, maxage=60*60*24):
58
        """ Initialise the table definitions in the wrapper object
59
60
        This function generates the OSM element classes as SQLAlchemy table
61
        declaratives.
62
63
        Positional arguments:
64
65
          sa - reference to SQLAlchemy stuff; can be either of…
66
                 …an Engine instance, or…
67
                 …a tuple of (Engine, Base), or…
68
                 …a tuple of (Engine, Base, ScopedSession), or…
69
                 …a Flask-SQLAlchemy instance.
70
          prefix - optional; prefix for table names, defaults to "osm_"
71
          overpass - optional; API endpoint URL for Overpass API. Can be…
72
                      …None to disable loading data from Overpass (the default), or…
73
                      …True to enable the default endpoint URL, or…
74
                      …a string with a custom endpoint URL.
75
          maxage - optional; the maximum age after which elements are refreshed from
76
                   Overpass, in seconds, defaults to 86400s (1d)
77
        """
78
79
        # Create fields for SQLAlchemy stuff
80 1
        self.base = None
81 1
        self.engine = None
82 1
        self.session = None
83
84
        # Inspect sa argument
85 1
        if type(sa) is tuple:
0 ignored issues
show
introduced by
Using type() instead of isinstance() for a typecheck.
Loading history...
86 1
            self._engine = sa[0]
87 1
            self._base = sa[1]
88 1
            if len(sa) == 3:
89 1
                self._session = sa[2]
90 1
        elif type(sa) is Engine:
0 ignored issues
show
introduced by
Using type() instead of isinstance() for a typecheck.
Loading history...
91
            self._engine = sa
92
            self._base = declarative_base(bind=self._engine)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'declarative_base'
Loading history...
93
            self._session = scoped_session(sessionmaker(bind=self._engine))
94 1
        elif type(sa) is FlaskSQLAlchemy:
0 ignored issues
show
introduced by
Using type() instead of isinstance() for a typecheck.
Loading history...
95 1
            self._engine = sa.engine
96 1
            self._base = sa.Model
97 1
            self._session = sa.session
98
        else:
99
            raise TypeError("Invalid argument passed to sa parameter.")
100
101
        # Store prefix
102 1
        self._prefix = prefix
103
104
        # Store API endpoint for Overpass
105 1
        if overpass is not None:
106
            if overpass is True:
107
                self._overpass = _generate_overpass_api()
108
            else:
109
                self._overpass = _generate_overpass_api(overpass)
110
        else:
111 1
            self._overpass = None
112
113
        # Generate model and store as instance members
114 1
        self.Node, self.Way, self.Relation, self.Element = _generate_model(self._base,
0 ignored issues
show
Coding Style Naming introduced by
The name Node does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name Element does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name Way does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name Relation does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
115
                                                                           self._prefix)
116
117
        # Add triggers if online functionality is enabled
118 1
        if self._overpass is not None:
119
            _generate_triggers(self, maxage)
120
121 1
    def import_osm_file(self, session, path):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
122
        _import_osm_file(self, session, path)
123