1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

gis: fixed deprecated backend references in _get_sql_clause(); quote_name() no longer a GeoQuerySet attribute; PostGIS db creation now tries to use pg_config to obtain the POSTGIS_SQL_PATH.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6026 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-08-30 12:58:04 +00:00
parent f4203ef757
commit 85ea950759
3 changed files with 39 additions and 24 deletions

View File

@ -13,9 +13,9 @@
"""
from django.conf import settings
from django.db import connection
from django.db.models.query import LOOKUP_SEPARATOR, field_choices, find_field, FieldFound, QUERY_TERMS, get_where_clause
from django.db.models.query import field_choices, find_field, get_where_clause, \
FieldFound, LOOKUP_SEPARATOR, QUERY_TERMS
from django.utils.datastructures import SortedDict
qn = connection.ops.quote_name
if settings.DATABASE_ENGINE == 'postgresql_psycopg2':
# PostGIS is the spatial database, getting the rquired modules, renaming as necessary.
@ -30,7 +30,7 @@ else:
# parse_lookup() and lookup_inner() are modified from their django/db/models/query.py
# counterparts to support constructing SQL for geographic queries.
#
# Status: Synced with r5609.
# Status: Synced with r5982.
#
def parse_lookup(kwarg_items, opts):
# Helper function that handles converting API kwargs
@ -90,6 +90,7 @@ def parse_lookup(kwarg_items, opts):
return joins, where, params
def lookup_inner(path, lookup_type, value, opts, table, column):
qn = connection.ops.quote_name
joins, where, params = SortedDict(), [], []
current_opts = opts
current_table = table
@ -246,6 +247,7 @@ def lookup_inner(path, lookup_type, value, opts, table, column):
else:
# Last query term was a normal field.
column = field.column
db_type = field.db_type()
# If the field is a geometry field, then the WHERE clause will need to be obtained
# with the get_geo_where_clause()

View File

@ -6,7 +6,7 @@ from commands import getstatusoutput
import os, re, sys
def create_lang(db_name, verbosity=1):
"This sets up the pl/pgsql language on the given database."
"Sets up the pl/pgsql language on the given database."
# Getting the command-line options for the shell command
options = get_cmd_options(db_name)
@ -50,8 +50,11 @@ def _create_with_cursor(db_name, verbosity=1, autoclobber=False):
created_regex = re.compile(r'^createdb: database creation failed: ERROR: database ".+" already exists')
def _create_with_shell(db_name, verbosity=1, autoclobber=False):
"""If no spatial database already exists, then using a cursor will not work. Thus, a
`createdb` command will be issued through the shell to bootstrap the database."""
"""
If no spatial database already exists, then using a cursor will not work.
Thus, a `createdb` command will be issued through the shell to bootstrap
creation of the spatial database.
"""
# Getting the command-line options for the shell command
options = get_cmd_options(False)
@ -80,7 +83,7 @@ def _create_with_shell(db_name, verbosity=1, autoclobber=False):
raise Exception, 'Unknown error occurred in creating database: %s' % output
def create_spatial_db(test=False, verbosity=1, autoclobber=False, interactive=False):
"This Python routine creates a spatial database based on settings.py."
"Creates a spatial database based on the settings."
# Making sure we're using PostgreSQL and psycopg2
if settings.DATABASE_ENGINE != 'postgresql_psycopg2':
@ -119,7 +122,10 @@ def create_spatial_db(test=False, verbosity=1, autoclobber=False, interactive=Fa
cursor = connection.cursor()
def drop_db(db_name=False, test=False):
"Using the cursor, drops the given database. All exceptions will be propagated up."
"""
Drops the given database (defaults to what is returned from get_spatial_db().
All exceptions are propagated up to the caller.
"""
if not db_name: db_name = get_spatial_db(test=test)
cursor = connection.cursor()
cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(db_name))
@ -138,8 +144,10 @@ def get_cmd_options(db_name):
return options
def get_spatial_db(test=False):
"""This routine returns the name of the spatial database.
Set the 'test' keyword for the test spatial database name."""
"""
Returns the name of the spatial database. The 'test' keyword may be set
to return the test spatial database name.
"""
if test:
if settings.TEST_DATABASE_NAME:
test_db_name = settings.TEST_DATABASE_NAME
@ -152,7 +160,10 @@ def get_spatial_db(test=False):
return settings.DATABASE_NAME
def load_postgis_sql(db_name, verbosity=1):
"This routine loads up the PostGIS SQL files lwpostgis.sql and spatial_ref_sys.sql."
""""
This routine loads up the PostGIS SQL files lwpostgis.sql and
spatial_ref_sys.sql.
"""
# Getting the path to the PostGIS SQL
try:
@ -160,7 +171,9 @@ def load_postgis_sql(db_name, verbosity=1):
# PostGIS SQL files are located
sql_path = settings.POSTGIS_SQL_PATH
except AttributeError:
sql_path = '/usr/local/share'
status, sql_path = getstatusoutput('pg_config --sharedir')
if status != 0:
sql_path = '/usr/local/share'
# The PostGIS SQL post-creation files.
lwpostgis_file = os.path.join(sql_path, 'lwpostgis.sql')

View File

@ -17,8 +17,6 @@ class GeoQ(Q):
class GeoQuerySet(QuerySet):
"Geographical-enabled QuerySet object."
quote_name = connection.ops.quote_name
#### Overloaded QuerySet Routines ####
def __init__(self, model=None):
super(GeoQuerySet, self).__init__(model=model)
@ -47,6 +45,7 @@ class GeoQuerySet(QuerySet):
return clone
def _get_sql_clause(self):
qn = connection.ops.quote_name
opts = self.model._meta
# Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z.
@ -81,10 +80,10 @@ class GeoQuerySet(QuerySet):
# Add any additional SELECTs.
if self._select:
select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), self.quote_name(s[0])) for s in self._select.items()])
select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), qn(s[0])) for s in self._select.items()])
# Start composing the body of the SQL statement.
sql = [" FROM", self.quote_name(opts.db_table)]
sql = [" FROM", qn(opts.db_table)]
# Compose the join dictionary into SQL describing the joins.
if joins:
@ -107,7 +106,7 @@ class GeoQuerySet(QuerySet):
ordering_to_use = opts.ordering
for f in handle_legacy_orderlist(ordering_to_use):
if f == '?': # Special case.
order_by.append(backend.get_random_function_sql())
order_by.append(connection.ops.random_function_sql())
else:
if f.startswith('-'):
col_name = f[1:]
@ -117,21 +116,21 @@ class GeoQuerySet(QuerySet):
order = "ASC"
if "." in col_name:
table_prefix, col_name = col_name.split('.', 1)
table_prefix = self.quote_name(table_prefix) + '.'
table_prefix = qn(table_prefix) + '.'
else:
# Use the database table as a column prefix if it wasn't given,
# and if the requested column isn't a custom SELECT.
if "." not in col_name and col_name not in (self._select or ()):
table_prefix = self.quote_name(opts.db_table) + '.'
table_prefix = qn(opts.db_table) + '.'
else:
table_prefix = ''
order_by.append('%s%s %s' % (table_prefix, self.quote_name(orderfield2column(col_name, opts)), order))
order_by.append('%s%s %s' % (table_prefix, qn(orderfield2column(col_name, opts)), order))
if order_by:
sql.append("ORDER BY " + ", ".join(order_by))
# LIMIT and OFFSET clauses
if self._limit is not None:
sql.append("%s " % backend.get_limit_offset_sql(self._limit, self._offset))
sql.append("%s " % connection.ops.limit_offset_sql(self._limit, self._offset))
else:
assert self._offset is None, "'offset' is not allowed without 'limit'"
@ -144,8 +143,9 @@ class GeoQuerySet(QuerySet):
#### Methods specific to the GeoQuerySet ####
def _field_column(self, field):
return "%s.%s" % (self.quote_name(self.model._meta.db_table),
self.quote_name(field.column))
qn = connection.ops.quote_name
return "%s.%s" % (qn(self.model._meta.db_table),
qn(field.column))
def kml(self, field_name, precision=8):
"""Returns KML representation of the given field name in a `kml`
@ -176,7 +176,7 @@ class GeoQuerySet(QuerySet):
# override the geometry column returned from the database.
self._custom_select[field.column] = \
'(ST_Transform(%s, %s)) AS %s' % (self._field_column(field), srid,
self.quote_name(field.column))
connection.ops.quote_name(field.column))
return self._clone()