Commit a1fbc0dc authored by Justin Bronn's avatar Justin Bronn
Browse files

Fixed #12637 -- GeoDjango's `inspectdb` command is now a subclass of Django's,...

Fixed #12637 -- GeoDjango's `inspectdb` command is now a subclass of Django's, and works with all spatial backends (Oracle and SpatiaLite did work before).  This changeset introduces new introspection modules for all of the spatial backends and adds hooks to the original `inspectdb.Command` class to enable reuse.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@12257 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 58440c0b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
from django.db.backends.mysql.base import *
from django.db.backends.mysql.base import DatabaseWrapper as MySQLDatabaseWrapper
from django.contrib.gis.db.backends.mysql.creation import MySQLCreation
from django.contrib.gis.db.backends.mysql.introspection import MySQLIntrospection
from django.contrib.gis.db.backends.mysql.operations import MySQLOperations

class DatabaseWrapper(MySQLDatabaseWrapper):
@@ -9,3 +10,4 @@ class DatabaseWrapper(MySQLDatabaseWrapper):
        super(DatabaseWrapper, self).__init__(*args, **kwargs)
        self.creation = MySQLCreation(self)
        self.ops = MySQLOperations()
        self.introspection = MySQLIntrospection(self)
+32 −0
Original line number Diff line number Diff line
from MySQLdb.constants import FIELD_TYPE

from django.contrib.gis.gdal import OGRGeomType
from django.db.backends.mysql.introspection import DatabaseIntrospection

class MySQLIntrospection(DatabaseIntrospection):
    # Updating the data_types_reverse dictionary with the appropriate
    # type for Geometry fields.
    data_types_reverse = DatabaseIntrospection.data_types_reverse.copy()
    data_types_reverse[FIELD_TYPE.GEOMETRY] = 'GeometryField'

    def get_geometry_type(self, table_name, geo_col):
        cursor = self.connection.cursor()
        try:
            # In order to get the specific geometry type of the field,
            # we introspect on the table definition using `DESCRIBE`.
            cursor.execute('DESCRIBE %s' %
                           self.connection.ops.quote_name(table_name))
            # Increment over description info until we get to the geometry
            # column.
            for column, typ, null, key, default, extra in cursor.fetchall():
                if column == geo_col:
                    # Using OGRGeomType to convert from OGC name to Django field.
                    # MySQL does not support 3D or SRIDs, so the field params
                    # are empty.
                    field_type = OGRGeomType(typ).django
                    field_params = {}
                    break
        finally:
            cursor.close()

        return field_type, field_params
+3 −1
Original line number Diff line number Diff line
from django.db.backends.oracle.base import *
from django.db.backends.oracle.base import DatabaseWrapper as OracleDatabaseWrapper
from django.contrib.gis.db.backends.oracle.creation import OracleCreation
from django.contrib.gis.db.backends.oracle.introspection import OracleIntrospection
from django.contrib.gis.db.backends.oracle.operations import OracleOperations

class DatabaseWrapper(OracleDatabaseWrapper):
    def __init__(self, *args, **kwargs):
        super(DatabaseWrapper, self).__init__(*args, **kwargs)
        self.creation = OracleCreation(self)
        self.ops = OracleOperations(self)
        self.creation = OracleCreation(self)
        self.introspection = OracleIntrospection(self)
+39 −0
Original line number Diff line number Diff line
import cx_Oracle
from django.db.backends.oracle.introspection import DatabaseIntrospection

class OracleIntrospection(DatabaseIntrospection):
    # Associating any OBJECTVAR instances with GeometryField.  Of course,
    # this won't work right on Oracle objects that aren't MDSYS.SDO_GEOMETRY,
    # but it is the only object type supported within Django anyways.
    data_types_reverse = DatabaseIntrospection.data_types_reverse.copy()
    data_types_reverse[cx_Oracle.OBJECT] = 'GeometryField'

    def get_geometry_type(self, table_name, geo_col):
        cursor = self.connection.cursor()
        try:
            # Querying USER_SDO_GEOM_METADATA to get the SRID and dimension information.
            try:
                cursor.execute('SELECT "DIMINFO", "SRID" FROM "USER_SDO_GEOM_METADATA" WHERE "TABLE_NAME"=%s AND "COLUMN_NAME"=%s',
                               (table_name.upper(), geo_col.upper()))
                row = cursor.fetchone()
            except Exception, msg:
                raise Exception('Could not find entry in USER_SDO_GEOM_METADATA corresponding to "%s"."%s"\n'
                                'Error message: %s.' % (table_name, geo_col, msg))

            # TODO: Research way to find a more specific geometry field type for
            # the column's contents.
            field_type = 'GeometryField'

            # Getting the field parameters.
            field_params = {}
            dim, srid = row
            if srid != 4326:
                field_params['srid'] = srid
            # Length of object array ( SDO_DIM_ARRAY ) is number of dimensions.
            dim = len(dim)
            if dim != 2:
                field_params['dim'] = dim
        finally:
            cursor.close()

        return field_type, field_params
+2 −0
Original line number Diff line number Diff line
from django.db.backends.postgresql_psycopg2.base import *
from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper as Psycopg2DatabaseWrapper
from django.contrib.gis.db.backends.postgis.creation import PostGISCreation
from django.contrib.gis.db.backends.postgis.introspection import PostGISIntrospection
from django.contrib.gis.db.backends.postgis.operations import PostGISOperations

class DatabaseWrapper(Psycopg2DatabaseWrapper):
@@ -8,3 +9,4 @@ class DatabaseWrapper(Psycopg2DatabaseWrapper):
        super(DatabaseWrapper, self).__init__(*args, **kwargs)
        self.creation = PostGISCreation(self)
        self.ops = PostGISOperations(self)
        self.introspection = PostGISIntrospection(self)
Loading