creation.py 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from django.db.backends.creation import BaseDatabaseCreation
  2. from django.db.backends.utils import truncate_name
  3. class DatabaseCreation(BaseDatabaseCreation):
  4. # This dictionary maps Field objects to their associated PostgreSQL column
  5. # types, as strings. Column-type strings can contain format strings; they'll
  6. # be interpolated against the values of Field.__dict__ before being output.
  7. # If a column type is set to None, it won't be included in the output.
  8. data_types = {
  9. 'AutoField': 'serial',
  10. 'BinaryField': 'bytea',
  11. 'BooleanField': 'boolean',
  12. 'CharField': 'varchar(%(max_length)s)',
  13. 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
  14. 'DateField': 'date',
  15. 'DateTimeField': 'timestamp with time zone',
  16. 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
  17. 'FileField': 'varchar(%(max_length)s)',
  18. 'FilePathField': 'varchar(%(max_length)s)',
  19. 'FloatField': 'double precision',
  20. 'IntegerField': 'integer',
  21. 'BigIntegerField': 'bigint',
  22. 'IPAddressField': 'inet',
  23. 'GenericIPAddressField': 'inet',
  24. 'NullBooleanField': 'boolean',
  25. 'OneToOneField': 'integer',
  26. 'PositiveIntegerField': 'integer',
  27. 'PositiveSmallIntegerField': 'smallint',
  28. 'SlugField': 'varchar(%(max_length)s)',
  29. 'SmallIntegerField': 'smallint',
  30. 'TextField': 'text',
  31. 'TimeField': 'time',
  32. }
  33. data_type_check_constraints = {
  34. 'PositiveIntegerField': '"%(column)s" >= 0',
  35. 'PositiveSmallIntegerField': '"%(column)s" >= 0',
  36. }
  37. def sql_table_creation_suffix(self):
  38. test_settings = self.connection.settings_dict['TEST']
  39. assert test_settings['COLLATION'] is None, "PostgreSQL does not support collation setting at database creation time."
  40. if test_settings['CHARSET']:
  41. return "WITH ENCODING '%s'" % test_settings['CHARSET']
  42. return ''
  43. def sql_indexes_for_field(self, model, f, style):
  44. output = []
  45. db_type = f.db_type(connection=self.connection)
  46. if db_type is not None and (f.db_index or f.unique):
  47. qn = self.connection.ops.quote_name
  48. db_table = model._meta.db_table
  49. tablespace = f.db_tablespace or model._meta.db_tablespace
  50. if tablespace:
  51. tablespace_sql = self.connection.ops.tablespace_sql(tablespace)
  52. if tablespace_sql:
  53. tablespace_sql = ' ' + tablespace_sql
  54. else:
  55. tablespace_sql = ''
  56. def get_index_sql(index_name, opclass=''):
  57. return (style.SQL_KEYWORD('CREATE INDEX') + ' ' +
  58. style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + ' ' +
  59. style.SQL_KEYWORD('ON') + ' ' +
  60. style.SQL_TABLE(qn(db_table)) + ' ' +
  61. "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) +
  62. "%s;" % tablespace_sql)
  63. if not f.unique:
  64. output = [get_index_sql('%s_%s' % (db_table, f.column))]
  65. # Fields with database column types of `varchar` and `text` need
  66. # a second index that specifies their operator class, which is
  67. # needed when performing correct LIKE queries outside the
  68. # C locale. See #12234.
  69. if db_type.startswith('varchar'):
  70. output.append(get_index_sql('%s_%s_like' % (db_table, f.column),
  71. ' varchar_pattern_ops'))
  72. elif db_type.startswith('text'):
  73. output.append(get_index_sql('%s_%s_like' % (db_table, f.column),
  74. ' text_pattern_ops'))
  75. return output