Fixed #9858 -- Added ability to use PostGIS template with GIS test runner via `POSTGIS_TEMPLATE` setting. Thanks to Aryeh Leib Taurog for feature suggestion and initial patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9803 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2009-02-01 18:22:57 +00:00
parent d982edff4b
commit 2b8e768b22
1 changed files with 35 additions and 24 deletions

View File

@ -30,7 +30,7 @@ def create_lang(db_name, verbosity=1):
if verbosity >= 1: print createlang_cmd if verbosity >= 1: print createlang_cmd
# Must have database super-user privileges to execute createlang -- it must # Must have database super-user privileges to execute createlang -- it must
# also be in your path. # also be in your path.
status, output = getstatusoutput(createlang_cmd) status, output = getstatusoutput(createlang_cmd)
# Checking the status of the command, 0 => execution successful # Checking the status of the command, 0 => execution successful
@ -39,12 +39,18 @@ def create_lang(db_name, verbosity=1):
def _create_with_cursor(db_name, verbosity=1, autoclobber=False): def _create_with_cursor(db_name, verbosity=1, autoclobber=False):
"Creates database with psycopg2 cursor." "Creates database with psycopg2 cursor."
qn = connection.ops.quote_name
# Constructing the necessary SQL to create the database (the DATABASE_USER # Constructing the necessary SQL to create the database.
# must possess the privileges to create a database) create_sql = 'CREATE DATABASE %s' % qn(db_name)
create_sql = 'CREATE DATABASE %s' % connection.ops.quote_name(db_name)
# If there's a template database for PostGIS set, then use it.
if hasattr(settings, 'POSTGIS_TEMPLATE'):
create_sql += ' TEMPLATE %s' % qn(settings.POSTGIS_TEMPLATE)
# The DATABASE_USER must possess the privileges to create a spatial database.
if settings.DATABASE_USER: if settings.DATABASE_USER:
create_sql += ' OWNER %s' % settings.DATABASE_USER create_sql += ' OWNER %s' % qn(settings.DATABASE_USER)
cursor = connection.cursor() cursor = connection.cursor()
connection.creation.set_autocommit() connection.creation.set_autocommit()
@ -52,7 +58,6 @@ def _create_with_cursor(db_name, verbosity=1, autoclobber=False):
try: try:
# Trying to create the database first. # Trying to create the database first.
cursor.execute(create_sql) cursor.execute(create_sql)
#print create_sql
except Exception, e: except Exception, e:
# Drop and recreate, if necessary. # Drop and recreate, if necessary.
if not autoclobber: if not autoclobber:
@ -69,12 +74,17 @@ created_regex = re.compile(r'^createdb: database creation failed: ERROR: databa
def _create_with_shell(db_name, verbosity=1, autoclobber=False): def _create_with_shell(db_name, verbosity=1, autoclobber=False):
""" """
If no spatial database already exists, then using a cursor will not work. 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 Thus, a `createdb` command will be issued through the shell to bootstrap
creation of the spatial database. creation of the spatial database.
"""
TODO: Actually allow this method to be used without a spatial database
in place first.
"""
# Getting the command-line options for the shell command # Getting the command-line options for the shell command
options = get_cmd_options(False) options = get_cmd_options(False)
if hasattr(settings, 'POSTGIS_TEMPLATE'):
options += '-T %s ' % settings.POSTGIS_TEMPlATE
create_cmd = 'createdb -O %s %s%s' % (settings.DATABASE_USER, options, db_name) create_cmd = 'createdb -O %s %s%s' % (settings.DATABASE_USER, options, db_name)
if verbosity >= 1: print create_cmd if verbosity >= 1: print create_cmd
@ -115,13 +125,15 @@ def create_spatial_db(test=False, verbosity=1, autoclobber=False, interactive=Fa
db_name = get_spatial_db() db_name = get_spatial_db()
_create_with_shell(db_name, verbosity=verbosity, autoclobber=autoclobber) _create_with_shell(db_name, verbosity=verbosity, autoclobber=autoclobber)
# Creating the db language, does not need to be done on NT platforms # If a template database is used, then don't need to do any of the following.
# since the PostGIS installer enables this capability. if not hasattr(settings, 'POSTGIS_TEMPLATE'):
if os.name != 'nt': # Creating the db language, does not need to be done on NT platforms
create_lang(db_name, verbosity=verbosity) # since the PostGIS installer enables this capability.
if os.name != 'nt':
create_lang(db_name, verbosity=verbosity)
# Now adding in the PostGIS routines. # Now adding in the PostGIS routines.
load_postgis_sql(db_name, verbosity=verbosity) load_postgis_sql(db_name, verbosity=verbosity)
if verbosity >= 1: print 'Creation of spatial database %s successful.' % db_name if verbosity >= 1: print 'Creation of spatial database %s successful.' % db_name
@ -135,7 +147,7 @@ def create_spatial_db(test=False, verbosity=1, autoclobber=False, interactive=Fa
def drop_db(db_name=False, test=False): def drop_db(db_name=False, test=False):
""" """
Drops the given database (defaults to what is returned from Drops the given database (defaults to what is returned from
get_spatial_db()). All exceptions are propagated up to the caller. get_spatial_db()). All exceptions are propagated up to the caller.
""" """
if not db_name: db_name = get_spatial_db(test=test) if not db_name: db_name = get_spatial_db(test=test)
cursor = connection.cursor() cursor = connection.cursor()
@ -158,7 +170,7 @@ def get_cmd_options(db_name):
def get_spatial_db(test=False): def get_spatial_db(test=False):
""" """
Returns the name of the spatial database. The 'test' keyword may be set Returns the name of the spatial database. The 'test' keyword may be set
to return the test spatial database name. to return the test spatial database name.
""" """
if test: if test:
if settings.TEST_DATABASE_NAME: if settings.TEST_DATABASE_NAME:
@ -174,14 +186,13 @@ def get_spatial_db(test=False):
def load_postgis_sql(db_name, verbosity=1): def load_postgis_sql(db_name, verbosity=1):
""" """
This routine loads up the PostGIS SQL files lwpostgis.sql and This routine loads up the PostGIS SQL files lwpostgis.sql and
spatial_ref_sys.sql. spatial_ref_sys.sql.
""" """
# Getting the path to the PostGIS SQL # Getting the path to the PostGIS SQL
try: try:
# POSTGIS_SQL_PATH may be placed in settings to tell GeoDjango where the # POSTGIS_SQL_PATH may be placed in settings to tell GeoDjango where the
# PostGIS SQL files are located. This is especially useful on Win32 # PostGIS SQL files are located. This is especially useful on Win32
# platforms since the output of pg_config looks like "C:/PROGRA~1/..". # platforms since the output of pg_config looks like "C:/PROGRA~1/..".
sql_path = settings.POSTGIS_SQL_PATH sql_path = settings.POSTGIS_SQL_PATH
except AttributeError: except AttributeError:
status, sql_path = getstatusoutput('pg_config --sharedir') status, sql_path = getstatusoutput('pg_config --sharedir')
@ -215,14 +226,14 @@ def load_postgis_sql(db_name, verbosity=1):
raise Exception('Error in loading PostGIS spatial_ref_sys table.') raise Exception('Error in loading PostGIS spatial_ref_sys table.')
# Setting the permissions because on Windows platforms the owner # Setting the permissions because on Windows platforms the owner
# of the spatial_ref_sys and geometry_columns tables is always # of the spatial_ref_sys and geometry_columns tables is always
# the postgres user, regardless of how the db is created. # the postgres user, regardless of how the db is created.
if os.name == 'nt': set_permissions(db_name) if os.name == 'nt': set_permissions(db_name)
def set_permissions(db_name): def set_permissions(db_name):
""" """
Sets the permissions on the given database to that of the user specified Sets the permissions on the given database to that of the user specified
in the settings. Needed specifically for PostGIS on Win32 platforms. in the settings. Needed specifically for PostGIS on Win32 platforms.
""" """
cursor = connection.cursor() cursor = connection.cursor()
user = settings.DATABASE_USER user = settings.DATABASE_USER