creation.py 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import os
  2. import sys
  3. from django.db.backends.creation import BaseDatabaseCreation
  4. from django.utils.six.moves import input
  5. class DatabaseCreation(BaseDatabaseCreation):
  6. # SQLite doesn't actually support most of these types, but it "does the right
  7. # thing" given more verbose field definitions, so leave them as is so that
  8. # schema inspection is more useful.
  9. data_types = {
  10. 'AutoField': 'integer',
  11. 'BinaryField': 'BLOB',
  12. 'BooleanField': 'bool',
  13. 'CharField': 'varchar(%(max_length)s)',
  14. 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
  15. 'DateField': 'date',
  16. 'DateTimeField': 'datetime',
  17. 'DecimalField': 'decimal',
  18. 'FileField': 'varchar(%(max_length)s)',
  19. 'FilePathField': 'varchar(%(max_length)s)',
  20. 'FloatField': 'real',
  21. 'IntegerField': 'integer',
  22. 'BigIntegerField': 'bigint',
  23. 'IPAddressField': 'char(15)',
  24. 'GenericIPAddressField': 'char(39)',
  25. 'NullBooleanField': 'bool',
  26. 'OneToOneField': 'integer',
  27. 'PositiveIntegerField': 'integer unsigned',
  28. 'PositiveSmallIntegerField': 'smallint unsigned',
  29. 'SlugField': 'varchar(%(max_length)s)',
  30. 'SmallIntegerField': 'smallint',
  31. 'TextField': 'text',
  32. 'TimeField': 'time',
  33. }
  34. data_types_suffix = {
  35. 'AutoField': 'AUTOINCREMENT',
  36. }
  37. def sql_for_pending_references(self, model, style, pending_references):
  38. "SQLite3 doesn't support constraints"
  39. return []
  40. def sql_remove_table_constraints(self, model, references_to_delete, style):
  41. "SQLite3 doesn't support constraints"
  42. return []
  43. def _get_test_db_name(self):
  44. test_database_name = self.connection.settings_dict['TEST']['NAME']
  45. if test_database_name and test_database_name != ':memory:':
  46. return test_database_name
  47. return ':memory:'
  48. def _create_test_db(self, verbosity, autoclobber):
  49. test_database_name = self._get_test_db_name()
  50. if test_database_name != ':memory:':
  51. # Erase the old test database
  52. if verbosity >= 1:
  53. print("Destroying old test database '%s'..." % self.connection.alias)
  54. if os.access(test_database_name, os.F_OK):
  55. if not autoclobber:
  56. confirm = input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name)
  57. if autoclobber or confirm == 'yes':
  58. try:
  59. os.remove(test_database_name)
  60. except Exception as e:
  61. sys.stderr.write("Got an error deleting the old test database: %s\n" % e)
  62. sys.exit(2)
  63. else:
  64. print("Tests cancelled.")
  65. sys.exit(1)
  66. return test_database_name
  67. def _destroy_test_db(self, test_database_name, verbosity):
  68. if test_database_name and test_database_name != ":memory:":
  69. # Remove the SQLite database file
  70. os.remove(test_database_name)
  71. def test_db_signature(self):
  72. """
  73. Returns a tuple that uniquely identifies a test database.
  74. This takes into account the special cases of ":memory:" and "" for
  75. SQLite since the databases will be distinct despite having the same
  76. TEST NAME. See http://www.sqlite.org/inmemorydb.html
  77. """
  78. test_dbname = self._get_test_db_name()
  79. sig = [self.connection.settings_dict['NAME']]
  80. if test_dbname == ':memory:':
  81. sig.append(self.connection.alias)
  82. return tuple(sig)