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.

recorder.py 2.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. from django.apps.registry import Apps
  2. from django.db import models
  3. from django.db.utils import DatabaseError
  4. from django.utils.timezone import now
  5. from .exceptions import MigrationSchemaMissing
  6. class MigrationRecorder:
  7. """
  8. Deal with storing migration records in the database.
  9. Because this table is actually itself used for dealing with model
  10. creation, it's the one thing we can't do normally via migrations.
  11. We manually handle table creation/schema updating (using schema backend)
  12. and then have a floating model to do queries with.
  13. If a migration is unapplied its row is removed from the table. Having
  14. a row in the table always means a migration is applied.
  15. """
  16. class Migration(models.Model):
  17. app = models.CharField(max_length=255)
  18. name = models.CharField(max_length=255)
  19. applied = models.DateTimeField(default=now)
  20. class Meta:
  21. apps = Apps()
  22. app_label = "migrations"
  23. db_table = "django_migrations"
  24. def __str__(self):
  25. return "Migration %s for %s" % (self.name, self.app)
  26. def __init__(self, connection):
  27. self.connection = connection
  28. @property
  29. def migration_qs(self):
  30. return self.Migration.objects.using(self.connection.alias)
  31. def has_table(self):
  32. """Return True if the django_migrations table exists."""
  33. return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
  34. def ensure_schema(self):
  35. """Ensure the table exists and has the correct schema."""
  36. # If the table's there, that's fine - we've never changed its schema
  37. # in the codebase.
  38. if self.has_table():
  39. return
  40. # Make the table
  41. try:
  42. with self.connection.schema_editor() as editor:
  43. editor.create_model(self.Migration)
  44. except DatabaseError as exc:
  45. raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)
  46. def applied_migrations(self):
  47. """Return a set of (app, name) of applied migrations."""
  48. if self.has_table():
  49. return {tuple(x) for x in self.migration_qs.values_list('app', 'name')}
  50. else:
  51. # If the django_migrations table doesn't exist, then no migrations
  52. # are applied.
  53. return set()
  54. def record_applied(self, app, name):
  55. """Record that a migration was applied."""
  56. self.ensure_schema()
  57. self.migration_qs.create(app=app, name=name)
  58. def record_unapplied(self, app, name):
  59. """Record that a migration was unapplied."""
  60. self.ensure_schema()
  61. self.migration_qs.filter(app=app, name=name).delete()
  62. def flush(self):
  63. """Delete all migration records. Useful for testing migrations."""
  64. self.migration_qs.all().delete()