示例#1
0
 def as_postgresql(self, compiler, connection):
     function = None
     if self.geo_field.geodetic(connection) and not self.source_is_geography():
         raise NotSupportedError("ST_Perimeter cannot use a non-projected non-geography field.")
     dim = min(f.dim for f in self.get_source_fields())
     if dim > 2:
         function = connection.ops.perimeter3d
     return super().as_sql(compiler, connection, function=function)
示例#2
0
 def alter_db_table(self, model, old_db_table, new_db_table, disable_constraints=True):
     if disable_constraints and self._is_referenced_by_fk_constraint(old_db_table):
         if self.connection.in_atomic_block:
             raise NotSupportedError((
                 'Renaming the %r table while in a transaction is not '
                 'supported on SQLite because it would break referential '
                 'integrity. Try adding `atomic = False` to the Migration class.'
             ) % old_db_table)
         self.connection.enable_constraint_checking()
         super().alter_db_table(model, old_db_table, new_db_table)
         self.connection.disable_constraint_checking()
     else:
         super().alter_db_table(model, old_db_table, new_db_table)
示例#3
0
 def __enter__(self):
     # Some SQLite schema alterations need foreign key constraints to be
     # disabled. Enforce it here for the duration of the schema edition.
     if not self.connection.disable_constraint_checking():
         raise NotSupportedError(
             'SQLite schema editor cannot be used while foreign key '
             'constraint checks are enabled. Make sure to disable them '
             'before entering a transaction.atomic() context because '
             'SQLite3 does not support disabling them in the middle of '
             'a multi-statement transaction.'
         )
     self.connection.cursor().execute('PRAGMA legacy_alter_table = ON')
     return super().__enter__()
示例#4
0
 def callproc(self, procname, params=None, kparams=None):
     # Keyword parameters for callproc aren't supported in PEP 249, but the
     # database driver may support them (e.g. cx_Oracle).
     if kparams is not None and not self.db.features.supports_callproc_kwargs:
         raise NotSupportedError(
             'Keyword parameters for callproc are not supported on this '
             'database backend.'
         )
     self.db.validate_no_broken_transaction()
     with self.db.wrap_database_errors:
         if params is None and kparams is None:
             return self.cursor.callproc(procname)
         elif kparams is None:
             return self.cursor.callproc(procname, params)
         else:
             params = params or ()
             return self.cursor.callproc(procname, params, kparams)
示例#5
0
    def geo_db_type(self, f):
        """
        Return the database field type for the given spatial field.
        """
        if f.geom_type == 'RASTER':
            return 'raster'

        # Type-based geometries.
        # TODO: Support 'M' extension.
        if f.dim == 3:
            geom_type = f.geom_type + 'Z'
        else:
            geom_type = f.geom_type
        if f.geography:
            if f.srid != 4326:
                raise NotSupportedError(
                    'PostGIS only supports geography columns with an SRID of 4326.'
                )

            return 'geography(%s,%d)' % (geom_type, f.srid)
        else:
            return 'geometry(%s,%d)' % (geom_type, f.srid)
示例#6
0
 def alter_field(self, model, old_field, new_field, strict=False):
     old_field_name = old_field.name
     table_name = model._meta.db_table
     _, old_column_name = old_field.get_attname_column()
     if (new_field.name != old_field_name and
             self._is_referenced_by_fk_constraint(table_name, old_column_name, ignore_self=True)):
         if self.connection.in_atomic_block:
             raise NotSupportedError((
                 'Renaming the %r.%r column while in a transaction is not '
                 'supported on SQLite because it would break referential '
                 'integrity. Try adding `atomic = False` to the Migration class.'
             ) % (model._meta.db_table, old_field_name))
         with atomic(self.connection.alias):
             super().alter_field(model, old_field, new_field, strict=strict)
             # Follow SQLite's documented procedure for performing changes
             # that don't affect the on-disk content.
             # https://sqlite.org/lang_altertable.html#otheralter
             with self.connection.cursor() as cursor:
                 schema_version = cursor.execute('PRAGMA schema_version').fetchone()[0]
                 cursor.execute('PRAGMA writable_schema = 1')
                 references_template = ' REFERENCES "%s" ("%%s") ' % table_name
                 new_column_name = new_field.get_attname_column()[1]
                 search = references_template % old_column_name
                 replacement = references_template % new_column_name
                 cursor.execute('UPDATE sqlite_master SET sql = replace(sql, %s, %s)', (search, replacement))
                 cursor.execute('PRAGMA schema_version = %d' % (schema_version + 1))
                 cursor.execute('PRAGMA writable_schema = 0')
                 # The integrity check will raise an exception and rollback
                 # the transaction if the sqlite_master updates corrupt the
                 # database.
                 cursor.execute('PRAGMA integrity_check')
         # Perform a VACUUM to refresh the database representation from
         # the sqlite_master table.
         with self.connection.cursor() as cursor:
             cursor.execute('VACUUM')
     else:
         super().alter_field(model, old_field, new_field, strict=strict)
示例#7
0
 def spatial_function_name(self, func_name):
     if func_name in self.unsupported_functions:
         raise NotSupportedError(
             "This backend doesn't support the %s function." % func_name)
     return self.function_names.get(func_name,
                                    self.geom_func_prefix + func_name)
示例#8
0
 def check_expression_support(self, expression):
     if isinstance(expression, self.disallowed_aggregates):
         raise NotSupportedError(
             "%s spatial aggregation is not supported by this database backend."
             % expression.name)
     super().check_expression_support(expression)
示例#9
0
 def as_sqlite(self, compiler, connection):
     if self.geo_field.geodetic(connection):
         raise NotSupportedError("Perimeter cannot use a non-projected field.")
     return super().as_sql(compiler, connection)
示例#10
0
 def as_sql(self, compiler, connection, **extra_context):
     if self.geo_field.geodetic(connection) and not connection.features.supports_length_geodetic:
         raise NotSupportedError("This backend doesn't support Length on geodetic fields")
     return super().as_sql(compiler, connection, **extra_context)
示例#11
0
 def as_sql(self, compiler, connection, **extra_context):
     if not connection.features.supports_area_geodetic and self.geo_field.geodetic(connection):
         raise NotSupportedError('Area on geodetic coordinate systems not supported.')
     return super().as_sql(compiler, connection, **extra_context)