Skip to content

python 3 support Geoalchemy supporter #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
*.pyc
/GeoAlchemy.egg-info
/doc/_build
/build/
/dist/
25 changes: 15 additions & 10 deletions geoalchemy/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@
from sqlalchemy.sql.expression import ColumnClause, literal
from sqlalchemy.types import UserDefinedType
from sqlalchemy.ext.compiler import compiles
import six

from utils import from_wkt
from functions import functions, _get_function, BaseFunction

if six.PY3:
from .utils import from_wkt
from .functions import functions, _get_function, BaseFunction
buffer = memoryview
ColumnComparator = ColumnProperty.Comparator
else:
from utils import from_wkt
from functions import functions, _get_function, BaseFunction
ColumnComparator = ColumnProperty.ColumnComparator
# Base classes for geoalchemy

class SpatialElement(object):
Expand Down Expand Up @@ -56,7 +63,7 @@ class WKTSpatialElement(SpatialElement, expression.Function):
"""

def __init__(self, desc, srid=4326, geometry_type='GEOMETRY'):
assert isinstance(desc, basestring)
assert isinstance(desc, six.string_types)
self.desc = desc
self.srid = srid
self.geometry_type = geometry_type
Expand Down Expand Up @@ -85,7 +92,7 @@ class WKBSpatialElement(SpatialElement, expression.Function):
"""

def __init__(self, desc, srid=4326, geometry_type='GEOMETRY'):
assert isinstance(desc, (basestring, buffer))
assert isinstance(desc, (six.binary_type, buffer)) # python3: buffer -> memoryview
self.desc = desc
self.srid = srid
self.geometry_type = geometry_type
Expand All @@ -96,11 +103,9 @@ def __init__(self, desc, srid=4326, geometry_type='GEOMETRY'):
def __compile_wkbspatialelement(element, compiler, **kw):
from geoalchemy.dialect import DialectManager
database_dialect = DialectManager.get_spatial_dialect(compiler.dialect)

function = _get_function(element, compiler, (database_dialect.bind_wkb_value(element),
element.srid),
kw.get('within_columns_clause', False))

return compiler.process(function)


Expand Down Expand Up @@ -201,7 +206,7 @@ def _to_gis(value, srid_db):
if isinstance(value.desc, (WKBSpatialElement, WKTSpatialElement)):
return _check_srid(value.desc, srid_db)
return _check_srid(value, srid_db)
elif isinstance(value, basestring):
elif isinstance(value, six.string_types):
return _check_srid(WKTSpatialElement(value), srid_db)
elif isinstance(value, expression.ClauseElement):
return value
Expand Down Expand Up @@ -239,7 +244,7 @@ def _make_proxy(self, selectable, name=None):
def __compile_rawcolumn(rawcolumn, compiler, **kw):
return compiler.visit_column(rawcolumn.column)

class SpatialComparator(ColumnProperty.ColumnComparator):
class SpatialComparator(ColumnComparator):
"""Intercepts standard Column operators on mapped class attributes
and overrides their behavior.

Expand All @@ -259,7 +264,7 @@ def RAW(self):
return RawColumn(self.__clause_element__())

def __getattr__(self, name):
return getattr(functions, name)(self)
return getattr(functions, name)(self.prop.columns[0])

# override the __eq__() operator (allows to use '==' on geometries)
def __eq__(self, other):
Expand Down
3 changes: 2 additions & 1 deletion geoalchemy/dialect.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from geoalchemy.functions import functions
from geoalchemy.base import WKTSpatialElement, WKBSpatialElement,\
DBSpatialElement
import six

class SpatialDialect(object):
"""This class bundles all required classes and methods to support
Expand Down Expand Up @@ -202,7 +203,7 @@ def get_spatial_dialect(dialect):

"""
possible_spatial_dialects = [spatial_dialect for (dialect_sqlalchemy, spatial_dialect)
in DialectManager.__dialects().iteritems()
in six.iteritems(DialectManager.__dialects())
if isinstance(dialect, dialect_sqlalchemy)]

if possible_spatial_dialects:
Expand Down
7 changes: 3 additions & 4 deletions geoalchemy/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from sqlalchemy.types import NullType, TypeDecorator
import types
import re
import six

WKT_REGEX = re.compile('.*\\(.*\\).*')

Expand All @@ -14,7 +15,6 @@ def parse_clause(clause, compiler):

"""
from geoalchemy.base import SpatialElement, WKTSpatialElement, WKBSpatialElement, DBSpatialElement, GeometryBase

