Skip to content

Commit

Permalink
added docs and refactoring to improve code readibility
Browse files Browse the repository at this point in the history
  • Loading branch information
matley committed Apr 30, 2012
1 parent ae38b71 commit 8a860e8
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 40 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -2,3 +2,5 @@
*.db
nosetest*
.coverage
*~
#*#
8 changes: 8 additions & 0 deletions README
@@ -1,2 +1,10 @@
==Description==
The Earthquake Catalogue Tool allows to extract informations from earthquake
catalogues specified in different formats.


==Requirements==

You need to install pysqlite2 and spatialite library (>= 3.0). Please, ensure that you are using a sqlite3 with load extension capabilities (the one provided with macports is good) and that spatialite library location is in your ld library path.

Mac OS X user note: you have to download pysqlite2 and install manually as you need to comment out (in the setup.cfg) the line containing `define=SQLITE_OMIT_LOAD_EXTENSION`
120 changes: 80 additions & 40 deletions eqcatalogue/models.py
Expand Up @@ -21,6 +21,12 @@
'min_distance', 'max_distance',
'num_stations')

## We used non-declarative model mapping, as we need to define model
## at runtime (not at module import time). Actually, only at runtime
## we can load the spatialite extension and then the spatialite
## metadata needed by geoalchemy to build the orm (see
## CatalogueDatabase._setup)


class EventSource(object):
"""A source of event catalogues. E.g. ISC Web Catalogue
Expand Down Expand Up @@ -240,43 +246,9 @@ def __init__(self, filename=None, memory=False, drop=False):
self._metadata = None
self._setup(filename=filename, memory=memory, drop=drop)

def _connect(self, dbapi_connection, connection_rec=None):
"""Enable load extension on connect. Event handler triggered
by sqlalchemy"""
dbapi_connection.enable_load_extension(True)
self._load_extension(dbapi_connection)
if connection_rec:
pass

def _load_extension(self, session):
"""Load spatial lite extension in `session`
:param:: session:
A sqlalchemy session."""

try:
session.execute("select load_extension('libspatialite.so')")
except sqlite.OperationalError:
try:
session.execute("select load_extension('libspatialite.dylib')")
except sqlite.OperationalError:
try:
session.execute(
"select load_extension('libspatialite.dll')")
except:
raise RuntimeError("""
Could not load libspatial extension.
Check your spatialite and pysqlite2 installation"""
)

try:
session.execute('select * from spatial_ref_sys')
except sqlite.OperationalError:
_initialize_spatialite_db(session)

def _setup(self, memory=False, filename=None, drop=False):
"""Setup a sqlalchemy connection to spatialite with the proper
setup."""
metadata."""

if memory:
self._engine = sqlalchemy.create_engine('sqlite://', module=sqlite)
Expand All @@ -289,20 +261,18 @@ def _setup(self, memory=False, filename=None, drop=False):
pool_size=1)
sqlevent.listen(self._engine,
"first_connect",
lambda c, r: self._connect(c, r))
_connect)
self.session = orm.sessionmaker(bind=self._engine)()
self._metadata = sqlalchemy.MetaData(self._engine)
self._create_schema()
if drop:
self._metadata.drop_all()
self._metadata.create_all(self._engine)

def _create_schema(self):
"""Create and contains the model definition"""

def _create_schema_eventsource(self):
"""Create Event Source Schema"""
metadata = self._metadata

orm.clear_mappers()
eventsource = sqlalchemy.Table(
'catalogue_eventsource', metadata,
sqlalchemy.Column('id', sqlalchemy.Integer,
Expand All @@ -315,6 +285,11 @@ def _create_schema(self):
orm.Mapper(EventSource, eventsource)
geoalchemy.GeometryDDL(eventsource)

def _create_schema_agency(self):
"""Create the schema for the Agency model"""

metadata = self._metadata

agency = sqlalchemy.Table(
'catalogue_agency', metadata,
sqlalchemy.Column('id',
Expand All @@ -335,6 +310,11 @@ def _create_schema(self):
})
geoalchemy.GeometryDDL(agency)

def _create_schema_event(self):
"""Create the schema for the Event model"""

metadata = self._metadata

event = sqlalchemy.Table(
'catalogue_event', metadata,
sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
Expand All @@ -351,6 +331,11 @@ def _create_schema(self):
})
geoalchemy.GeometryDDL(event)

def _create_schema_magnitudemeasure(self):
"""Create the schema for the magnitude measure model"""

metadata = self._metadata

magnitudemeasure = sqlalchemy.Table(
'catalogue_magnitudemeasure', metadata,
sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
Expand Down Expand Up @@ -380,6 +365,9 @@ def _create_schema(self):
})
geoalchemy.GeometryDDL(magnitudemeasure)

def _create_schema_origin(self):
"""Create the schema for the Origin model"""
metadata = self._metadata
origin = sqlalchemy.Table(
'catalogue_origin', metadata,
sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
Expand Down Expand Up @@ -412,6 +400,11 @@ def _create_schema(self):
'position': geoalchemy.GeometryColumn(origin.c.position)})
geoalchemy.GeometryDDL(origin)

def _create_schema_measuremetadata(self):
"""Create the schema for the measure metadata model"""

metadata = self._metadata

measuremetadata = sqlalchemy.Table(
'catalogue_measuremetadata', metadata,
sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
Expand All @@ -430,6 +423,18 @@ def _create_schema(self):
backref=orm.backref('metadatas'))})
geoalchemy.GeometryDDL(measuremetadata)

def _create_schema(self):
"""Create and contains the model definition"""

orm.clear_mappers()

self._create_schema_eventsource()
self._create_schema_agency()
self._create_schema_event()
self._create_schema_magnitudemeasure()
self._create_schema_origin()
self._create_schema_measuremetadata()


def _initialize_spatialite_db(connection):
"""Initialize Spatialite Database. Needed only when a newly
Expand All @@ -445,3 +450,38 @@ def _initialize_spatialite_db(connection):
"+ellps=WGS84 +datum=WGS84 +no_defs')")
except sqlite.IntegrityError:
pass


def _load_extension(session):
"""Load spatial lite extension in `session`
:param:: session:
A sqlalchemy session."""

try:
session.execute("select load_extension('libspatialite.so')")
except sqlite.OperationalError:
try:
session.execute("select load_extension('libspatialite.dylib')")
except sqlite.OperationalError:
try:
session.execute(
"select load_extension('libspatialite.dll')")
except:
raise RuntimeError("""
Could not load libspatial extension.
Check your spatialite and pysqlite2 installation"""
)
try:
session.execute('select * from spatial_ref_sys')
except sqlite.OperationalError:
_initialize_spatialite_db(session)


def _connect(dbapi_connection, connection_rec=None):
"""Enable load extension on connect. Event handler triggered
by sqlalchemy"""
dbapi_connection.enable_load_extension(True)
_load_extension(dbapi_connection)
if connection_rec:
pass
2 changes: 2 additions & 0 deletions requirements.txt
@@ -0,0 +1,2 @@
geoalchemy
pysqlite2

0 comments on commit 8a860e8

Please sign in to comment.