Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #13315, #13430 -- Recreated `django.contrib.gis.db.backend` mod…

…ule with `SpatialBackend` alias and added `Adaptor` alias for backwards-compatibility purposes; added GeoDjango 1.2 backwards-incompatibility documentation and release notes; added a section in the docs about how MySQL is a crippled spatial database; updated versions in install docs.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13097 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 402f8cede599950d44be9db03f3fd1e46e3dbaba 1 parent 41ccfa1
Justin Bronn authored May 04, 2010
24  django/contrib/gis/db/backend/__init__.py
... ...
@@ -0,0 +1,24 @@
  1
+from django.db import connection
  2
+
  3
+if hasattr(connection.ops, 'spatial_version'):
  4
+    from warnings import warn
  5
+    warn('The `django.contrib.gis.db.backend` module was refactored and '
  6
+         'renamed to `django.contrib.gis.db.backends` in 1.2.  '
  7
+         'All functionality of `SpatialBackend` '
  8
+         'has been moved to the `ops` attribute of the spatial database '
  9
+         'backend.  A `SpatialBackend` alias is provided here for '
  10
+         'backwards-compatibility, but will be removed in 1.3.')
  11
+    SpatialBackend = connection.ops
  12
+
  13
+from django.db import connection
  14
+
  15
+if hasattr(connection.ops, 'spatial_version'):
  16
+    from warnings import warn
  17
+    warn('The `django.contrib.gis.db.backend` module was refactored and '
  18
+         'renamed to `django.contrib.gis.db.backends` in 1.2.  '
  19
+         'All functionality of `SpatialBackend` '
  20
+         'has been moved to the `ops` attribute of the spatial database '
  21
+         'backend.  A `SpatialBackend` alias is provided here for '
  22
+         'backwards-compatibility, but will be removed in 1.3.')
  23
+    SpatialBackend = connection.ops
  24
+
1  django/contrib/gis/db/backends/mysql/operations.py
@@ -13,6 +13,7 @@ class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
13 13
     from_text = 'GeomFromText'
14 14
 
15 15
     Adapter = WKTAdapter
  16
+    Adaptor = Adapter # Backwards-compatibility alias.
16 17
 
17 18
     geometry_functions = {
18 19
         'bbcontains' : 'MBRContains', # For consistency w/PostGIS API
2  django/contrib/gis/db/backends/oracle/models.py
@@ -18,7 +18,6 @@ class GeometryColumns(models.Model):
18 18
     srid = models.IntegerField(primary_key=True)
19 19
     # TODO: Add support for `diminfo` column (type MDSYS.SDO_DIM_ARRAY).
20 20
     class Meta:
21  
-        app_label = 'gis'
22 21
         db_table = 'USER_SDO_GEOM_METADATA'
23 22
         managed = False
24 23
 
@@ -54,7 +53,6 @@ class SpatialRefSys(models.Model, SpatialRefSysMixin):
54 53
     objects = models.GeoManager()
55 54
 
56 55
     class Meta:
57  
-        app_label = 'gis'
58 56
         db_table = 'CS_SRS'
59 57
         managed = False
60 58
 
1  django/contrib/gis/db/backends/oracle/operations.py
@@ -75,6 +75,7 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
75 75
     valid_aggregates = dict([(a, None) for a in ('Union', 'Extent')])
76 76
 
77 77
     Adapter = OracleSpatialAdapter
  78
+    Adaptor = Adapter # Backwards-compatibility alias.
78 79
 
79 80
     area = 'SDO_GEOM.SDO_AREA'
80 81
     gml= 'SDO_UTIL.TO_GMLGEOMETRY'
2  django/contrib/gis/db/backends/postgis/models.py
@@ -18,7 +18,6 @@ class GeometryColumns(models.Model):
18 18
     type = models.CharField(max_length=30)
19 19
 
20 20
     class Meta:
21  
-        app_label = 'gis'
22 21
         db_table = 'geometry_columns'
23 22
         managed = False
24 23
 
@@ -55,7 +54,6 @@ class SpatialRefSys(models.Model, SpatialRefSysMixin):
55 54
     proj4text = models.CharField(max_length=2048)
56 55
 
57 56
     class Meta:
58  
-        app_label = 'gis'
59 57
         db_table = 'spatial_ref_sys'
60 58
         managed = False
61 59
 
1  django/contrib/gis/db/backends/postgis/operations.py
@@ -66,6 +66,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
66 66
                              ('Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union')])
67 67
 
68 68
     Adapter = PostGISAdapter
  69
+    Adaptor = Adapter # Backwards-compatibility alias.
69 70
 