if hasattr(clause, '__clause_element__'):
# for example a column name
return clause.__clause_element__()
Expand All @@ -27,7 +27,7 @@ def parse_clause(clause, compiler):
if isinstance(clause, DBSpatialElement):
return literal(clause.desc, GeometryBase)
return clause.desc
elif isinstance(clause, basestring) and WKT_REGEX.match(clause):
elif isinstance(clause, six.string_types) and WKT_REGEX.match(clause):
return WKTSpatialElement(clause)

# for raw parameters
Expand Down Expand Up @@ -117,7 +117,6 @@ def __call__(self, *arguments, **kwargs):

if len(kwargs) > 0:
self.flags.update(kwargs)

return self

class ReturnsGeometryFunction(BaseFunction):
Expand Down Expand Up @@ -148,7 +147,6 @@ def __compile_base_function(element, compiler, **kw):

from geoalchemy.dialect import DialectManager
database_dialect = DialectManager.get_spatial_dialect(compiler.dialect)

if database_dialect.is_member_function(element.__class__):
geometry = params.pop(0)
function_name = database_dialect.get_function(element.__class__)
Expand Down Expand Up @@ -184,6 +182,7 @@ def __compile_base_function(element, compiler, **kw):
)

else:

function = _get_function(element, compiler, params, kw.get('within_columns_clause', False))
return compiler.process(function)

Expand Down
4 changes: 2 additions & 2 deletions geoalchemy/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class GeometryExtensionColumn(Column):
@compiles(GeometryExtensionColumn)
def compile_column(element, compiler, **kw):
if isinstance(element.table, (Table, Alias)):
if kw.has_key("within_columns_clause") and kw["within_columns_clause"] == True:
if "within_columns_clause" in kw and kw["within_columns_clause"] == True:
if element.type.wkt_internal:
if isinstance(compiler.dialect, PGDialect):
return compiler.process(functions.wkt(element))
Expand All @@ -181,7 +181,7 @@ def GeometryColumn(*args, **kw):
set the properties for a geometry column when defining the mapping.

"""
if kw.has_key("comparator"):
if 'comparator' in kw:
comparator = kw.pop("comparator")
else:
comparator = SpatialComparator
Expand Down
17 changes: 15 additions & 2 deletions geoalchemy/mysql.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from sqlalchemy import func
from geoalchemy.base import SpatialComparator, PersistentSpatialElement,\
WKBSpatialElement
WKBSpatialElement, WKTSpatialElement
from geoalchemy.dialect import SpatialDialect
from geoalchemy.functions import functions, BaseFunction

Expand All @@ -12,7 +12,7 @@ def __getattr__(self, name):
try:
return SpatialComparator.__getattr__(self, name)
except AttributeError:
return getattr(mysql_functions, name)(self)
return getattr(mysql_functions, name)(self.prop.columns[0])


class MySQLPersistentSpatialElement(PersistentSpatialElement):
Expand Down Expand Up @@ -60,6 +60,15 @@ class mbr_contains(BaseFunction):
"""MBRContains(g1, g2)"""
pass

class st_within(BaseFunction):
"""ST_Within(g1, g2)"""
pass

class st_contains(BaseFunction):
"""ST_Within(g1, g2)"""
pass


@staticmethod
def _within_distance(compiler, geom1, geom2, distance, *args):
"""MySQL does not support the function distance, so we are doing
Expand Down Expand Up @@ -92,6 +101,8 @@ class MySQLSpatialDialect(SpatialDialect):
"""Implementation of SpatialDialect for MySQL."""

__functions = {
WKTSpatialElement: 'ST_GeomFromText',
functions.wkb: 'ST_AsBinary',
functions.length : 'GLength',
functions.is_valid : None,
functions.is_simple : None,
Expand All @@ -113,6 +124,8 @@ class MySQLSpatialDialect(SpatialDialect):
mysql_functions.mbr_within : 'MBRWithin',
mysql_functions.mbr_overlaps : 'MBROverlaps',
mysql_functions.mbr_contains : 'MBRContains',
mysql_functions.st_within: 'ST_Within',
mysql_functions.st_contains: 'ST_Contains',
functions._within_distance : mysql_functions._within_distance
}

Expand Down
2 changes: 1 addition & 1 deletion geoalchemy/oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def cast_param(params):
params.pop(0)
return func.ST_GEOMETRY(geom)

elif isinstance(geom, (WKBSpatialElement, WKTSpatialElement)) and geom.geometry_type <> Geometry.name:
elif isinstance(geom, (WKBSpatialElement, WKTSpatialElement)) and not geom.geometry_type == Geometry.name:
params.pop(0)
return getattr(func, 'ST_%s' % (geom.geometry_type))(geom)

Expand Down
Loading