Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

creation.py 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import subprocess
  2. import sys
  3. from django.db.backends.base.creation import BaseDatabaseCreation
  4. from .client import DatabaseClient
  5. class DatabaseCreation(BaseDatabaseCreation):
  6. def sql_table_creation_suffix(self):
  7. suffix = []
  8. test_settings = self.connection.settings_dict['TEST']
  9. if test_settings['CHARSET']:
  10. suffix.append('CHARACTER SET %s' % test_settings['CHARSET'])
  11. if test_settings['COLLATION']:
  12. suffix.append('COLLATE %s' % test_settings['COLLATION'])
  13. return ' '.join(suffix)
  14. def _execute_create_test_db(self, cursor, parameters, keepdb=False):
  15. try:
  16. if keepdb:
  17. # If the database should be kept, add "IF NOT EXISTS" to avoid
  18. # "database exists" error, also temporarily disable "database
  19. # exists" warning.
  20. cursor.execute('''
  21. SET @_tmp_sql_notes := @@sql_notes, sql_notes = 0;
  22. CREATE DATABASE IF NOT EXISTS %(dbname)s %(suffix)s;
  23. SET sql_notes = @_tmp_sql_notes;
  24. ''' % parameters)
  25. else:
  26. super()._execute_create_test_db(cursor, parameters, keepdb)
  27. except Exception as e:
  28. if len(e.args) < 1 or e.args[0] != 1007:
  29. # All errors except "database exists" (1007) cancel tests.
  30. sys.stderr.write('Got an error creating the test database: %s\n' % e)
  31. sys.exit(2)
  32. else:
  33. raise e
  34. def _clone_test_db(self, suffix, verbosity, keepdb=False):
  35. source_database_name = self.connection.settings_dict['NAME']
  36. target_database_name = self.get_test_db_clone_settings(suffix)['NAME']
  37. test_db_params = {
  38. 'dbname': self.connection.ops.quote_name(target_database_name),
  39. 'suffix': self.sql_table_creation_suffix(),
  40. }
  41. with self._nodb_connection.cursor() as cursor:
  42. try:
  43. self._execute_create_test_db(cursor, test_db_params, keepdb)
  44. except Exception:
  45. try:
  46. if verbosity >= 1:
  47. print("Destroying old test database for alias %s..." % (
  48. self._get_database_display_str(verbosity, target_database_name),
  49. ))
  50. cursor.execute('DROP DATABASE %(dbname)s' % test_db_params)
  51. self._execute_create_test_db(cursor, test_db_params, keepdb)
  52. except Exception as e:
  53. sys.stderr.write("Got an error recreating the test database: %s\n" % e)
  54. sys.exit(2)
  55. dump_cmd = DatabaseClient.settings_to_cmd_args(self.connection.settings_dict)
  56. dump_cmd[0] = 'mysqldump'
  57. dump_cmd[-1] = source_database_name
  58. load_cmd = DatabaseClient.settings_to_cmd_args(self.connection.settings_dict)
  59. load_cmd[-1] = target_database_name
  60. dump_proc = subprocess.Popen(dump_cmd, stdout=subprocess.PIPE)
  61. load_proc = subprocess.Popen(load_cmd, stdin=dump_proc.stdout, stdout=subprocess.PIPE)
  62. dump_proc.stdout.close() # allow dump_proc to receive a SIGPIPE if load_proc exits.
  63. load_proc.communicate()