def test_lookup_cast(self): from django.db.backends.postgresql_psycopg2.operations import DatabaseOperations do = DatabaseOperations(connection=None) for lookup in ('iexact', 'contains', 'icontains', 'startswith', 'istartswith', 'endswith', 'iendswith', 'regex', 'iregex'): self.assertIn('::text', do.lookup_cast(lookup))
def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self)
def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get('isolation_level', RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self)
def test_lookup_cast(self): from django.db.backends.postgresql_psycopg2.operations import DatabaseOperations do = DatabaseOperations(connection=None) for lookup in ( "iexact", "contains", "icontains", "startswith", "istartswith", "endswith", "iendswith", "regex", "iregex", ): self.assertIn("::text", do.lookup_cast(lookup))
def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures(self) autocommit = self.settings_dict["OPTIONS"].get('autocommit', False) self.features.uses_autocommit = autocommit if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self._set_isolation_level(level) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self)
def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) settings_dict = self.settings_dict self.features = DatabaseFeatures(self) autocommit = settings_dict["OPTIONS"].get('autocommit', False) self.features.uses_autocommit = autocommit if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self._set_isolation_level(level) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) self._pg_version = None if not settings_dict['NAME']: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value.") try: self.pool = _pools[self.alias] except KeyError: 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'] = force_str(settings_dict['PASSWORD']) if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] self.pool = GeventConnectionPool(1, DB_POOL_MAX_CONN, **conn_params) _pools[self.alias] = self.pool
def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures(self) autocommit = self.settings_dict["OPTIONS"].get('autocommit', False) self.features.uses_autocommit = autocommit self._set_isolation_level(int(not autocommit)) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self)
def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures(self) autocommit = self.settings_dict["OPTIONS"].get('autocommit', False) self.features.uses_autocommit = autocommit if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self._set_isolation_level(level) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) self._pg_version = None self.conn_params = self._conn_params() if self.alias not in POOLS: self.pool = POOLS[self.alias] = PostgresConnectionPool(maxsize=1000, **self.conn_params) else: self.pool = POOLS[self.alias]
class pgServerSideCurorDBWrapper(DatabaseWrapper): """ Psycopg2 database backend that allows the use of server side cursors. Intented Usage: qs = Model.objects.all() with server_side_cursors(qs, itersize=x): for item in qs.iterator(): item.value """ vendor = 'postgresql' operators = { 'exact': '= %s', 'iexact': '= UPPER(%s)', 'contains': 'LIKE %s', 'icontains': 'LIKE UPPER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE UPPER(%s)', 'iendswith': 'LIKE UPPER(%s)', } def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures(self) autocommit = self.settings_dict["OPTIONS"].get('autocommit', False) self.features.uses_autocommit = autocommit if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self._set_isolation_level(level) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) self._pg_version = None def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') def close(self): self.validate_thread_sharing() if self.connection is None: return try: self.connection.close() self.connection = None except Database.Error: # In some cases (database restart, network connection lost etc...) # the connection to the database is lost without giving Django a # notification. If we don't set self.connection to None, the error # will occur a every request. self.connection = None logger.warning('psycopg2 error while closing the connection.', exc_info=sys.exc_info() ) raise def _get_pg_version(self): if self._pg_version is None: self._pg_version = get_version(self.connection) return self._pg_version pg_version = property(_get_pg_version) def _cursor(self): settings_dict = self.settings_dict if self.connection is None: 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') tz = 'UTC' if settings.USE_TZ else settings_dict.get('TIME_ZONE') if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status('TimeZone') if conn_tz != tz: # Set the time zone in autocommit mode (see #17062) self.connection.set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) self.connection.cursor().execute( self.ops.set_time_zone_sql(), [tz]) self.connection.set_isolation_level(self.isolation_level) self._get_pg_version() connection_created.send(sender=self.__class__, connection=self) #here uses a server side cursor cursor = self.connection.cursor(name='cur%s' % str(uuid.uuid4()).replace('-', ''), scrollable=True, withhold=True) cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return pgServerSideCursorWrapper(cursor, self) def _enter_transaction_management(self, managed): """ Switch the isolation level when needing transaction support, so that the same transaction is visible across all the queries. """ if self.features.uses_autocommit and managed and not self.isolation_level: self._set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED) def _leave_transaction_management(self, managed): """ If the normal operating mode is "autocommit", switch back to that when leaving transaction management. """ if self.features.uses_autocommit and not managed and self.isolation_level: self._set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) def _set_isolation_level(self, level): """ Do all the related feature configurations for changing isolation levels. This doesn't touch the uses_autocommit feature, since that controls the movement *between* isolation levels. """ assert level in range(5) try: if self.connection is not None: self.connection.set_isolation_level(level) finally: self.isolation_level = level self.features.uses_savepoints = bool(level) def _commit(self): if self.connection is not None: try: return self.connection.commit() except Database.IntegrityError, e: raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'postgresql' operators = { 'exact': '= %s', 'iexact': '= UPPER(%s)', 'contains': 'LIKE %s', 'icontains': 'LIKE UPPER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE UPPER(%s)', 'iendswith': 'LIKE UPPER(%s)', } Database = Database def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get('isolation_level', RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) def get_connection_params(self): settings_dict = self.settings_dict if not settings_dict['NAME']: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value.") conn_params = { 'database': settings_dict['NAME'], } conn_params.update(settings_dict['OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if 'isolation_level' in conn_params: del conn_params['isolation_level'] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = force_str(settings_dict['PASSWORD']) if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) def init_connection_state(self): settings_dict = self.settings_dict self.connection.set_client_encoding('UTF8') tz = 'UTC' if settings.USE_TZ else settings_dict.get('TIME_ZONE') if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status('TimeZone') if conn_tz != tz: # Set the time zone in autocommit mode (see #17062) self.set_autocommit(True) self.connection.cursor().execute( self.ops.set_time_zone_sql(), [tz] ) self.connection.set_isolation_level(self.isolation_level) def create_cursor(self): cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return cursor def close(self): self.validate_thread_sharing() if self.connection is None: return try: self.connection.close() self.connection = None except Database.Error: # In some cases (database restart, network connection lost etc...) # the connection to the database is lost without giving Django a # notification. If we don't set self.connection to None, the error # will occur a every request. self.connection = None logger.warning('psycopg2 error while closing the connection.', exc_info=sys.exc_info() ) raise finally: self.set_clean() def _set_isolation_level(self, isolation_level): assert isolation_level in range(1, 5) # Use set_autocommit for level = 0 if self.psycopg2_version >= (2, 4, 2): self.connection.set_session(isolation_level=isolation_level) else: self.connection.set_isolation_level(isolation_level) def _set_autocommit(self, autocommit): if self.psycopg2_version >= (2, 4, 2): self.connection.autocommit = autocommit else: if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = self.isolation_level self.connection.set_isolation_level(level) def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') def is_usable(self): try: # Use a psycopg cursor directly, bypassing Django's utilities. self.connection.cursor().execute("SELECT 1") except DatabaseError: return False else: return True @cached_property def psycopg2_version(self): version = psycopg2.__version__.split(' ', 1)[0] return tuple(int(v) for v in version.split('.')) @cached_property def pg_version(self): with self.temporary_connection(): return get_version(self.connection)
class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'postgresql' operators = { 'exact': '= %s', 'iexact': '= UPPER(%s)', 'contains': 'LIKE %s', 'icontains': 'LIKE UPPER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE UPPER(%s)', 'iendswith': 'LIKE UPPER(%s)', } pattern_ops = { 'startswith': "LIKE %s || '%%%%'", 'istartswith': "LIKE UPPER(%s) || '%%%%'", } Database = Database def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get('isolation_level', RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) def get_connection_params(self): settings_dict = self.settings_dict # None may be used to connect to the default 'postgres' db if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value.") conn_params = { 'database': settings_dict['NAME'] or 'postgres', } conn_params.update(settings_dict['OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if 'isolation_level' in conn_params: del conn_params['isolation_level'] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = force_str(settings_dict['PASSWORD']) if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) def init_connection_state(self): settings_dict = self.settings_dict self.connection.set_client_encoding('UTF8') tz = 'UTC' if settings.USE_TZ else settings_dict.get('TIME_ZONE') if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status('TimeZone') if conn_tz != tz: cursor = self.connection.cursor() try: cursor.execute(self.ops.set_time_zone_sql(), [tz]) finally: cursor.close() # Commit after setting the time zone (see #17062) if not self.get_autocommit(): self.connection.commit() def create_cursor(self): cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return cursor def _set_isolation_level(self, isolation_level): assert isolation_level in range(1, 5) # Use set_autocommit for level = 0 if self.psycopg2_version >= (2, 4, 2): self.connection.set_session(isolation_level=isolation_level) else: self.connection.set_isolation_level(isolation_level) def _set_autocommit(self, autocommit): with self.wrap_database_errors: if self.psycopg2_version >= (2, 4, 2): self.connection.autocommit = autocommit else: if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = self.isolation_level self.connection.set_isolation_level(level) def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') def is_usable(self): try: # Use a psycopg cursor directly, bypassing Django's utilities. self.connection.cursor().execute("SELECT 1") except Database.Error: return False else: return True def schema_editor(self, *args, **kwargs): "Returns a new instance of this backend's SchemaEditor" return DatabaseSchemaEditor(self, *args, **kwargs) @cached_property def psycopg2_version(self): version = psycopg2.__version__.split(' ', 1)[0] return tuple(int(v) for v in version.split('.')) @cached_property def pg_version(self): with self.temporary_connection(): return get_version(self.connection)
class DatabaseWrapper(BaseDatabaseWrapper): vendor = "postgresql" operators = { "exact": "= %s", "iexact": "= UPPER(%s)", "contains": "LIKE %s", "icontains": "LIKE UPPER(%s)", "regex": "~ %s", "iregex": "~* %s", "gt": "> %s", "gte": ">= %s", "lt": "< %s", "lte": "<= %s", "startswith": "LIKE %s", "endswith": "LIKE %s", "istartswith": "LIKE UPPER(%s)", "iendswith": "LIKE UPPER(%s)", } pattern_ops = {"startswith": "LIKE %s || '%%%%'", "istartswith": "LIKE UPPER(%s) || '%%%%'"} Database = Database def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get("isolation_level", RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) def get_connection_params(self): settings_dict = self.settings_dict # None may be used to connect to the default 'postgres' db if settings_dict["NAME"] == "": from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("settings.DATABASES is improperly configured. " "Please supply the NAME value.") conn_params = {"database": settings_dict["NAME"] or "postgres"} conn_params.update(settings_dict["OPTIONS"]) if "autocommit" in conn_params: del conn_params["autocommit"] if "isolation_level" in conn_params: del conn_params["isolation_level"] if settings_dict["USER"]: conn_params["user"] = settings_dict["USER"] if settings_dict["PASSWORD"]: conn_params["password"] = force_str(settings_dict["PASSWORD"]) if settings_dict["HOST"]: conn_params["host"] = settings_dict["HOST"] if settings_dict["PORT"]: conn_params["port"] = settings_dict["PORT"] return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) def init_connection_state(self): settings_dict = self.settings_dict self.connection.set_client_encoding("UTF8") tz = "UTC" if settings.USE_TZ else settings_dict.get("TIME_ZONE") if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status("TimeZone") if conn_tz != tz: cursor = self.connection.cursor() try: cursor.execute(self.ops.set_time_zone_sql(), [tz]) finally: cursor.close() # Commit after setting the time zone (see #17062) if not self.get_autocommit(): self.connection.commit() def create_cursor(self): cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return cursor def _set_isolation_level(self, isolation_level): assert isolation_level in range(1, 5) # Use set_autocommit for level = 0 if self.psycopg2_version >= (2, 4, 2): self.connection.set_session(isolation_level=isolation_level) else: self.connection.set_isolation_level(isolation_level) def _set_autocommit(self, autocommit): with self.wrap_database_errors: if self.psycopg2_version >= (2, 4, 2): self.connection.autocommit = autocommit else: if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = self.isolation_level self.connection.set_isolation_level(level) def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute("SET CONSTRAINTS ALL IMMEDIATE") self.cursor().execute("SET CONSTRAINTS ALL DEFERRED") def is_usable(self): try: # Use a psycopg cursor directly, bypassing Django's utilities. self.connection.cursor().execute("SELECT 1") except Database.Error: return False else: return True def schema_editor(self, *args, **kwargs): "Returns a new instance of this backend's SchemaEditor" return DatabaseSchemaEditor(self, *args, **kwargs) @cached_property def psycopg2_version(self): version = psycopg2.__version__.split(" ", 1)[0] return tuple(int(v) for v in version.split(".")) @cached_property def pg_version(self): with self.temporary_connection(): return get_version(self.connection)
class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'postgresql' operators = { 'exact': '= %s', 'iexact': '= UPPER(%s)', 'contains': 'LIKE %s', 'icontains': 'LIKE UPPER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE UPPER(%s)', 'iendswith': 'LIKE UPPER(%s)', } def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) settings_dict = self.settings_dict self.features = DatabaseFeatures(self) autocommit = settings_dict["OPTIONS"].get('autocommit', False) self.features.uses_autocommit = autocommit if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self._set_isolation_level(level) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) self._pg_version = None if not settings_dict['NAME']: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value.") try: self.pool = _pools[self.alias] except KeyError: 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'] = force_str(settings_dict['PASSWORD']) if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] self.pool = GeventConnectionPool(1, DB_POOL_MAX_CONN, **conn_params) _pools[self.alias] = self.pool def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') def close(self): self.validate_thread_sharing() if self.connection is None: return try: self.pool.putconn(self.connection) self.connection = None except Database.Error: # In some cases (database restart, network connection lost etc...) # the connection to the database is lost without giving Django a # notification. If we don't set self.connection to None, the error # will occur a every request. self.connection = None logger.warning('psycopg2 error while closing the connection.', exc_info=sys.exc_info()) raise def _get_pg_version(self): if self._pg_version is None: self._pg_version = get_version(self.connection) return self._pg_version pg_version = property(_get_pg_version) def _cursor(self): if self.connection is None: self.connection = self.pool.getconn() self.connection.set_client_encoding('UTF8') tz = 'UTC' if settings.USE_TZ else self.settings_dict.get( 'TIME_ZONE') if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status('TimeZone') if conn_tz != tz: # Set the time zone in autocommit mode (see #17062) self.connection.set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) self.connection.cursor().execute( self.ops.set_time_zone_sql(), [tz]) self.connection.set_isolation_level(self.isolation_level) self._get_pg_version() connection_created.send(sender=self.__class__, connection=self) cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return CursorWrapper(cursor) def _enter_transaction_management(self, managed): """ Switch the isolation level when needing transaction support, so that the same transaction is visible across all the queries. """ if self.features.uses_autocommit and managed and not self.isolation_level: self._set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED) def _leave_transaction_management(self, managed): """ If the normal operating mode is "autocommit", switch back to that when leaving transaction management. """ if self.features.uses_autocommit and not managed and self.isolation_level: self._set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) def _set_isolation_level(self, level): """ Do all the related feature configurations for changing isolation levels. This doesn't touch the uses_autocommit feature, since that controls the movement *between* isolation levels. """ assert level in range(5) try: if self.connection is not None: self.connection.set_isolation_level(level) finally: self.isolation_level = level self.features.uses_savepoints = bool(level) def _commit(self): if self.connection is not None: try: return self.connection.commit() except Database.IntegrityError as e: six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'postgresql' operators = { 'exact': '= %s', 'iexact': '= UPPER(%s)', 'contains': 'LIKE %s', 'icontains': 'LIKE UPPER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE UPPER(%s)', 'iendswith': 'LIKE UPPER(%s)', } Database = Database def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get('isolation_level', RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) def get_connection_params(self): settings_dict = self.settings_dict if not settings_dict['NAME']: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value.") conn_params = { 'database': settings_dict['NAME'], } conn_params.update(settings_dict['OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if 'isolation_level' in conn_params: del conn_params['isolation_level'] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = force_str(settings_dict['PASSWORD']) if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) def init_connection_state(self): settings_dict = self.settings_dict self.connection.set_client_encoding('UTF8') tz = 'UTC' if settings.USE_TZ else settings_dict.get('TIME_ZONE') if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status('TimeZone') if conn_tz != tz: # Set the time zone in autocommit mode (see #17062) self.set_autocommit(True) self.connection.cursor().execute(self.ops.set_time_zone_sql(), [tz]) self.connection.set_isolation_level(self.isolation_level) def create_cursor(self): cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return cursor def close(self): self.validate_thread_sharing() if self.connection is None: return try: self.connection.close() self.connection = None except Database.Error: # In some cases (database restart, network connection lost etc...) # the connection to the database is lost without giving Django a # notification. If we don't set self.connection to None, the error # will occur a every request. self.connection = None logger.warning('psycopg2 error while closing the connection.', exc_info=sys.exc_info()) raise finally: self.set_clean() def _set_isolation_level(self, isolation_level): assert isolation_level in range(1, 5) # Use set_autocommit for level = 0 if self.psycopg2_version >= (2, 4, 2): self.connection.set_session(isolation_level=isolation_level) else: self.connection.set_isolation_level(isolation_level) def _set_autocommit(self, autocommit): if self.psycopg2_version >= (2, 4, 2): self.connection.autocommit = autocommit else: if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = self.isolation_level self.connection.set_isolation_level(level) def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') def is_usable(self): try: # Use a psycopg cursor directly, bypassing Django's utilities. self.connection.cursor().execute("SELECT 1") except DatabaseError: return False else: return True @cached_property def psycopg2_version(self): version = psycopg2.__version__.split(' ', 1)[0] return tuple(int(v) for v in version.split('.')) @cached_property def pg_version(self): with self.temporary_connection(): return get_version(self.connection)
class DatabaseWrapper(BaseDatabaseWrapper): vendor = "postgresql" operators = { "exact": "= %s", "iexact": "= UPPER(%s)", "contains": "LIKE %s", "icontains": "LIKE UPPER(%s)", "regex": "~ %s", "iregex": "~* %s", "gt": "> %s", "gte": ">= %s", "lt": "< %s", "lte": "<= %s", "startswith": "LIKE %s", "endswith": "LIKE %s", "istartswith": "LIKE UPPER(%s)", "iendswith": "LIKE UPPER(%s)", } def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures(self) autocommit = self.settings_dict["OPTIONS"].get("autocommit", False) self.features.uses_autocommit = autocommit if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self._set_isolation_level(level) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) self._pg_version = None def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute("SET CONSTRAINTS ALL IMMEDIATE") self.cursor().execute("SET CONSTRAINTS ALL DEFERRED") def close(self): self.validate_thread_sharing() if self.connection is None: return try: self.connection.close() self.connection = None except Database.Error: # In some cases (database restart, network connection lost etc...) # the connection to the database is lost without giving Django a # notification. If we don't set self.connection to None, the error # will occur a every request. self.connection = None logger.warning("psycopg2 error while closing the connection.", exc_info=sys.exc_info()) raise def _get_pg_version(self): if self._pg_version is None: self._pg_version = get_version(self.connection) return self._pg_version pg_version = property(_get_pg_version) def _cursor(self): settings_dict = self.settings_dict if self.connection is None: if not settings_dict["NAME"]: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value." ) 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") tz = "UTC" if settings.USE_TZ else settings_dict.get("TIME_ZONE") if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status("TimeZone") if conn_tz != tz: # Set the time zone in autocommit mode (see #17062) self.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) self.connection.cursor().execute(self.ops.set_time_zone_sql(), [tz]) self.connection.set_isolation_level(self.isolation_level) self._get_pg_version() connection_created.send(sender=self.__class__, connection=self) cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return CursorWrapper(cursor) def _enter_transaction_management(self, managed): """ Switch the isolation level when needing transaction support, so that the same transaction is visible across all the queries. """ if self.features.uses_autocommit and managed and not self.isolation_level: self._set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED) def _leave_transaction_management(self, managed): """ If the normal operating mode is "autocommit", switch back to that when leaving transaction management. """ if self.features.uses_autocommit and not managed and self.isolation_level: self._set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) def _set_isolation_level(self, level): """ Do all the related feature configurations for changing isolation levels. This doesn't touch the uses_autocommit feature, since that controls the movement *between* isolation levels. """ assert level in range(5) try: if self.connection is not None: self.connection.set_isolation_level(level) finally: self.isolation_level = level self.features.uses_savepoints = bool(level) def _commit(self): if self.connection is not None: try: return self.connection.commit() except Database.IntegrityError as e: raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'postgresql' # This dictionary maps Field objects to their associated PostgreSQL column # types, as strings. Column-type strings can contain format strings; they'll # be interpolated against the values of Field.__dict__ before being output. # If a column type is set to None, it won't be included in the output. data_types = { 'AutoField': 'serial', 'BinaryField': 'bytea', 'BooleanField': 'boolean', 'CharField': 'varchar(%(max_length)s)', 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'timestamp with time zone', 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 'DurationField': 'interval', 'FileField': 'varchar(%(max_length)s)', 'FilePathField': 'varchar(%(max_length)s)', 'FloatField': 'double precision', 'IntegerField': 'integer', 'BigIntegerField': 'bigint', 'IPAddressField': 'inet', 'GenericIPAddressField': 'inet', 'NullBooleanField': 'boolean', 'OneToOneField': 'integer', 'PositiveIntegerField': 'integer', 'PositiveSmallIntegerField': 'smallint', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'text', 'TimeField': 'time', 'UUIDField': 'uuid', } data_type_check_constraints = { 'PositiveIntegerField': '"%(column)s" >= 0', 'PositiveSmallIntegerField': '"%(column)s" >= 0', } operators = { 'exact': '= %s', 'iexact': '= UPPER(%s)', 'contains': 'LIKE %s', 'icontains': 'LIKE UPPER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE UPPER(%s)', 'iendswith': 'LIKE UPPER(%s)', } # The patterns below are used to generate SQL pattern lookup clauses when # the right-hand side of the lookup isn't a raw string (it might be an expression # or the result of a bilateral transformation). # In those cases, special characters for LIKE operators (e.g. \, *, _) should be # escaped on database side. # # Note: we use str.format() here for readability as '%' is used as a wildcard for # the LIKE operator. pattern_esc = r"REPLACE(REPLACE(REPLACE({}, '\', '\\'), '%%', '\%%'), '_', '\_')" pattern_ops = { 'contains': "LIKE '%%' || {} || '%%'", 'icontains': "LIKE '%%' || UPPER({}) || '%%'", 'startswith': "LIKE {} || '%%'", 'istartswith': "LIKE UPPER({}) || '%%'", 'endswith': "LIKE '%%' || {}", 'iendswith': "LIKE '%%' || UPPER({})", } Database = Database SchemaEditorClass = DatabaseSchemaEditor def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get('isolation_level', RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) def get_connection_params(self): settings_dict = self.settings_dict # None may be used to connect to the default 'postgres' db if settings_dict['NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value.") conn_params = { 'database': settings_dict['NAME'] or 'postgres', } conn_params.update(settings_dict['OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if 'isolation_level' in conn_params: del conn_params['isolation_level'] if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: conn_params['password'] = force_str(settings_dict['PASSWORD']) if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) def init_connection_state(self): settings_dict = self.settings_dict self.connection.set_client_encoding('UTF8') tz = 'UTC' if settings.USE_TZ else settings_dict.get('TIME_ZONE') if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status('TimeZone') if conn_tz != tz: cursor = self.connection.cursor() try: cursor.execute(self.ops.set_time_zone_sql(), [tz]) finally: cursor.close() # Commit after setting the time zone (see #17062) if not self.get_autocommit(): self.connection.commit() def create_cursor(self): cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return cursor def _set_isolation_level(self, isolation_level): assert isolation_level in range(1, 5) # Use set_autocommit for level = 0 if self.psycopg2_version >= (2, 4, 2): self.connection.set_session(isolation_level=isolation_level) else: self.connection.set_isolation_level(isolation_level) def _set_autocommit(self, autocommit): with self.wrap_database_errors: if self.psycopg2_version >= (2, 4, 2): self.connection.autocommit = autocommit else: if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = self.isolation_level self.connection.set_isolation_level(level) def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') def is_usable(self): try: # Use a psycopg cursor directly, bypassing Django's utilities. self.connection.cursor().execute("SELECT 1") except Database.Error: return False else: return True @cached_property def psycopg2_version(self): version = psycopg2.__version__.split(' ', 1)[0] return tuple(int(v) for v in version.split('.') if v.isdigit()) @cached_property def pg_version(self): with self.temporary_connection(): return get_version(self.connection)
class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'postgresql' operators = { 'exact': '= %s', 'iexact': '= UPPER(%s)', 'contains': 'LIKE %s', 'icontains': 'LIKE UPPER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE UPPER(%s)', 'iendswith': 'LIKE UPPER(%s)', } Database = Database def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures(self) autocommit = self.settings_dict["OPTIONS"].get('autocommit', False) self.features.uses_autocommit = autocommit if autocommit: level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT else: level = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self._set_isolation_level(level) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation(self) def check_constraints(self, table_names=None): """ To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they are returned to deferred. """ self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') def close(self): self.validate_thread_sharing() if self.connection is None: return try: self.connection.close() self.connection = None except Database.Error: # In some cases (database restart, network connection lost etc...) # the connection to the database is lost without giving Django a # notification. If we don't set self.connection to None, the error # will occur a every request. self.connection = None logger.warning('psycopg2 error while closing the connection.', exc_info=sys.exc_info() ) raise finally: self.set_clean() @cached_property def pg_version(self): with self.temporary_connection(): return get_version(self.connection) def get_connection_params(self): settings_dict = self.settings_dict if not settings_dict['NAME']: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured( "settings.DATABASES is improperly configured. " "Please supply the NAME value.") 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'] = force_str(settings_dict['PASSWORD']) if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: conn_params['port'] = settings_dict['PORT'] return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) def init_connection_state(self): settings_dict = self.settings_dict self.connection.set_client_encoding('UTF8') tz = 'UTC' if settings.USE_TZ else settings_dict.get('TIME_ZONE') if tz: try: get_parameter_status = self.connection.get_parameter_status except AttributeError: # psycopg2 < 2.0.12 doesn't have get_parameter_status conn_tz = None else: conn_tz = get_parameter_status('TimeZone') if conn_tz != tz: # Set the time zone in autocommit mode (see #17062) self.connection.set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) self.connection.cursor().execute( self.ops.set_time_zone_sql(), [tz]) self.connection.set_isolation_level(self.isolation_level) def create_cursor(self): cursor = self.connection.cursor() cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None return cursor def _enter_transaction_management(self, managed): """ Switch the isolation level when needing transaction support, so that the same transaction is visible across all the queries. """ if self.features.uses_autocommit and managed and not self.isolation_level: self._set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED) def _leave_transaction_management(self, managed): """ If the normal operating mode is "autocommit", switch back to that when leaving transaction management. """ if self.features.uses_autocommit and not managed and self.isolation_level: self._set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) def _set_isolation_level(self, level): """ Do all the related feature configurations for changing isolation levels. This doesn't touch the uses_autocommit feature, since that controls the movement *between* isolation levels. """ assert level in range(5) try: if self.connection is not None: self.connection.set_isolation_level(level) if level == psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT: self.set_clean() finally: self.isolation_level = level self.features.uses_savepoints = bool(level) def set_dirty(self): if ((self.transaction_state and self.transaction_state[-1]) or not self.features.uses_autocommit): super(DatabaseWrapper, self).set_dirty()