def get_postgresql_version(connection): """Returns the version number of the PostgreSQL connection.""" try: from django.db.backends.postgresql.version import get_version # Django 1.3 except ImportError: # Use the Django 1.4 method. from django.db.backends.postgresql_psycopg2.version import get_version return get_version(connection) else: # Use the Django 1.3 method. cursor = connection.cursor() major, major2, minor = get_version(cursor) return major * 10000 + major2 * 100 + minor
def test_version_detection(self): """Test PostgreSQL version detection""" # Helper mocks class CursorMock(object): "Very simple mock of DB-API cursor" def execute(self, arg): pass def fetchone(self): return ["PostgreSQL 9.3"] def __enter__(self): return self def __exit__(self, type, value, traceback): pass class OlderConnectionMock(object): "Mock of psycopg2 (< 2.0.12) connection" def cursor(self): return CursorMock() # psycopg2 < 2.0.12 code path conn = OlderConnectionMock() self.assertEqual(pg_version.get_version(conn), 90300)
def _cursor(self, settings): set_tz = False if self.connection is None: set_tz = True if settings.DATABASE_NAME == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You need to specify DATABASE_NAME in your Django settings file." ) conn_params = { 'database': settings.DATABASE_NAME, } conn_params.update(self.options) if settings.DATABASE_USER: conn_params['user'] = settings.DATABASE_USER if settings.DATABASE_PASSWORD: conn_params['password'] = settings.DATABASE_PASSWORD if settings.DATABASE_HOST: conn_params['host'] = settings.DATABASE_HOST if settings.DATABASE_PORT: conn_params['port'] = settings.DATABASE_PORT self.connection = Database.connect(**conn_params) self.connection.set_isolation_level( 1) # make transactions transparent to all cursors self.connection.set_client_encoding('UTF8') cursor = self.connection.cursor() cursor.tzinfo_factory = None if set_tz: cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False return cursor
def _cursor(self): """ Returns a unique server side cursor if they are enabled, otherwise falls through to the default client side cursors. """ cursor = super(DatabaseWrapper, self)._cursor() if self.server_side_cursors: cursor = self.connection.cursor(name='cur%s' %\ str(uuid.uuid4()).replace('-', '')) cursor.tzinfo_factory = None if self.server_side_cursor_itersize is not None: cursor.itersize = self.server_side_cursor_itersize cursor = CursorWrapper(cursor) self._register() if not hasattr(self, '_version'): try: from django.db.backends.postgresql.version import get_version self.__class__._version = get_version(cursor) except ImportError: pass if self._pg_version is None: self._pg_version = self.postgres_version return cursor
def _cursor(self, settings): set_tz = False if self.connection is None: set_tz = True if settings.DATABASE_NAME == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You need to specify DATABASE_NAME in your Django settings file." ) conn_string = "dbname=%s" % settings.DATABASE_NAME if settings.DATABASE_USER: conn_string = "user=%s %s" % (settings.DATABASE_USER, conn_string) if settings.DATABASE_PASSWORD: conn_string += " password='******'" % settings.DATABASE_PASSWORD if settings.DATABASE_HOST: conn_string += " host=%s" % settings.DATABASE_HOST if settings.DATABASE_PORT: conn_string += " port=%s" % settings.DATABASE_PORT self.connection = Database.connect(conn_string, **self.options) self.connection.set_isolation_level( 1) # make transactions transparent to all cursors cursor = self.connection.cursor() if set_tz: cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE]) if not hasattr(self, '_version'): version = get_version(cursor) self.__class__._version = version if version < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False cursor.execute("SET client_encoding to 'UNICODE'") cursor = UnicodeCursorWrapper(cursor, 'utf-8') return cursor
def _get_postgres_version(self): if self._postgres_version is None: from django.db import connection from django.db.backends.postgresql.version import get_version cursor = connection.cursor() self._postgres_version = get_version(cursor) return self._postgres_version
def _cursor(self): set_tz = False settings_dict = self.settings_dict if self.connection is None: set_tz = True if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You need to specify NAME in your Django settings file.") conn_string = "dbname=%s" % settings_dict['NAME'] if settings_dict['USER']: conn_string = "user=%s %s" % (settings_dict['USER'], conn_string) if settings_dict['PASSWORD']: conn_string += " password='******'" % settings_dict['PASSWORD'] if settings_dict['HOST']: conn_string += " host=%s" % settings_dict['HOST'] if settings_dict['PORT']: conn_string += " port=%s" % settings_dict['PORT'] self.connection = Database.connect(conn_string, **settings_dict['OPTIONS']) self.connection.set_isolation_level( 1) # make transactions transparent to all cursors connection_created.send(sender=self.__class__) cursor = self.connection.cursor() if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False cursor.execute("SET client_encoding to 'UNICODE'") cursor = UnicodeCursorWrapper(cursor, 'utf-8') return cursor
def _get_postgres_version(self): if self._postgres_version is None: from django.db.backends.postgresql.version import get_version cursor = self.connection.cursor() self._postgres_version = get_version(cursor) return self._postgres_version
def _cursor(self, settings): set_tz = False if self.connection is None: set_tz = True if settings.DATABASE_NAME == "": from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.") conn_params = {"database": settings.DATABASE_NAME} conn_params.update(self.options) if settings.DATABASE_USER: conn_params["user"] = settings.DATABASE_USER if settings.DATABASE_PASSWORD: conn_params["password"] = settings.DATABASE_PASSWORD if settings.DATABASE_HOST: conn_params["host"] = settings.DATABASE_HOST if settings.DATABASE_PORT: conn_params["port"] = settings.DATABASE_PORT self.connection = Database.connect(**conn_params) self.connection.set_isolation_level(1) # make transactions transparent to all cursors self.connection.set_client_encoding("UTF8") cursor = self.connection.cursor() cursor.tzinfo_factory = None if set_tz: cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE]) if not hasattr(self, "_version"): self.__class__._version = get_version(cursor) if self._version < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False return cursor
def _cursor(self, settings): set_tz = False if self.connection is None: set_tz = True if settings.DATABASE_NAME == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.") conn_string = "dbname=%s" % settings.DATABASE_NAME if settings.DATABASE_USER: conn_string = "user=%s %s" % (settings.DATABASE_USER, conn_string) if settings.DATABASE_PASSWORD: conn_string += " password='******'" % settings.DATABASE_PASSWORD if settings.DATABASE_HOST: conn_string += " host=%s" % settings.DATABASE_HOST if settings.DATABASE_PORT: conn_string += " port=%s" % settings.DATABASE_PORT self.connection = ConnectionWrapper(conn_string, **self.options) cursor = self.connection.cursor() cursor.tzinfo_factory = None if set_tz: cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False return cursor
def _cursor(self, settings): set_tz = False if self.connection is None: set_tz = True if settings.DATABASE_NAME == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.") conn_string = "dbname=%s" % settings.DATABASE_NAME if settings.DATABASE_USER: conn_string = "user=%s %s" % (settings.DATABASE_USER, conn_string) if settings.DATABASE_PASSWORD: conn_string += " password='******'" % settings.DATABASE_PASSWORD if settings.DATABASE_HOST: conn_string += " host=%s" % settings.DATABASE_HOST if settings.DATABASE_PORT: conn_string += " port=%s" % settings.DATABASE_PORT self.connection = Database.connect(conn_string, **self.options) self.connection.set_isolation_level(1) # make transactions transparent to all cursors self.connection.set_client_encoding('UTF8') cursor = self.connection.cursor() cursor.tzinfo_factory = None if set_tz: cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE]) if not hasattr(self, '_version'): version = get_version(cursor) self.__class__._version = version if version < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False return cursor
def _cursor(self): new_connection = False set_tz = False settings_dict = self.settings_dict if self.connection is None: new_connection = True set_tz = settings_dict.get('TIME_ZONE') if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify NAME in your Django settings file.") conn_string = "dbname=%s" % settings_dict['NAME'] if settings_dict['USER']: conn_string = "user=%s %s" % (settings_dict['USER'], conn_string) if settings_dict['PASSWORD']: conn_string += " password='******'" % settings_dict['PASSWORD'] if settings_dict['HOST']: conn_string += " host=%s" % settings_dict['HOST'] if settings_dict['PORT']: conn_string += " port=%s" % settings_dict['PORT'] self.connection = Database.connect(conn_string, **settings_dict['OPTIONS']) self.connection.set_isolation_level(1) # make transactions transparent to all cursors connection_created.send(sender=self.__class__) cursor = self.connection.cursor() if new_connection: if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False cursor.execute("SET client_encoding to 'UNICODE'") cursor = UnicodeCursorWrapper(cursor, 'utf-8') return cursor
def _cursor(self): new_connection = False set_tz = False settings_dict = self.settings_dict if self.connection is None: new_connection = True set_tz = settings_dict.get('TIME_ZONE') if settings_dict['DATABASE_NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You need to specify DATABASE_NAME in your Django settings file." ) conn_params = { 'database': settings_dict['DATABASE_NAME'], } conn_params.update(settings_dict['DATABASE_OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if settings_dict['DATABASE_USER']: conn_params['user'] = settings_dict['DATABASE_USER'] if settings_dict['DATABASE_PASSWORD']: conn_params['password'] = settings_dict['DATABASE_PASSWORD'] if settings_dict['DATABASE_HOST']: conn_params['host'] = settings_dict['DATABASE_HOST'] if settings_dict['DATABASE_PORT']: conn_params['port'] = settings_dict['DATABASE_PORT'] self.connection = Database.connect(**conn_params) self.connection.set_client_encoding('UTF8') self.connection.set_isolation_level(self.isolation_level) connection_created.send(sender=self.__class__) cursor = self.connection.cursor() cursor.tzinfo_factory = None if new_connection: if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False if self.features.uses_autocommit: if self._version[0:2] < (8, 2): # FIXME: Needs extra code to do reliable model insert # handling, so we forbid it for now. from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment." ) else: # FIXME: Eventually we're enable this by default for # versions that support it, but, right now, that's hard to # do without breaking other things (#10509). self.features.can_return_id_from_insert = True return cursor
def _cursor(self): new_connection = False set_tz = False settings_dict = self.settings_dict if self.connection is None: new_connection = True set_tz = settings_dict.get('TIME_ZONE') if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify NAME in your Django settings file.") conn_params = { 'database': settings_dict['NAME'], } conn_params.update(settings_dict['OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = settings_dict['PASSWORD'] if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] self.connection = Database.connect(**conn_params) self.connection.set_client_encoding('UTF8') self.connection.set_isolation_level(self.isolation_level) connection_created.send(sender=self.__class__) cursor = self.connection.cursor() cursor.tzinfo_factory = None if new_connection: if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False if self.features.uses_autocommit: if self._version[0:2] < (8, 2): # FIXME: Needs extra code to do reliable model insert # handling, so we forbid it for now. from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment.") else: # FIXME: Eventually we're enable this by default for # versions that support it, but, right now, that's hard to # do without breaking other things (#10509). self.features.can_return_id_from_insert = True return CursorWrapper(cursor)
def _cursor(self): set_tz = False settings_dict = self.settings_dict if self.connection is None: set_tz = True if settings_dict["DATABASE_NAME"] == "": from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.") conn_params = {"database": settings_dict["DATABASE_NAME"]} conn_params.update(settings_dict["DATABASE_OPTIONS"]) if "autocommit" in conn_params: del conn_params["autocommit"] if settings_dict["DATABASE_USER"]: conn_params["user"] = settings_dict["DATABASE_USER"] if settings_dict["DATABASE_PASSWORD"]: conn_params["password"] = settings_dict["DATABASE_PASSWORD"] if settings_dict["DATABASE_HOST"]: conn_params["host"] = settings_dict["DATABASE_HOST"] if settings_dict["DATABASE_PORT"]: conn_params["port"] = settings_dict["DATABASE_PORT"] self.connection = Database.connect(**conn_params) self.connection.set_client_encoding("UTF8") self.connection.set_isolation_level(self.isolation_level) connection_created.send(sender=self.__class__) cursor = self.connection.cursor() cursor.tzinfo_factory = None if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict["TIME_ZONE"]]) if not hasattr(self, "_version"): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False if self.features.uses_autocommit: if self._version[0:2] < (8, 2): # FIXME: Needs extra code to do reliable model insert # handling, so we forbid it for now. from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment." ) else: # FIXME: Eventually we're enable this by default for # versions that support it, but, right now, that's hard to # do without breaking other things (#10509). self.features.can_return_id_from_insert = True return cursor
def _cursor(self): """ Returns a unique server side cursor if they are enabled, otherwise falls through to the default client side cursors. """ global pool if not pool: poolclass = PersistentPool \ if self.pool_type == POOLTYPE_PERSISTENT else QueuePool pool = poolclass(self.settings_dict) if self.connection is None: self.connection = pool.getconn() if self.connection is not None and not self._try_connected(): self.connection = None if self.connection is not None: self.connection.set_client_encoding('UTF8') self.connection.set_isolation_level(self.isolation_level) cursor = super(DatabaseWrapper, self)._cursor() if self.server_side_cursors: cursor = self.connection.cursor(name='cur%s' %\ str(uuid.uuid4()).replace('-', '')) cursor.tzinfo_factory = None if self.server_side_cursor_itersize is not None: cursor.itersize = self.server_side_cursor_itersize cursor = CursorWrapper(cursor) self._register() if not hasattr(self, '_version'): try: from django.db.backends.postgresql.version import get_version self.__class__._version = get_version(cursor) except ImportError: pass if self._pg_version is None: self._pg_version = self.postgres_version return cursor
def _cursor(self): ''' Override _cursor to plug in our connection pool code. We'll return a wrapped Connection which can handle returning itself to the pool when its .close() method is called. ''' from django.db.backends.postgresql.version import get_version new_connection = False set_tz = False settings_dict = self.settings_dict if self.connection is None or connection_pools[self.alias]['settings'] != settings_dict: new_connection = True set_tz = settings_dict.get('TIME_ZONE') # Is this the initial use of the global connection_pools dictionary for # this python interpreter? Build a ThreadedConnectionPool instance and # add it to the dictionary if so. if self.alias not in connection_pools or connection_pools[self.alias]['settings'] != settings_dict: if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify NAME in your Django settings file.") conn_params = { 'database': settings_dict['NAME'], } conn_params.update(settings_dict['OPTIONS']) for extra in ['autocommit'] + pool_config_defaults.keys(): if extra in conn_params: del conn_params[extra] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = settings_dict['PASSWORD'] if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] self.create_connection_pool(conn_params) self.connection = PooledConnection(connection_pools[self.alias]['pool'], test_query=self._test_on_borrow_query) self.connection.set_client_encoding('UTF8') self.connection.set_isolation_level(self.isolation_level) # We'll continue to emulate the old signal frequency in case any code depends upon it connection_created.send(sender=self.__class__, connection=self) cursor = self.connection.cursor() cursor.tzinfo_factory = None if new_connection: if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False if self.features.uses_autocommit: if self._version[0:2] < (8, 2): # FIXME: Needs extra code to do reliable model insert # handling, so we forbid it for now. from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment.") else: # FIXME: Eventually we're enable this by default for # versions that support it, but, right now, that's hard to # do without breaking other things (#10509). self.features.can_return_id_from_insert = True return CursorWrapper(cursor)
def _cursor(self): ''' Override _cursor to plug in our connection pool code. We'll return a wrapped Connection which can handle returning itself to the pool when its .close() method is called. ''' from django.db.backends.postgresql.version import get_version new_connection = False set_tz = False settings_dict = self.settings_dict if self.connection is None or connection_pools[ self.alias]['settings'] != settings_dict: new_connection = True set_tz = settings_dict.get('TIME_ZONE') # Is this the initial use of the global connection_pools dictionary for # this python interpreter? Build a ThreadedConnectionPool instance and # add it to the dictionary if so. if self.alias not in connection_pools or connection_pools[ self.alias]['settings'] != settings_dict: if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You need to specify NAME in your Django settings file." ) conn_params = { 'database': settings_dict['NAME'], } conn_params.update(settings_dict['OPTIONS']) for extra in ['autocommit'] + pool_config_defaults.keys(): if extra in conn_params: del conn_params[extra] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = settings_dict['PASSWORD'] if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] self.create_connection_pool(conn_params) self.connection = PooledConnection( connection_pools[self.alias]['pool'], test_query=self._test_on_borrow_query) self.connection.set_client_encoding('UTF8') self.connection.set_isolation_level(self.isolation_level) # We'll continue to emulate the old signal frequency in case any code depends upon it connection_created.send(sender=self.__class__, connection=self) cursor = self.connection.cursor() cursor.tzinfo_factory = None if new_connection: if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False if self.features.uses_autocommit: if self._version[0:2] < (8, 2): # FIXME: Needs extra code to do reliable model insert # handling, so we forbid it for now. from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment." ) else: # FIXME: Eventually we're enable this by default for # versions that support it, but, right now, that's hard to # do without breaking other things (#10509). self.features.can_return_id_from_insert = True return CursorWrapper(cursor)
def _cursor(self): """ Override _cursor to plug in our connection pool code. We'll return a wrapped Connection which can handle returning itself to the pool when its .close() method is called. """ new_connection = False set_tz = False settings_dict = self.settings_dict if self.connection is None: new_connection = True set_tz = settings_dict.get("TIME_ZONE") # Is this the initial use of the global connection_pools dictionary for # this python interpreter? Build a ThreadedConnectionPool instance and # add it to the dictionary if so. global connection_pools if self.alias not in connection_pools: if settings_dict["NAME"] == "": from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify NAME in your Django settings file.") conn_params = {"database": settings_dict["NAME"]} max_conns = settings_dict["OPTIONS"].pop("MAX_CONNS", 1) min_conns = settings_dict["OPTIONS"].pop("MIN_CONNS", max_conns) conn_params.update(settings_dict["OPTIONS"]) if "autocommit" in conn_params: del conn_params["autocommit"] if settings_dict["USER"]: conn_params["user"] = settings_dict["USER"] if settings_dict["PASSWORD"]: conn_params["password"] = settings_dict["PASSWORD"] if settings_dict["HOST"]: conn_params["host"] = settings_dict["HOST"] if settings_dict["PORT"]: conn_params["port"] = settings_dict["PORT"] connection_pools_lock.acquire() try: logger.debug("Creating connection pool for db alias %s" % self.alias) from psycopg2 import pool connection_pools[self.alias] = pool.ThreadedConnectionPool(min_conns, max_conns, **conn_params) finally: connection_pools_lock.release() self.connection = PooledConnection(connection_pools[self.alias]) self.connection.set_client_encoding("UTF8") self.connection.set_isolation_level(self.isolation_level) # We'll continue to emulate the old signal frequency in case any code depends upon it connection_created.send(sender=self.__class__, connection=self) cursor = self.connection.cursor() cursor.tzinfo_factory = None if new_connection: if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict["TIME_ZONE"]]) if not hasattr(self, "_version"): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False if self.features.uses_autocommit: if self._version[0:2] < (8, 2): # FIXME: Needs extra code to do reliable model insert # handling, so we forbid it for now. from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment." ) else: # FIXME: Eventually we're enable this by default for # versions that support it, but, right now, that's hard to # do without breaking other things (#10509). self.features.can_return_id_from_insert = True return CursorWrapper(cursor)
def _cursor(self): ''' Override _cursor to plug in our connection pool code. We'll return a wrapped Connection which can handle returning itself to the pool when its .close() method is called. ''' global connection_pools from django.db.backends.postgresql.version import get_version new_connection = False set_tz = False settings_dict = self.settings_dict if self.connection is None or connection_pools[self.alias]['settings'] != settings_dict: new_connection = True set_tz = settings_dict.get('TIME_ZONE') # Is this the initial use of the global connection_pools dictionary for # this python interpreter? Build a ThreadedConnectionPool instance and # add it to the dictionary if so. if self.alias not in connection_pools or connection_pools[self.alias]['settings'] != settings_dict: if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify NAME in your Django settings file.") conn_params = { 'dbname': settings_dict['NAME'], } max_conns = settings_dict['OPTIONS'].pop('MAX_CONNS', 1) min_conns = settings_dict['OPTIONS'].pop('MIN_CONNS', max_conns) conn_params.update(settings_dict['OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = settings_dict['PASSWORD'] if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] # Use dsn string rather than keyword arguments to enable more libpq options # http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING dsn = str(conn_params).replace(":","=").replace("'","").replace(" ","").lstrip("{").rstrip("}").replace(","," ") connection_pools_lock.acquire() try: logger.debug("Creating connection pool for db alias %s" % self.alias) from psycopg2 import pool connection_pools[self.alias] = { 'pool': pool.ThreadedConnectionPool(min_conns, max_conns, dsn), 'settings': dict(settings_dict), } finally: connection_pools_lock.release() self.connection = PooledConnection(connection_pools[self.alias]['pool']) self.connection.set_client_encoding('UTF8') self.connection.set_isolation_level(self.isolation_level) # We'll continue to emulate the old signal frequency in case any code depends upon it connection_created.send(sender=self.__class__, connection=self) cursor = self.connection.cursor() cursor.tzinfo_factory = None if new_connection: if set_tz: cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) if not hasattr(self, '_version'): self.__class__._version = get_version(cursor) if self._version[0:2] < (8, 0): # No savepoint support for earlier version of PostgreSQL. self.features.uses_savepoints = False if self.features.uses_autocommit: if self._version[0:2] < (8, 2): # FIXME: Needs extra code to do reliable model insert # handling, so we forbid it for now. from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment.") else: # FIXME: Eventually we're enable this by default for # versions that support it, but, right now, that's hard to # do without breaking other things (#10509). self.features.can_return_id_from_insert = True return CursorWrapper(cursor)
def postgres_version(self): from django_orm.backends.postgresql_psycopg2.version import get_version if not hasattr(self, '_postgres_version'): self.__class__._postgres_version = get_version(self.connection) return self._postgres_version