Author: jbronn
Date: 2007-07-25 21:00:38 -0500 (Wed, 25 Jul 2007)
New Revision: 5761
Added:
django/branches/gis/django/contrib/gis/utils/spatial_db.py
Modified:
django/branches/gis/django/contrib/gis/gdal/geomtype.py
django/branches/gis/django/contrib/gis/utils/__init__.py
Log:
gis: added spatial database creation utility and fixed a bug in gdal geomtype
module.
Modified: django/branches/gis/django/contrib/gis/gdal/geomtype.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/geomtype.py 2007-07-26
01:55:37 UTC (rev 5760)
+++ django/branches/gis/django/contrib/gis/gdal/geomtype.py 2007-07-26
02:00:38 UTC (rev 5761)
@@ -1,4 +1,5 @@
from types import StringType
+from django.contrib.gis.gdal.error import OGRException
#### OGRGeomType ####
class OGRGeomType(object):
Modified: django/branches/gis/django/contrib/gis/utils/__init__.py
===================================================================
--- django/branches/gis/django/contrib/gis/utils/__init__.py 2007-07-26
01:55:37 UTC (rev 5760)
+++ django/branches/gis/django/contrib/gis/utils/__init__.py 2007-07-26
02:00:38 UTC (rev 5761)
@@ -1,2 +1,3 @@
from LayerMapping import LayerMapping
from inspect_data import sample
+from spatial_db import create_spatial_db
Added: django/branches/gis/django/contrib/gis/utils/spatial_db.py
===================================================================
--- django/branches/gis/django/contrib/gis/utils/spatial_db.py
(rev 0)
+++ django/branches/gis/django/contrib/gis/utils/spatial_db.py 2007-07-26
02:00:38 UTC (rev 5761)
@@ -0,0 +1,190 @@
+from django.conf import settings
+from django.core.management import syncdb
+from django.db import connection, backend
+from django.test.utils import _set_autocommit, TEST_DATABASE_PREFIX
+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."
+
+ # Getting the command-line options for the shell command
+ options = get_cmd_options(db_name)
+
+ # Constructing the 'createlang' command.
+ createlang_cmd = 'createlang %splpgsql' % options
+ if verbosity >= 1: print createlang_cmd
+
+ # Must have database super-user privileges to execute createlang -- it must
+ # also be in your path.
+ status, output = getstatusoutput(createlang_cmd)
+
+ # Checking the status of the command, 0 => execution successful
+ if status != 0:
+ raise Exception, "Error executing 'plpgsql' command: %s\n" % output
+
+
+def _create_with_cursor(db_name, verbosity=1, autoclobber=False):
+ "Creates database with psycopg2 cursor."
+
+ # Constructing the necessary SQL to create the database (the DATABASE_USER
+ # must possess the privileges to create a database)
+ create_sql = 'CREATE DATABASE %s OWNER %s' % (backend.quote_name(db_name),
+ settings.DATABASE_USER)
+ cursor = connection.cursor()
+ _set_autocommit(connection)
+
+ try:
+ # Trying to create the database first.
+ cursor.execute(create_sql)
+ except Exception, e:
+ # Drop and recreate, if necessary.
+ if not autoclobber:
+ confirm = raw_input("\nIt appears the database, %s, already
exists. Type 'yes' to delete it, or 'no' to cancel: " % db_name)
+ if autoclobber or confirm == 'yes':
+ if verbosity >= 1: print 'Destroying old spatial database...'
+ drop_db(db_name)
+ if verbosity >= 1: print 'Creating new spatial database...'
+ cursor.execute(create_sql)
+ else:
+ raise Exception, 'Spatial Database Creation canceled.'
+
+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."""
+
+ # Getting the command-line options for the shell command
+ options = get_cmd_options(False)
+ create_cmd = 'createdb -O %s %s%s' % (settings.DATABASE_USER, options,
db_name)
+ if verbosity >= 1: print create_cmd
+
+ # Attempting to create the database.
+ status, output = getstatusoutput(create_cmd)
+ if status != 0:
+ if created_regex.match(output):
+ if not autoclobber:
+ confirm = raw_input("\nIt appears the database, %s, already
exists. Type 'yes' to delete it, or 'no' to cancel: " % db_name)
+ if autoclobber or confirm == 'yes':
+ if verbosity >= 1: print 'Destroying old spatial database...'
+ drop_cmd = 'dropdb %s%s' % (options, db_name)
+ status, output = getstatusoutput(drop_cmd)
+ if status != 0:
+ raise Exception, 'Could not drop database %s: %s' %
(db_name, output)
+ if verbosity >= 1: print 'Creating new spatial database...'
+ status, output = getstatusoutput(create_cmd)
+ if status != 0:
+ raise Exception, 'Could not create database after
dropping: %s' % output
+ else:
+ raise Exception, 'Spatial Database Creation canceled.'
+ else:
+ raise Exception, 'Unknown error occurred in creating database: %s'
% output
+
+def create_spatial_db(test=False, verbosity=1, autoclobber=False):
+ "This Python routine creates a spatial database based on settings.py."
+
+ # Making sure we're using PostgreSQL and psycopg2
+ if settings.DATABASE_ENGINE != 'postgresql_psycopg2':
+ raise Exception, 'Spatial database creation only supported
postgresql_psycopg2 platform.'
+
+ # This routine depends on getstatusoutput(), which does not work on
Windows.
+ # TODO: Consider executing shell commands with popen for Windows
compatibility
+ if os.name == 'nt':
+ raise Exception, 'Automatic spatial database creation only supported
on *NIX platforms.'
+
+ # Getting the spatial database name
+ if test:
+ db_name = get_spatial_db(test=True)
+ _create_with_cursor(db_name, verbosity=verbosity,
autoclobber=autoclobber)
+ else:
+ db_name = get_spatial_db()
+ _create_with_shell(db_name, verbosity=verbosity,
autoclobber=autoclobber)
+
+ # Creating the db language.
+ create_lang(db_name, verbosity=verbosity)
+
+ # Now adding in the PostGIS routines.
+ load_postgis_sql(db_name, verbosity=verbosity)
+
+ if verbosity >= 1: print 'Creation of spatial database %s successful.' %
db_name
+
+ # Closing the connection
+ connection.close()
+ settings.DATABASE_NAME = db_name
+
+ # Syncing the database
+ syncdb(verbosity, interactive=False)
+
+ # Get a cursor (even though we don't need one yet). This has
+ # the side effect of initializing the test database.
+ cursor = connection.cursor()
+
+def drop_db(db_name=False, test=False):
+ "Using the cursor, drops the given database. All exceptions will be
propagated up."
+ if not db_name: db_name = get_spatial_db(test=test)
+ cursor = connection.cursor()
+ cursor.execute("DROP DATABASE %s" % backend.quote_name(db_name))
+
+def get_cmd_options(db_name):
+ "Obtains the command-line PostgreSQL connection options for shell
commands."
+ # The db_name parameter is optional
+ if db_name:
+ options = '-d %s -U %s ' % (db_name, settings.DATABASE_USER)
+ else:
+ options = '-U %s ' % settings.DATABASE_USER
+ if settings.DATABASE_HOST:
+ options += '-h %s ' % settings.DATABASE_HOST
+ if settings.DATABASE_PORT:
+ options += '-p %s ' % settings.DATABASE_PORT
+ 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."""
+ if test:
+ if settings.TEST_DATABASE_NAME:
+ test_db_name = settings.TEST_DATABASE_NAME
+ else:
+ test_db_name = TEST_DATABASE_PREFIX + settings.DATABASE_NAME
+ return test_db_name
+ else:
+ if not settings.DATABASE_NAME:
+ raise Exception, 'must configure DATABASE_NAME in settings.py'
+ 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."
+
+ # Getting the path to the PostGIS SQL
+ try:
+ # POSTGIS_SQL_PATH may be placed in settings to tell GeoDjango where
the
+ # PostGIS SQL files are located
+ sql_path = settings.POSTGIS_SQL_PATH
+ except AttributeError:
+ sql_path = '/usr/local/share'
+
+ # The PostGIS SQL post-creation files.
+ lwpostgis_file = os.path.join(sql_path, 'lwpostgis.sql')
+ srefsys_file = os.path.join(sql_path, 'spatial_ref_sys.sql')
+ if not os.path.isfile(lwpostgis_file):
+ raise Exception, 'Could not find PostGIS function definitions in %s' %
lwpostgis_file
+ if not os.path.isfile(srefsys_file):
+ raise Exception, 'Could not find PostGIS spatial reference system
definitions in %s' % srefsys_file
+
+ # Getting the psql command-line options.
+ options = get_cmd_options(db_name)
+
+ # Now trying to load up the PostGIS functions
+ cmd = 'psql %s-f %s' % (options, lwpostgis_file)
+ if verbosity >= 1: print cmd
+ status, output = getstatusoutput(cmd)
+ if status != 0:
+ raise Exception, 'Error in loading PostGIS lwgeometry routines.'
+
+ # Now trying to load up the Spatial Reference System table
+ cmd = 'psql %s-f %s' % (options, srefsys_file)
+ if verbosity >= 1: print cmd
+ status, output = getstatusoutput(cmd)
+ if status !=0:
+ raise Exception, 'Error in loading PostGIS spatial_ref_sys table.'
+
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---