70 71
     def __init__(self, connection):
71 72
         super(PostGISOperations, self).__init__(connection)
2  django/contrib/gis/db/backends/spatialite/models.py
@@ -16,7 +16,6 @@ class GeometryColumns(models.Model):
16 16
     spatial_index_enabled = models.IntegerField()
17 17
 
18 18
     class Meta:
19  
-        app_label = 'gis'
20 19
         db_table = 'geometry_columns'
21 20
         managed = False
22 21
 
@@ -57,6 +56,5 @@ def wkt(self):
57 56
         return SpatialReference(self.proj4text).wkt
58 57
 
59 58
     class Meta:
60  
-        app_label = 'gis'
61 59
         db_table = 'spatial_ref_sys'
62 60
         managed = False
1  django/contrib/gis/db/backends/spatialite/operations.py
@@ -55,6 +55,7 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
55 55
     valid_aggregates = dict([(k, None) for k in ('Extent', 'Union')])
56 56
 
57 57
     Adapter = SpatiaLiteAdapter
  58
+    Adaptor = Adapter # Backwards-compatibility alias.
58 59
 
59 60
     area = 'Area'
60 61
     centroid = 'Centroid'
9  django/contrib/gis/models.py
... ...
@@ -0,0 +1,9 @@
  1
+from django.db import connection
  2
+
  3
+if (hasattr(connection.ops, 'spatial_version') and
  4
+    not connection.ops.mysql):
  5
+    # Getting the `SpatialRefSys` and `GeometryColumns`
  6
+    # models for the default spatial backend.  These
  7
+    # aliases are provided for backwards-compatibility.
  8
+    SpatialRefSys = connection.ops.spatial_ref_sys()
  9
+    GeometryColumns = connection.ops.geometry_columns()
55  docs/ref/contrib/gis/db-api.txt
@@ -23,13 +23,16 @@ its functionality into full-fledged spatial database backends:
23 23
 * :mod:`django.contrib.gis.db.backends.oracle`
24 24
 * :mod:`django.contrib.gis.db.backends.spatialite`
25 25
 
26  
-Backwards-Compatibility
27  
------------------------
  26
+Database Settings Backwards-Compatibility
  27
+-----------------------------------------
28 28
 
29  
-For those using the old database settings (e.g., the ``DATABASE_*`` settings)
30  
-Django 1.2 will automatically use the appropriate spatial backend as long
31  
-as :mod:`django.contrib.gis` is in your :setting:`INSTALLED_APPS`.  For
32  
-example, if you have the following in your settings::
  29
+In :ref:`Django 1.2 <releases-1.2>`, the way 
  30
+to :ref:`specify databases <specifying-databases>` in your settings was changed.
  31
+The old database settings format (e.g., the ``DATABASE_*`` settings)
  32
+is backwards compatible with GeoDjango, and  will automatically use the
  33
+appropriate spatial backend as long as :mod:`django.contrib.gis` is in
  34
+your :setting:`INSTALLED_APPS`.  For example, if you have the following in
  35
+your settings::
33 36
 
34 37
     DATABASE_ENGINE='postgresql_psycopg2'
35 38
 
@@ -41,9 +44,37 @@ example, if you have the following in your settings::
41 44
       ...
42 45
     )
43 46
 
44  
-Then, :mod:`django.contrib.gis.db.backends.postgis` will automatically be used as your
  47
+Then, :mod:`django.contrib.gis.db.backends.postgis` is automatically used as your
45 48
 spatial backend.
46 49
 
  50
+.. _mysql-spatial-limitations:
  51
+
  52
+MySQL Spatial Limitations
  53
+-------------------------
  54
+
  55
+MySQL's spatial extensions only support bounding box operations
  56
+(what MySQL calls minimum bounding rectangles, or MBR).  Specifically,
  57
+`MySQL does not conform to the OGC standard <http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html>`_:
  58
+
  59
+    Currently, MySQL does not implement these functions
  60
+    [``Contains``, ``Crosses``, ``Disjoint``, ``Intersects``, ``Overlaps``,
  61
+    ``Touches``, ``Within``]
  62
+    according to the specification.  Those that are implemented return
  63
+    the same result as the corresponding MBR-based functions. 
  64
+
  65
+In other words, while spatial lookups such as :lookup:`contains <gis-contains>`
  66
+are available in GeoDjango when using MySQL, the results returned are really
  67
+equivalent to what would be returned when using :lookup:`bbcontains`
  68
+on a different spatial backend.
  69
+
  70
+.. warning::
  71
+
  72
+    True spatial indexes (R-trees) are only supported with
  73
