Code

PostgreSQL backend minor improvement: database creation less likely to fail
[roundup.git] / roundup / backends / back_postgresql.py
index 5d30c3875285f5557c80796443e80f705db9f487..defa905e2dfb3db5145dd63f5170bfd5d142d8d0 100644 (file)
@@ -36,28 +36,36 @@ def connection_dict(config, dbnamestr=None):
 def db_create(config):
     """Clear all database contents and drop database itself"""
     command = "CREATE DATABASE %s WITH ENCODING='UNICODE'"%config.RDBMS_NAME
+    if config.RDBMS_TEMPLATE :
+        command = command + " TEMPLATE=%s" % config.RDBMS_TEMPLATE
     logging.getLogger('roundup.hyperdb').info(command)
     db_command(config, command)
 
 def db_nuke(config, fail_ok=0):
     """Clear all database contents and drop database itself"""
     command = 'DROP DATABASE %s'% config.RDBMS_NAME
-    logging.getLogger('hyperdb').info(command)
+    logging.getLogger('roundup.hyperdb').info(command)
     db_command(config, command)
 
     if os.path.exists(config.DATABASE):
         shutil.rmtree(config.DATABASE)
 
-def db_command(config, command):
+def db_command(config, command, database='postgres'):
     '''Perform some sort of database-level command. Retry 10 times if we
     fail by conflicting with another user.
+
+    Since PostgreSQL version 8.1 there is a database "postgres",
+    before "template1" seems to habe been used, so we fall back to it. 
+    Compare to issue2550543.
     '''
     template1 = connection_dict(config)
-    template1['database'] = 'template1'
+    template1['database'] = database
 
     try:
         conn = psycopg.connect(**template1)
     except psycopg.OperationalError, message:
+        if str(message).find('database "postgres" does not exist') >= 0:
+            return db_command(config, command, database='template1')
         raise hyperdb.DatabaseError(message)
 
     conn.set_isolation_level(0)
@@ -131,7 +139,8 @@ class Database(rdbms_common.Database):
 
     def sql_open_connection(self):
         db = connection_dict(self.config, 'database')
-        logging.getLogger('hyperdb').info('open database %r'%db['database'])
+        logging.getLogger('roundup.hyperdb').info(
+            'open database %r'%db['database'])
         try:
             conn = psycopg.connect(**db)
         except psycopg.OperationalError, message:
@@ -218,7 +227,7 @@ class Database(rdbms_common.Database):
     def sql_commit(self, fail_ok=False):
         ''' Actually commit to the database.
         '''
-        logging.getLogger('hyperdb').info('commit')
+        logging.getLogger('roundup.hyperdb').info('commit')
 
         try:
             self.conn.commit()
@@ -226,7 +235,8 @@ class Database(rdbms_common.Database):
             # we've been instructed that this commit is allowed to fail
             if fail_ok and str(message).endswith('could not serialize '
                     'access due to concurrent update'):
-                logging.getLogger('hyperdb').info('commit FAILED, but fail_ok')
+                logging.getLogger('roundup.hyperdb').info(
+                    'commit FAILED, but fail_ok')
             else:
                 raise