+    MyISAM tables on MySQL. [#fnmysqlidx]_ In other words, when using
  74
+    MySQL spatial extensions you have to choose between fast spatial
  75
+    lookups and the integrity of your data -- MyISAM tables do
  76
+    not support transactions or foreign key constraints.
  77
+
47 78
 Creating and Saving Geographic Models
48 79
 =====================================
49 80
 Here is an example of how to create a geometry object (assuming the ``Zipcode``
@@ -307,4 +338,12 @@ Method                                PostGIS  Oracle  SpatiaLite
307 338
 .. [#fngeojson] *See* Howard Butler, Martin Daly, Allan Doyle, Tim Schaub, & Christopher Schmidt, `The GeoJSON Format Specification <http://geojson.org/geojson-spec.html>`_, Revision 1.0 (June 16, 2008).
308 339
 .. [#fndistsphere14] *See* `PostGIS 1.4 documentation <http://postgis.refractions.net/documentation/manual-1.4/ST_Distance_Sphere.html>`_ on ``ST_distance_sphere``.
309 340
 .. [#fndistsphere15] *See* `PostGIS 1.5 documentation <http://postgis.refractions.net/documentation/manual-1.5/ST_Distance_Sphere.html>`_ on ``ST_distance_sphere``.
310  
-.. [#] MySQL only supports bounding box operations (known as minimum bounding rectangles, or MBR, in MySQL).  Thus, spatial lookups such as :lookup:`contains <gis-contains>` are really equivalent to :lookup:`bbcontains`.
  341
+.. [#fnmysqlidx] *See* `Creating Spatial Indexes <http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-indexes.html>`_
  342
+   in the MySQL 5.1 Reference Manual:
  343
+
  344
+       For MyISAM tables, ``SPATIAL INDEX`` creates an R-tree index. For storage
  345
+       engines that support nonspatial indexing of spatial columns, the engine
  346
+       creates a B-tree index. A B-tree index on spatial values will be useful
  347
+       for exact-value lookups, but not for range scans.
  348
+
  349
+.. [#] Refer :ref:`mysql-spatial-limitations` section for more details.
18  docs/ref/contrib/gis/install.txt
@@ -150,13 +150,13 @@ directly from Python using ctypes.
150 150
 First, download GEOS 3.2 from the refractions website and untar the source 
151 151
 archive::
152 152
 
153  
-    $ wget http://download.osgeo.org/geos/geos-3.2.1.tar.bz2
154  
-    $ tar xjf geos-3.2.1.tar.bz2
  153
+    $ wget http://download.osgeo.org/geos/geos-3.2.2.tar.bz2
  154
+    $ tar xjf geos-3.2.2.tar.bz2
155 155
 
156 156
 Next, change into the directory where GEOS was unpacked, run the configure 
157 157
 script, compile, and install::
158 158
 
159  
-    $ cd geos-3.2.1
  159
+    $ cd geos-3.2.2
160 160
     $ ./configure
161 161
     $ make
162 162
     $ sudo make install
@@ -273,9 +273,9 @@ supports :ref:`GDAL's vector data <ref-gdal>` capabilities [#]_.
273 273
 
274 274
 First download the latest GDAL release version and untar the archive::
275 275
 
276  
-    $ wget http://download.osgeo.org/gdal/gdal-1.7.1.tar.gz
277  
-    $ tar xzf gdal-1.7.1.tar.gz
278  
-    $ cd gdal-1.7.1
  276
+    $ wget http://download.osgeo.org/gdal/gdal-1.7.2.tar.gz
  277
+    $ tar xzf gdal-1.7.2.tar.gz
  278
+    $ cd gdal-1.7.2
279 279
 
280 280
 Configure, make and install::
281 281
 
@@ -516,9 +516,9 @@ user.  For example, you can use the following to become the ``postgres`` user::
516 516
 
517 517
    The location *and* name of the PostGIS SQL files (e.g., from
518 518
    ``POSTGIS_SQL_PATH`` below) depends on the version of PostGIS.
519  
-   PostGIS versions 1.3 and below use ``<sharedir>/contrib/lwpostgis.sql``, whereas
520  
-   versions 1.4 and 1.5 use ``<sharedir>/contrib/postgis-1.4/postgis.sql`` and
521  
-   ``<sharedir>/contrib/postgis-1.5/postgis.sql``, respectively.
  519
+   PostGIS versions 1.3 and below use ``<pg_sharedir>/contrib/lwpostgis.sql``;
  520
+   whereas version 1.4 uses ``<sharedir>/contrib/postgis.sql`` and
  521
+   version 1.5 uses ``<sharedir>/contrib/postgis-1.5/postgis.sql``.
522 522
 
523 523
    The example below assumes PostGIS 1.5, thus you may need to modify
524 524
    ``POSTGIS_SQL_PATH`` and the name of the SQL file for the specific 
136  docs/releases/1.2.txt
@@ -77,6 +77,9 @@ changes:
77 77
 
78 78
        __members__ = property(lambda self: self.__dir__())
79 79
 
  80
+
  81
+.. _specifying-databases:
  82
+
80 83
 Specifying databases
81 84
 --------------------
82 85
 
@@ -338,8 +341,6 @@ you need an unmodified instance of your model, you should pass a copy to the
338 341
 ``ModelForm`` constructor.
339 342
 
340 343
 
341  
-.. _deprecated-features-1.2:
342  
-
343 344
 ``BooleanField`` on MySQL
344 345
 --------------------------
345 346
 
@@ -350,6 +351,8 @@ people this shouldn't have been a problem because ``bool`` is a subclass of
350 351
 only time this should ever be an issue is if you were expecting printing the
351 352
 ``repr`` of a ``BooleanField`` to print ``1`` or ``0``.
352 353
 
  354
+.. _deprecated-features-1.2:
  355
+
353 356
 Features deprecated in 1.2
354 357
 ==========================
355 358
 
@@ -363,7 +366,7 @@ library, has been deprecated.
363 366
 If you are currently using the ``postgresql`` backend, you should
364 367
 migrate to using the ``postgresql_psycopg2`` backend. To update your
365 368
 code, install the ``psycopg2`` library and change the
366  
-``DATABASE_ENGINE`` setting to read ``postgresql_psycopg2``.
  369
+:setting:`DATABASE_ENGINE` setting to read ``postgresql_psycopg2``.
367 370
 
368 371
 CSRF response-rewriting middleware
369 372
 ----------------------------------
@@ -594,6 +597,88 @@ deprecated in favor of the new :ref:`Format localization
594 597
 information in a ``formats.py`` file in the corresponding
595 598
 ``django/conf/locale/<locale name>/`` directory.
596 599
 
  600
+GeoDjango
  601
+---------
  602
+
  603
+To allow support for multiple databases, the GeoDjango database internals were
  604
+changed substantially.  The largest backwards-incompatible change is that
  605
+the module ``django.contrib.gis.db.backend`` was renamed to
  606
+:mod:`django.contrib.gis.db.backends`, where the full-fledged
  607
+:ref:`spatial databased backends <spatial-backends>` now exist.  The
  608
+following sections provide information on the most-popular APIs that
  609
+were affected by these changes.
  610
+
  611
+``SpatialBackend``
  612
+^^^^^^^^^^^^^^^^^^
  613
+
  614
+Prior to the creation of the separate spatial backends, the 
  615
+``django.contrib.gis.db.backend.SpatialBackend`` object was
  616
+provided as an abstraction to introspect on the capabilities of
  617
+the spatial database.  All of the attributes and routines provided by
  618
+``SpatialBackend`` are now a part of the ``ops`` attribute of the
  619
+database backend.
  620
+
  621
+The old module ``django.contrib.gis.db.backend`` is still provided
  622
+for backwards-compatibility access to a ``SpatialBackend`` object,
  623
+which is just an alias to the ``ops`` module of the
  624
+*default* spatial database connection.
  625
+
  626
+Users that were relying on undocumented modules and objects
  627
+within ``django.contrib.gis.db.backend``, rather the abstractions
  628
+provided by ``SpatialBackend``, are required to modify their code.
  629
+For example, the following import which would work in 1.1 and
  630
+below::
  631
+
  632
+    from django.contrib.gis.db.backend.postgis import PostGISAdaptor
  633
+
  634
+Would need to be changed::
  635
+
  636
+    from django.db import connection
  637
+    PostGISAdaptor = connection.ops.Adapter
  638
+
  639
+``SpatialRefSys`` and ``GeometryColumns`` models
  640
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  641
+
  642
+In previous versions of GeoDjango, :mod:`django.contrib.gis.db.models`
  643
+had ``SpatialRefSys`` and ``GeometryColumns`` models for querying
  644
+the OGC spatial metadata tables ``spatial_ref_sys`` and ``geometry_columns``,
  645
+respectively.
  646
+
  647
+While these aliases are still provided, they are only for the
  648
+*default* database connection and exist only if the default connection
  649
+is using a supported spatial database backend.
  650
+
  651
+.. note::
  652
+
  653
+    Because the table structure of the OGC spatial metadata tables
  654
+    differs across spatial databases, the ``SpatialRefSys`` and
  655
+    ``GeometryColumns`` models can no longer be associated with
  656
+    the ``gis`` application name.  Thus, no models will be returned
  657
+    when using the ``get_models`` method in the following example::
  658
+
  659
+        >>> from django.db.models import get_app, get_models
  660
+        >>> get_models(get_app('gis'))
  661
+        []
  662
+
  663
+To get the correct ``SpatialRefSys`` and ``GeometryColumns``
  664
+for your spatial database use the methods provided by the spatial backend::
  665
+
  666
+     >>> from django.db import connections
  667
+     >>> SpatialRefSys = connections['my_spatialite'].ops.spatial_ref_sys()
  668
+     >>> GeometryColumns = connections['my_postgis'].ops.geometry_columns()
  669
+
  670
+.. note::
  671
+
  672
+    When using the models returned from the ``spatial_ref_sys()`` and
  673
+    ``geometry_columns()`` method, you'll still need to use the
  674
+    correct database alias when querying on the non-default connection.
  675
+    In other words, to ensure that the models in the example above
  676
+    use the correct database::
  677
+
  678
+        sr_qs = SpatialRefSys.objects.using('my_spatialite').filter(...)
  679
+        gc_qs = GeometryColumns.objects.using('my_postgis').filter(...)
  680
+
  681
+
597 682
 What's new in Django 1.2
598 683
 ========================
599 684
 
@@ -793,6 +878,51 @@ The built-in :class:`~django.contrib.auth.models.User` model's
793 878
 :attr:`~django.contrib.auth.models.User.username` field now allows a wider range
794 879
 of characters, including ``@``, ``+``, ``.`` and ``-`` characters.
795 880
 
  881
+GeoDjango
  882
+---------
  883
+
  884
+In 1.2, :ref:`GeoDjango <ref-contrib-gis>` was upgraded to provide
  885
+support for multiple spatial databases.  As a result, the following 
  886
+:ref:`spatial database backends <spatial-backends>`
  887
+are now included:
  888
+
  889
+* :mod:`django.contrib.gis.db.backends.postgis`
  890
+* :mod:`django.contrib.gis.db.backends.mysql`
  891
+* :mod:`django.contrib.gis.db.backends.oracle`
  892
+* :mod:`django.contrib.gis.db.backends.spatialite`
  893
+
  894
+GeoDjango now supports the rich capabilities added
  895
+in the `PostGIS 1.5 release <http://postgis.refractions.net/documentation/manual-1.5/>`_.
  896
+New features include suppport for the the :ref:`geography type <geography-type>`
  897
+and enabling of :ref:`distance queries <distance-queries>`
  898
+with non-point geometries on geographic coordinate systems.
  899
+
  900
+Support for 3D geometry fields was added, and may be enabled
  901
+by setting the :attr:`~django.contrib.gis.db.models.GeometryField.dim`
  902
+keyword to 3 in your :class:`~django.contrib.gis.db.models.GeometryField`.
  903
+The :class:`~django.contrib.gis.db.models.Extent3D` aggregate
  904
+and :meth:`~django.contrib.gis.db.models.GeoQuerySet.extent3d` ``GeoQuerySet``
  905
+method were added as a part of this feature.
  906
+
  907
+The following :class:`~django.contrib.gis.db.models.GeoQeurySet`
  908
+methods are new in 1.2:
  909
+
  910
+* :meth:`~django.contrib.gis.db.models.GeoQuerySet.force_rhr`
  911
+* :meth:`~django.contrib.gis.db.models.GeoQuerySet.reverse_geom`
  912
+* :meth:`~django.contrib.gis.db.models.GeoQuerySet.geohash`
  913
+
  914
+The :ref:`GEOS interface <ref-geos>` was updated to use
  915
+thread-safe C library functions when available on the platform.
  916
+
  917
+The :ref:`GDAL interface <ref-gdal>` now allows the user to place
  918
+set a :attr:`~django.contrib.gis.gdal.Layer.spatial_filter` on
  919
+the features returned from a :class:`~django.contrib.gis.gdal.DataSource`
  920
+:class:`~django.contrib.gis.gdal.Layer`.
  921
+
  922
+Finally, :ref:`GeoDjango's documentation <ref-contrib-gis>` is now
  923
+included with Django's and is no longer
  924
+hosted separately at `geodjango.org <http://geodjango.org/>`_.
  925
+
796 926
 Deprecation of old language code ``no``
797 927
 ---------------------------------------
798 928
 

0 notes on commit 402f8ce

Please sign in to comment.
Something went wrong with that request. Please try again.