def get_changes(self): # Get the model defs so we can use them for the yield later model_defs = freeze_apps([self.migrations.app_label()]) # Make the model changes for model_name in self.added_models: model = models.get_model(self.migrations.app_label(), model_name) real_fields, meta, m2m_fields = self.split_model_def(model, model_defs[model_key(model)]) yield ("AddModel", { "model": model, "model_def": real_fields, }) # And the field changes for field_desc in self.added_fields: try: model_name, field_name = field_desc.split(".") except (TypeError, ValueError): raise ValueError("%r is not a valid field description." % field_desc) model = models.get_model(self.migrations.app_label(), model_name) real_fields, meta, m2m_fields = self.split_model_def(model, model_defs[model_key(model)]) yield ("AddField", { "model": model, "field": model._meta.get_field_by_name(field_name)[0], "field_def": real_fields[field_name], }) # And the indexes for field_desc in self.added_indexes: try: model_name, field_name = field_desc.split(".") except (TypeError, ValueError): print("%r is not a valid field description." % field_desc) model = models.get_model(self.migrations.app_label(), model_name) yield ("AddIndex", { "model": model, "fields": [model._meta.get_field_by_name(field_name)[0]], })
def test_not_deleted_auto(self): empty_defs = { } old_defs = freezer.freeze_apps(["non_managed"]) class InitialMigration(SchemaMigration): "Serves as fake previous migration" def forwards(self, orm): pass def backwards(self, orm): pass models = self.full_defs complete_apps = ['non_managed'] migrations = Migrations("non_managed") initial_orm = FakeORM(InitialMigration, "non_managed") changes = AutoChanges( migrations = migrations, old_defs = self.full_defs, old_orm = initial_orm, new_defs = empty_defs, ) change_list = changes.get_changes() if list(change_list): self.fail("Auto migration deletes table for non-managed model")
def test_not_deleted_auto(self): empty_defs = {} old_defs = freezer.freeze_apps(["non_managed"]) class InitialMigration(SchemaMigration): "Serves as fake previous migration" def forwards(self, orm): pass def backwards(self, orm): pass models = self.full_defs complete_apps = ['non_managed'] migrations = Migrations("non_managed") initial_orm = FakeORM(InitialMigration, "non_managed") changes = AutoChanges( migrations=migrations, old_defs=self.full_defs, old_orm=initial_orm, new_defs=empty_defs, ) change_list = changes.get_changes() if list(change_list): self.fail("Auto migration deletes table for non-managed model")
def get_changes(self): # Get the frozen models for this app model_defs = freeze_apps([self.migrations.app_label()]) for model in models.get_models( models.get_app(self.migrations.app_label())): # Don't do anything for unmanaged, abstract or proxy models if model._meta.abstract or getattr( model._meta, "proxy", False) or not getattr(model._meta, "managed", True): continue real_fields, meta, m2m_fields = self.split_model_def( model, model_defs[model_key(model)]) # Firstly, add the main table and fields yield ("AddModel", { "model": model, "model_def": real_fields, }) # Then, add any indexing/uniqueness that's around if meta: for attr, operation in (("unique_together", "AddUnique"), ("index_together", "AddIndex")): together = eval(meta.get(attr, "[]")) if together: # If it's only a single tuple, make it into the longer one if isinstance(together[0], string_types): together = [together] # For each combination, make an action for it for fields in together: yield (operation, { "model": model, "fields": [ model._meta.get_field_by_name(x)[0] for x in fields ], }) # Finally, see if there's some M2M action for name, triple in m2m_fields.items(): field = model._meta.get_field_by_name(name)[0] # But only if it's not through=foo (#120) if field.rel.through: try: # Django 1.1 and below through_model = field.rel.through_model except AttributeError: # Django 1.2 through_model = field.rel.through if (not field.rel.through) or getattr(through_model._meta, "auto_created", False): yield ("AddM2M", { "model": model, "field": field, })
def test_south_migrations(self): from django.core.exceptions import ImproperlyConfigured from django.conf import settings from django.db import models from south.migration import Migrations, migrate_app from south.models import MigrationHistory from south.exceptions import NoMigrations from south.creator import changes, actions, freezer from south.management.commands.datamigration import Command as DataCommand apps = [app for app in settings.INSTALLED_APPS if app.startswith('wagtail.')] failing_apps = [] for app_name in apps: app = app_name.split('.')[-1] try: models.get_app(app) except ImproperlyConfigured: # This module fails to load, probably because it has no # models.py. Ignore it and move on continue try: migrations = Migrations(app, force_creation=False, verbose_creation=False) last_migration = migrations[-1] except (NoMigrations, IndexError): # No migrations for this app, probably doesnt have models continue if migrations.app_label() not in getattr(last_migration.migration_class(), "complete_apps", []): self.fail("Automatic migrations checking failed, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label()) # Alright, construct two model dicts to run the differ on. old_defs = dict( (k, v) for k, v in last_migration.migration_class().models.items() if k.split(".")[0] == migrations.app_label() ) new_defs = dict( (k, v) for k, v in freezer.freeze_apps([migrations.app_label()]).items() if k.split(".")[0] == migrations.app_label() ) change_source = changes.AutoChanges( migrations = migrations, old_defs = old_defs, old_orm = last_migration.orm(), new_defs = new_defs, ) name = 'test' # Get the actions, and then insert them into the actions lists if list(change_source.get_changes()): failing_apps.append(app_name) if failing_apps: self.fail('Model changes with no South migration detected in apps: %s' % ( ', '.join(failing_apps)))
def get_user_frozen_models(user_model): from south.creator.freezer import freeze_apps user_app, user_class = user_model.split('.') if user_model != 'auth.User': from south.migration.base import Migrations from south.exceptions import NoMigrations try: user_migrations = Migrations(user_app) except NoMigrations: extra_model = freeze_apps(user_app) else: from pybb import defaults migration_name = defaults.PYBB_INITIAL_CUSTOM_USER_MIGRATION or '0001_initial.py' initial_user_migration = user_migrations.migration(migration_name) extra_model = initial_user_migration.migration_class().models else: extra_model = freeze_apps(user_app) return extra_model
def get_user_frozen_models(user_model): from south.creator.freezer import freeze_apps user_app, user_class = user_model.split('.') if user_model != 'auth.User': from south.migration.base import Migrations from south.exceptions import NoMigrations try: user_migrations = Migrations(user_app) except NoMigrations: extra_model = freeze_apps(user_app) else: from noticeapp import defaults migration_name = defaults.PYBB_INITIAL_CUSTOM_USER_MIGRATION or '0001_initial.py' initial_user_migration = user_migrations.migration(migration_name) extra_model = initial_user_migration.migration_class().models else: extra_model = freeze_apps(user_app) return extra_model
def get_indexes(self): # TODO: не удаляются индексы у внешних ключей и добавочные # _like-индексы к ним. Например у House migration = Migrations('fias', force_creation=True) # получим текущее состояние базы new_defs = dict( (k, v) for k, v in freezer.freeze_apps([migration.app_label()]).items() if k.split(".")[0] == migration.app_label()) # скопируем и удалим все индексы old_defs = copy.deepcopy(new_defs) for table in old_defs.values(): for key, value in table.items(): # удалим 'index_together' if key == 'Meta' and 'index_together' in value: del value['index_together'] if isinstance(value, tuple): # удалим 'unique' if 'unique' in value[2]: value[2]['unique'] = False # удалим 'db_index' if 'db_index' in value[2]: value[2]['db_index'] = False class InitialMigration(SchemaMigration): def forwards(self, orm): pass def backwards(self, orm): pass models = old_defs complete_apps = ['fias'] initial_orm = FakeORM(InitialMigration, "fias") # получим все изменения, т.е. список индексов change_source = changes.AutoChanges( migrations=migration, old_defs=old_defs, old_orm=initial_orm, new_defs=new_defs, ) for action_name, params in change_source.get_changes(): try: action_class = getattr(actions, action_name) except AttributeError: raise ValueError("Invalid action name from source: %s" % action_name) else: if issubclass(action_class, AddUnique): yield action_class, params
def get_changes(self): # Get the frozen models for this app model_defs = freeze_apps([self.migrations.app_label()]) for model in models.get_models(models.get_app(self.migrations.app_label())): # Don't do anything for unmanaged, abstract or proxy models if model._meta.abstract or getattr( model._meta, "proxy", False) or not getattr(model._meta, "managed", True): continue real_fields, meta, m2m_fields = self.split_model_def( model, model_defs[model_key(model)]) # Firstly, add the main table and fields yield ("AddModel", { "model": model, "model_def": real_fields, }) # Then, add any indexing/uniqueness that's around if meta: for attr, operation in (("unique_together", "AddUnique"), ("index_together", "AddIndex")): together = eval(meta.get(attr, "[]")) if together: # If it's only a single tuple, make it into the longer one if isinstance(together[0], string_types): together = [together] # For each combination, make an action for it for fields in together: yield (operation, { "model": model, "fields": [model._meta.get_field_by_name(x)[0] for x in fields], }) # Finally, see if there's some M2M action for name, triple in m2m_fields.items(): field = model._meta.get_field_by_name(name)[0] # But only if it's not through=foo (#120) if field.rel.through: try: # Django 1.1 and below through_model = field.rel.through_model except AttributeError: # Django 1.2 through_model = field.rel.through if (not field.rel.through) or getattr(through_model._meta, "auto_created", False): yield ("AddM2M", { "model": model, "field": field, })
def get_changes(self): # Get the model defs so we can use them for the yield later model_defs = freeze_apps([self.migrations.app_label()]) # Make the model changes for model_name in self.added_models: model = models.get_model(self.migrations.app_label(), model_name) real_fields, meta, m2m_fields = self.split_model_def(model, model_defs[model_key(model)]) yield ("AddModel", { "model": model, "model_def": real_fields, }) # And the field changes for field_name in self.added_fields: raise NotImplementedError # And the indexes for index_name in self.added_indexes: raise NotImplementedError
def custom_user_frozen_models(user_model): migration_name = getattr(settings, 'INITIAL_CUSTOM_USER_MIGRATION', '0001_initial.py') if user_model != 'auth.User': from south.migration.base import Migrations from south.exceptions import NoMigrations from south.creator.freezer import freeze_apps user_app, user_model = user_model.split('.') try: user_migrations = Migrations(user_app) except NoMigrations: extra_model = freeze_apps(user_app) else: initial_user_migration = user_migrations.migration(migration_name) extra_model = initial_user_migration.migration_class().models else: extra_model = {} return extra_model
def get_changes(self): # Get the frozen models for this app model_defs = freeze_apps([self.migrations.app_label()]) for model in models.get_models(models.get_app(self.migrations.app_label())): # Don't do anything for unmanaged, abstract or proxy models if ( model._meta.abstract or getattr(model._meta, "proxy", False) or not getattr(model._meta, "managed", True) ): continue real_fields, meta, m2m_fields = self.split_model_def(model, model_defs[model_key(model)]) # Firstly, add the main table and fields yield ("AddModel", {"model": model, "model_def": real_fields}) # Then, add any uniqueness that's around if meta: unique_together = eval(meta.get("unique_together", "[]")) if unique_together: # If it's only a single tuple, make it into the longer one if isinstance(unique_together[0], basestring): unique_together = [unique_together] # For each combination, make an action for it for fields in unique_together: yield ( "AddUnique", {"model": model, "fields": [model._meta.get_field_by_name(x)[0] for x in fields]}, ) # Finally, see if there's some M2M action for name, triple in m2m_fields.items(): field = model._meta.get_field_by_name(name)[0] # But only if it's not through=foo (#120) if (not field.rel.through) or getattr(field.rel.through._meta, "auto_created", False): yield ("AddM2M", {"model": model, "field": field})
def test_dev_setup(appnexus_api_requests, cdn_api): """ Test preparing kanary to development #. drop current database #. run syncdb. Since pytest-django turns off south's syncdb command, we have to import it manually. Only this overwritten command, can sync apps that does not have migrations #. migrate database #. Check report adverts count - should be none, since they're being created in fill_campaigns only #. run fill_campaigns and fill_reports command #. check number of report adverts #. Try to read data from all models. If someone will forget about migrations, that's where we'll hit exceptions #. Check whether model differs from last migration """ from south.management.commands.syncdb import Command as SyncCommand """Run commands as a fresh dev.""" management.call_command('drop_kanary', interactive=False) sync = SyncCommand() sync.execute(verbosity=0, database=settings.DATABASES.keys()[0]) management.call_command('migrate', interactive=False) assert ReportAdvert.objects.count() == 0 management.call_command('fill_campaigns', interactive=False) management.call_command('fill_reports', interactive=False) assert ReportAdvert.objects.count() > 0 app_models = [] for app_mod in get_apps(): app_models.extend(get_models(app_mod)) for model in app_models: print('Querying for: ' + model.__name__) model.objects.first() for app in settings.INSTALLED_APPS: if app.split('.')[0] == 'ui': app = app.split('.')[-1] try: migrations = Migrations(app, force_creation=False, verbose_creation=False) # if there is no migrations directory except NoMigrations: continue # if there are no models except ImproperlyConfigured: continue # if migrations directory is empty if not migrations: continue last_migration = migrations[-1] # Two models saved in dictionary, one based migration, second on models.py migration_defs = dict( (k, v) for k, v in last_migration.migration_class().models.items() if k.split(".")[0] == migrations.app_label()) model_defs = dict((k, v) for k, v in freezer.freeze_apps( [migrations.app_label()]).items() if k.split(".")[0] == migrations.app_label()) change_source = AutoChanges( migrations=migrations, old_defs=migration_defs, old_orm=last_migration.orm(), new_defs=model_defs, ) assert list(change_source.get_changes()) == []
def handle(self, app=None, name="", added_model_list=None, added_field_list=None, freeze_list=None, initial=False, auto=False, stdout=False, added_index_list=None, verbosity=1, empty=False, **options): # Any supposed lists that are None become empty lists added_model_list = added_model_list or [] added_field_list = added_field_list or [] added_index_list = added_index_list or [] freeze_list = freeze_list or [] # --stdout means name = - if stdout: name = "-" # Only allow valid names if re.search('[^_\w]', name) and name != "-": self.error( "Migration names should contain only alphanumeric characters and underscores." ) # Make sure options are compatable if initial and (added_model_list or added_field_list or auto): self.error( "You cannot use --initial and other options together\n" + self.usage_str) if auto and (added_model_list or added_field_list or initial): self.error("You cannot use --auto and other options together\n" + self.usage_str) if not app: self.error("You must provide an app to create a migration for.\n" + self.usage_str) # Get the Migrations for this app (creating the migrations dir if needed) migrations = Migrations(app, force_creation=True, verbose_creation=verbosity > 0) # What actions do we need to do? if auto: # Get the old migration try: last_migration = migrations[-1] except IndexError: self.error( "You cannot use --auto on an app with no migrations. Try --initial." ) # Make sure it has stored models if migrations.app_label() not in getattr( last_migration.migration_class(), "complete_apps", []): self.error( "You cannot use automatic detection, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label()) # Alright, construct two model dicts to run the differ on. old_defs = dict( (k, v) for k, v in last_migration.migration_class().models.items() if k.split(".")[0] == migrations.app_label()) new_defs = dict((k, v) for k, v in freezer.freeze_apps( [migrations.app_label()]).items() if k.split(".")[0] == migrations.app_label()) change_source = changes.AutoChanges( migrations=migrations, old_defs=old_defs, old_orm=last_migration.orm(), new_defs=new_defs, ) elif initial: # Do an initial migration change_source = changes.InitialChanges(migrations) else: # Read the commands manually off of the arguments if (added_model_list or added_field_list or added_index_list): change_source = changes.ManualChanges( migrations, added_model_list, added_field_list, added_index_list, ) elif empty: change_source = None else: print >> sys.stderr, "You have not passed any of --initial, --auto, --empty, --add-model, --add-field or --add-index." sys.exit(1) # if not name, there's an error if not name: if change_source: name = change_source.suggest_name() if not name: self.error("You must provide a name for this migration\n" + self.usage_str) # See what filename is next in line. We assume they use numbers. new_filename = migrations.next_filename(name) # Get the actions, and then insert them into the actions lists forwards_actions = [] backwards_actions = [] if change_source: for action_name, params in change_source.get_changes(): # Run the correct Action class try: action_class = getattr(actions, action_name) except AttributeError: raise ValueError("Invalid action name from source: %s" % action_name) else: action = action_class(**params) action.add_forwards(forwards_actions) action.add_backwards(backwards_actions) print >> sys.stderr, action.console_line() # Nowt happen? That's not good for --auto. if auto and not forwards_actions: self.error("Nothing seems to have changed.") # Work out which apps to freeze apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list) # So, what's in this file, then? file_contents = MIGRATION_TEMPLATE % { "forwards": "\n".join(forwards_actions or ["pass"]), "backwards": "\n".join(backwards_actions or ["pass"]), "frozen_models": freezer.freeze_apps_to_string(apps_to_freeze), "complete_apps": apps_to_freeze and "complete_apps = [%s]" % (", ".join(map(repr, apps_to_freeze))) or "" } # - is a special name which means 'print to stdout' if name == "-": print file_contents # Write the migration file if the name isn't - else: fp = open(os.path.join(migrations.migrations_dir(), new_filename), "w") fp.write(file_contents) fp.close() if empty: print >> sys.stderr, "Created %s. You must now edit this migration and add the code for each direction." % new_filename else: print >> sys.stderr, "Created %s. You can now apply this migration with: ./manage.py migrate %s" % ( new_filename, app)
class Migration(SchemaMigration): def forwards(self, orm): # Changing field 'Backlink.site' db.alter_column( 'activitylog_backlink', 'site_id', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['sites.Site'], null=True)) def backwards(self, orm): # Changing field 'Backlink.site' db.alter_column( 'activitylog_backlink', 'site_id', self.gf('django.db.models.fields.related.ForeignKey')( default=1, to=orm['sites.Site'])) models = { apm_key: freeze_apps(apm_app)[apm_key], 'activitylog.backlink': { 'Meta': { 'object_name': 'Backlink' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hash': ('django.db.models.fields.IntegerField', [], { 'unique': 'True', 'db_index': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'referrer': ('django.db.models.fields.URLField', [], { 'default': "u''", 'max_length': '500', 'blank': 'True' }), 'site': ('django.db.models.fields.related.ForeignKey', [], { 'default': 'None', 'to': "orm['sites.Site']", 'null': 'True', 'blank': 'True' }), 'status': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }), 'url': ('django.db.models.fields.URLField', [], { 'default': "u''", 'max_length': '500', 'blank': 'True' }), 'visits': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }) }, 'activitylog.ip': { 'Meta': { 'object_name': 'IP' }, 'address': ('django.db.models.fields.IPAddressField', [], { 'null': 'True', 'default': 'None', 'max_length': '15', 'blank': 'True', 'unique': 'True', 'db_index': 'True' }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hostname': ('django.db.models.fields.CharField', [], { 'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'number': ('django.db.models.fields.BigIntegerField', [], { 'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True' }), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileIP']", 'symmetrical': 'False' }) }, 'activitylog.profileip': { 'Meta': { 'unique_together': "((u'ip', u'user'), (u'ip', u'profile'))", 'object_name': 'ProfileIP' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'ip': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.IP']" }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }), 'user': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['auth.User']" }) }, 'activitylog.profileuseragent': { 'Meta': { 'unique_together': "((u'agent', u'user'), (u'agent', u'profile'))", 'object_name': 'ProfileUserAgent' }, 'agent': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.UserAgent']" }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }), 'user': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['auth.User']" }) }, 'activitylog.useragent': { 'Meta': { 'object_name': 'UserAgent' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hash': ('django.db.models.fields.IntegerField', [], { 'unique': 'True', 'db_index': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'name': ('django.db.models.fields.TextField', [], { 'default': "u''", 'blank': 'True' }), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileUserAgent']", 'symmetrical': 'False' }) }, 'auth.group': { 'Meta': { 'object_name': 'Group' }, 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '80' }), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }) }, 'auth.permission': { 'Meta': { 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission' }, 'codename': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'content_type': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['contenttypes.ContentType']" }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) }, 'auth.user': { 'Meta': { 'object_name': 'User' }, 'date_joined': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'email': ('django.db.models.fields.EmailField', [], { 'max_length': '75', 'blank': 'True' }), 'first_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'groups': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'is_active': ('django.db.models.fields.BooleanField', [], { 'default': 'True' }), 'is_staff': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'is_superuser': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'last_login': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'last_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'password': ('django.db.models.fields.CharField', [], { 'max_length': '128' }), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }), 'username': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '30' }) }, 'contenttypes.contenttype': { 'Meta': { 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'" }, 'app_label': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'model': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '100' }) }, 'sites.site': { 'Meta': { 'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'" }, 'domain': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) } } complete_apps = ['activitylog']
def test_south_migrations(self): from django.core.exceptions import ImproperlyConfigured from django.conf import settings from django.db import models from south.migration import Migrations, migrate_app from south.models import MigrationHistory from south.exceptions import NoMigrations from south.creator import changes, actions, freezer from south.management.commands.datamigration import Command as DataCommand apps = [ app for app in settings.INSTALLED_APPS if app.startswith('wagtail.') ] failing_apps = [] for app_name in apps: app = app_name.split('.')[-1] try: models.get_app(app) except ImproperlyConfigured: # This module fails to load, probably because it has no # models.py. Ignore it and move on continue try: migrations = Migrations(app, force_creation=False, verbose_creation=False) last_migration = migrations[-1] except (NoMigrations, IndexError): # No migrations for this app, probably doesnt have models continue if migrations.app_label() not in getattr( last_migration.migration_class(), "complete_apps", []): self.fail( "Automatic migrations checking failed, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label()) # Alright, construct two model dicts to run the differ on. old_defs = dict( (k, v) for k, v in last_migration.migration_class().models.items() if k.split(".")[0] == migrations.app_label()) new_defs = dict((k, v) for k, v in freezer.freeze_apps( [migrations.app_label()]).items() if k.split(".")[0] == migrations.app_label()) change_source = changes.AutoChanges( migrations=migrations, old_defs=old_defs, old_orm=last_migration.orm(), new_defs=new_defs, ) name = 'test' # Get the actions, and then insert them into the actions lists if list(change_source.get_changes()): failing_apps.append(app_name) if failing_apps: self.fail( 'Model changes with no South migration detected in apps: %s' % (', '.join(failing_apps)))
class Migration(SchemaMigration): def forwards(self, orm): # Removing unique constraint on 'ProfileUserAgent', fields ['user', 'agent'] db.delete_unique('activitylog_profileuseragent', ['user_id', 'agent_id']) # Removing unique constraint on 'ProfileIP', fields ['ip', 'user'] db.delete_unique('activitylog_profileip', ['ip_id', 'user_id']) # Deleting field 'ProfileIP.user' db.delete_column('activitylog_profileip', 'user_id') # Deleting field 'ProfileUserAgent.user' db.delete_column('activitylog_profileuseragent', 'user_id') def backwards(self, orm): # User chose to not deal with backwards NULL issues for 'ProfileIP.user' raise RuntimeError( "Cannot reverse this migration. 'ProfileIP.user' and its values cannot be restored." ) # Adding unique constraint on 'ProfileIP', fields ['ip', 'user'] db.create_unique('activitylog_profileip', ['ip_id', 'user_id']) # User chose to not deal with backwards NULL issues for 'ProfileUserAgent.user' raise RuntimeError( "Cannot reverse this migration. 'ProfileUserAgent.user' and its values cannot be restored." ) # Adding unique constraint on 'ProfileUserAgent', fields ['user', 'agent'] db.create_unique('activitylog_profileuseragent', ['user_id', 'agent_id']) models = { apm_key: freeze_apps(apm_app)[apm_key], 'activitylog.backlink': { 'Meta': { 'object_name': 'Backlink' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hash': ('django.db.models.fields.IntegerField', [], { 'unique': 'True', 'db_index': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'referrer': ('django.db.models.fields.URLField', [], { 'default': "u''", 'max_length': '500', 'blank': 'True' }), 'site': ('django.db.models.fields.related.ForeignKey', [], { 'default': 'None', 'to': "orm['sites.Site']", 'null': 'True', 'blank': 'True' }), 'status': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }), 'url': ('django.db.models.fields.URLField', [], { 'default': "u''", 'max_length': '500', 'blank': 'True' }), 'visits': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }) }, 'activitylog.ip': { 'Meta': { 'object_name': 'IP' }, 'address': ('django.db.models.fields.IPAddressField', [], { 'null': 'True', 'default': 'None', 'max_length': '15', 'blank': 'True', 'unique': 'True', 'db_index': 'True' }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hostname': ('django.db.models.fields.CharField', [], { 'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'number': ('django.db.models.fields.BigIntegerField', [], { 'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True' }), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileIP']", 'symmetrical': 'False' }) }, 'activitylog.profileip': { 'Meta': { 'unique_together': "((u'ip', u'profile'),)", 'object_name': 'ProfileIP' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'ip': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.IP']" }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }) }, 'activitylog.profileuseragent': { 'Meta': { 'unique_together': "((u'agent', u'profile'),)", 'object_name': 'ProfileUserAgent' }, 'agent': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.UserAgent']" }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }) }, 'activitylog.useragent': { 'Meta': { 'object_name': 'UserAgent' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hash': ('django.db.models.fields.IntegerField', [], { 'unique': 'True', 'db_index': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'name': ('django.db.models.fields.TextField', [], { 'default': "u''", 'blank': 'True' }), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileUserAgent']", 'symmetrical': 'False' }) }, 'auth.group': { 'Meta': { 'object_name': 'Group' }, 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '80' }), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }) }, 'auth.permission': { 'Meta': { 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission' }, 'codename': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'content_type': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['contenttypes.ContentType']" }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) }, 'auth.user': { 'Meta': { 'object_name': 'User' }, 'date_joined': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'email': ('django.db.models.fields.EmailField', [], { 'max_length': '75', 'blank': 'True' }), 'first_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'groups': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'is_active': ('django.db.models.fields.BooleanField', [], { 'default': 'True' }), 'is_staff': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'is_superuser': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'last_login': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'last_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'password': ('django.db.models.fields.CharField', [], { 'max_length': '128' }), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }), 'username': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '30' }) }, 'contenttypes.contenttype': { 'Meta': { 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'" }, 'app_label': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'model': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '100' }) }, 'sites.site': { 'Meta': { 'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'" }, 'domain': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) } } complete_apps = ['activitylog']
def handle(self, app=None, name="", added_model_list=None, added_field_list=None, freeze_list=None, initial=False, auto=False, stdout=False, added_index_list=None, verbosity=1, **options): # Any supposed lists that are None become empty lists added_model_list = added_model_list or [] added_field_list = added_field_list or [] added_index_list = added_index_list or [] freeze_list = freeze_list or [] # --stdout means name = - if stdout: name = "-" # Make sure options are compatable if initial and (added_model_list or added_field_list or auto): self.error("You cannot use --initial and other options together\n" + self.usage_str) if auto and (added_model_list or added_field_list or initial): self.error("You cannot use --auto and other options together\n" + self.usage_str) # specify the default name 'initial' if a name wasn't specified and we're # doing a migration for an entire app if not name and initial: name = 'initial' # if not name, there's an error if not name: self.error("You must provide a name for this migration\n" + self.usage_str) if not app: self.error("You must provide an app to create a migration for.\n" + self.usage_str) # Get the Migrations for this app (creating the migrations dir if needed) migrations = Migrations(app, force_creation=True, verbose_creation=verbosity > 0) # See what filename is next in line. We assume they use numbers. new_filename = migrations.next_filename(name) # What actions do we need to do? if auto: # Get the old migration try: last_migration = migrations[-1] except IndexError: self.error("You cannot use --auto on an app with no migrations. Try --initial.") # Make sure it has stored models if migrations.app_label() not in getattr(last_migration.migration_class(), "complete_apps", []): self.error("You cannot use automatic detection, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label()) # Alright, construct two model dicts to run the differ on. old_defs = dict( (k, v) for k, v in last_migration.migration_class().models.items() if k.split(".")[0] == migrations.app_label() ) new_defs = dict( (k, v) for k, v in freezer.freeze_apps([migrations.app_label()]).items() if k.split(".")[0] == migrations.app_label() ) change_source = changes.AutoChanges( migrations = migrations, old_defs = old_defs, old_orm = last_migration.orm(), new_defs = new_defs, ) elif initial: # Do an initial migration change_source = changes.InitialChanges(migrations) else: # Read the commands manually off of the arguments if (added_model_list or added_field_list or added_index_list): change_source = changes.ManualChanges( migrations, added_model_list, added_field_list, added_index_list, ) else: print >>sys.stderr, "You have not passed any of --initial, --auto, --add-model, --add-field or --add-index." sys.exit(1) # Get the actions, and then insert them into the actions lists forwards_actions = [] backwards_actions = [] for action_name, params in change_source.get_changes(): # Run the correct Action class try: action_class = getattr(actions, action_name) except AttributeError: raise ValueError("Invalid action name from source: %s" % action_name) else: action = action_class(**params) action.add_forwards(forwards_actions) action.add_backwards(backwards_actions) print >>sys.stderr, action.console_line() # Nowt happen? That's not good for --auto. if auto and not forwards_actions: self.error("Nothing seems to have changed.") # Work out which apps to freeze apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list) # So, what's in this file, then? file_contents = MIGRATION_TEMPLATE % { "forwards": "\n".join(forwards_actions), "backwards": "\n".join(backwards_actions), "frozen_models": freezer.freeze_apps_to_string(apps_to_freeze), "complete_apps": apps_to_freeze and "complete_apps = [%s]" % (", ".join(map(repr, apps_to_freeze))) or "" } # - is a special name which means 'print to stdout' if name == "-": print file_contents # Write the migration file if the name isn't - else: fp = open(os.path.join(migrations.migrations_dir(), new_filename), "w") fp.write(file_contents) fp.close() print >>sys.stderr, "Created %s. You can now apply this migration with: ./manage.py migrate %s" % (new_filename, app)
class Migration(SchemaMigration): depends_on = depends_on def forwards(self, orm): # Adding model 'BadgeGroup' db.create_table('badges_badgegroup', ( ('name', self.gf('django.db.models.fields.CharField')(max_length=75)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('key', self.gf('django.db.models.fields.CharField')( max_length=75, primary_key=True)), ('description', self.gf('django.db.models.fields.TextField')( default=None, null=True, blank=True)), ('callback', self.gf('django.db.models.fields.CharField')( default=u'', max_length=100, blank=True)), ('multiple_allowed', self.gf('django.db.models.fields.BooleanField')(default=False)), )) db.send_create_signal('badges', ['BadgeGroup']) # Adding model 'BadgeIcon' db.create_table('badges_badgeicon', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('title', self.gf('django.db.models.fields.CharField')( unique=True, max_length=100, db_index=True)), ('slug', self.gf('django.db.models.fields.SlugField')( unique=True, max_length=50)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('height', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('width', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('image', self.gf('django.db.models.fields.files.ImageField')( max_length=200)), )) db.send_create_signal('badges', ['BadgeIcon']) # Adding model 'BadgeType' db.create_table('badges_badgetype', ( ('name', self.gf('django.db.models.fields.CharField')(max_length=75)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('key', self.gf('django.db.models.fields.CharField')( max_length=75, primary_key=True)), ('description', self.gf('django.db.models.fields.TextField')( default=None, null=True, blank=True)), ('callback', self.gf('django.db.models.fields.CharField')( default=u'', max_length=100, blank=True)), ('group', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['badges.BadgeGroup'])), ('icon', self.gf('django.db.models.fields.related.ForeignKey')( default=None, to=orm['badges.BadgeIcon'], null=True, blank=True)), )) db.send_create_signal('badges', ['BadgeType']) # Adding model 'Badge' db.create_table('badges_badge', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('created_by', self.gf('django.db.models.fields.related.ForeignKey')( related_name=u'+', on_delete=models.SET_NULL, default=None, to=orm[EDITOR_TRACKABLE_MODEL], blank=True, null=True)), ('modified_by', self.gf('django.db.models.fields.related.ForeignKey')( related_name=u'+', on_delete=models.SET_NULL, default=None, to=orm[EDITOR_TRACKABLE_MODEL], blank=True, null=True)), ('type', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['badges.BadgeType'])), ('owner_ct', self.gf('django.db.models.fields.related.ForeignKey')( related_name=u'badges_badge_owned_received', to=orm['contenttypes.ContentType'])), ('owner_oid', self.gf('django.db.models.fields.IntegerField')(db_index=True)), ('subject_ct', self.gf('django.db.models.fields.related.ForeignKey')( default=None, related_name=u'badges_badge_badges_given', null=True, blank=True, to=orm['contenttypes.ContentType'])), ('subject_oid', self.gf('django.db.models.fields.IntegerField')( default=None, null=True, db_index=True, blank=True)), ('comment', self.gf('django.db.models.fields.TextField')( default=None, null=True, blank=True)), )) db.send_create_signal('badges', ['Badge']) def backwards(self, orm): # Deleting model 'BadgeGroup' db.delete_table('badges_badgegroup') # Deleting model 'BadgeIcon' db.delete_table('badges_badgeicon') # Deleting model 'BadgeType' db.delete_table('badges_badgetype') # Deleting model 'Badge' db.delete_table('badges_badge') models = { apm_key: freeze_apps(apm_app)[apm_key], 'auth.group': { 'Meta': { 'object_name': 'Group' }, 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '80' }), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }) }, 'auth.permission': { 'Meta': { 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission' }, 'codename': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'content_type': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['contenttypes.ContentType']" }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) }, 'auth.user': { 'Meta': { 'object_name': 'User' }, 'date_joined': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'email': ('django.db.models.fields.EmailField', [], { 'max_length': '75', 'blank': 'True' }), 'first_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'groups': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'is_active': ('django.db.models.fields.BooleanField', [], { 'default': 'True' }), 'is_staff': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'is_superuser': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'last_login': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'last_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'password': ('django.db.models.fields.CharField', [], { 'max_length': '128' }), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }), 'username': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '30' }) }, 'badges.badge': { 'Meta': { 'object_name': 'Badge' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'comment': ('django.db.models.fields.TextField', [], { 'default': 'None', 'null': 'True', 'blank': 'True' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'created_by': ('django.db.models.fields.related.ForeignKey', [], { 'related_name': "u'+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['{EDITOR_TRACKABLE_MODEL}']".format( EDITOR_TRACKABLE_MODEL=EDITOR_TRACKABLE_MODEL), 'blank': 'True', 'null': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'modified_by': ('django.db.models.fields.related.ForeignKey', [], { 'related_name': "u'+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['{EDITOR_TRACKABLE_MODEL}']".format( EDITOR_TRACKABLE_MODEL=EDITOR_TRACKABLE_MODEL), 'blank': 'True', 'null': 'True' }), 'owner_ct': ('django.db.models.fields.related.ForeignKey', [], { 'related_name': "u'badges_badge_owned_received'", 'to': "orm['contenttypes.ContentType']" }), 'owner_oid': ('django.db.models.fields.IntegerField', [], { 'db_index': 'True' }), 'subject_ct': ('django.db.models.fields.related.ForeignKey', [], { 'default': 'None', 'related_name': "u'badges_badge_badges_given'", 'null': 'True', 'blank': 'True', 'to': "orm['contenttypes.ContentType']" }), 'subject_oid': ('django.db.models.fields.IntegerField', [], { 'default': 'None', 'null': 'True', 'db_index': 'True', 'blank': 'True' }), 'type': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['badges.BadgeType']" }) }, 'badges.badgegroup': { 'Meta': { 'object_name': 'BadgeGroup' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'callback': ('django.db.models.fields.CharField', [], { 'default': "u''", 'max_length': '100', 'blank': 'True' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'description': ('django.db.models.fields.TextField', [], { 'default': 'None', 'null': 'True', 'blank': 'True' }), 'key': ('django.db.models.fields.CharField', [], { 'max_length': '75', 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'multiple_allowed': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '75' }) }, 'badges.badgeicon': { 'Meta': { 'object_name': 'BadgeIcon' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'height': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'image': ('django.db.models.fields.files.ImageField', [], { 'max_length': '200' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'slug': ('django.db.models.fields.SlugField', [], { 'unique': 'True', 'max_length': '50' }), 'title': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '100', 'db_index': 'True' }), 'width': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }) }, 'badges.badgetype': { 'Meta': { 'object_name': 'BadgeType' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'callback': ('django.db.models.fields.CharField', [], { 'default': "u''", 'max_length': '100', 'blank': 'True' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'description': ('django.db.models.fields.TextField', [], { 'default': 'None', 'null': 'True', 'blank': 'True' }), 'group': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['badges.BadgeGroup']" }), 'icon': ('django.db.models.fields.related.ForeignKey', [], { 'default': 'None', 'to': "orm['badges.BadgeIcon']", 'null': 'True', 'blank': 'True' }), 'key': ('django.db.models.fields.CharField', [], { 'max_length': '75', 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '75' }) }, 'contenttypes.contenttype': { 'Meta': { 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'" }, 'app_label': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'model': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '100' }) } } complete_apps = ['badges']
def handle(self, app=None, name="", added_model_list=None, added_field_list=None, freeze_list=None, initial=False, auto=False, stdout=False, added_index_list=None, verbosity=1, empty=False, update=False, **options): # Any supposed lists that are None become empty lists added_model_list = added_model_list or [] added_field_list = added_field_list or [] added_index_list = added_index_list or [] freeze_list = freeze_list or [] # --stdout means name = - if stdout: name = "-" # Only allow valid names if re.search('[^_\w]', name) and name != "-": self.error( "Migration names should contain only alphanumeric characters and underscores.") # Make sure options are compatable if initial and (added_model_list or added_field_list or auto): self.error( "You cannot use --initial and other options together\n" + self.usage_str) if auto and (added_model_list or added_field_list or initial): self.error( "You cannot use --auto and other options together\n" + self.usage_str) if not app: self.error( "You must provide an app to create a migration for.\n" + self.usage_str) # See if the app exists app = app.split(".")[-1] try: app_module = models.get_app(app) except ImproperlyConfigured: print("There is no enabled application matching '%s'." % app) return # Get the Migrations for this app (creating the migrations dir if needed) migrations = Migrations(app, force_creation=True, verbose_creation=int(verbosity) > 0) # What actions do we need to do? if auto: # Get the old migration try: last_migration = migrations[-2 if update else -1] except IndexError: self.error( "You cannot use --auto on an app with no migrations. Try --initial.") # Make sure it has stored models if migrations.app_label() not in getattr( last_migration.migration_class(), "complete_apps", []): self.error( "You cannot use automatic detection, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label()) # Alright, construct two model dicts to run the differ on. old_defs = dict( (k, v) for k, v in last_migration.migration_class().models.items() if k.split(".")[0] == migrations.app_label() ) new_defs = dict( (k, v) for k, v in freezer.freeze_apps([migrations.app_label()]).items() if k.split(".")[0] == migrations.app_label() ) change_source = changes.AutoChanges( migrations=migrations, old_defs=old_defs, old_orm=last_migration.orm(), new_defs=new_defs, ) elif initial: # Do an initial migration change_source = changes.InitialChanges(migrations) else: # Read the commands manually off of the arguments if (added_model_list or added_field_list or added_index_list): change_source = changes.ManualChanges( migrations, added_model_list, added_field_list, added_index_list, ) elif empty: change_source = None else: print( "You have not passed any of --initial, --auto, --empty, --add-model, --add-field or --add-index.", file=sys.stderr) sys.exit(1) # Validate this so we can access the last migration without worrying if update and not migrations: self.error("You cannot use --update on an app with no migrations.") # if not name, there's an error if not name: if change_source: name = change_source.suggest_name() if update: name = re.sub(r'^\d{4}_', '', migrations[-1].name()) if not name: self.error( "You must provide a name for this migration\n" + self.usage_str) # Get the actions, and then insert them into the actions lists forwards_actions = [] backwards_actions = [] if change_source: for action_name, params in change_source.get_changes(): # Run the correct Action class try: action_class = getattr(actions, action_name) except AttributeError: raise ValueError( "Invalid action name from source: %s" % action_name) else: action = action_class(**params) action.add_forwards(forwards_actions) action.add_backwards(backwards_actions) print(action.console_line(), file=sys.stderr) # Nowt happen? That's not good for --auto. if auto and not forwards_actions: self.error("Nothing seems to have changed.") # Work out which apps to freeze apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list) # So, what's in this file, then? file_contents = MIGRATION_TEMPLATE % { "forwards": "\n".join(forwards_actions or [" pass"]), "backwards": "\n".join(backwards_actions or [" pass"]), "frozen_models": freezer.freeze_apps_to_string(apps_to_freeze), "complete_apps": apps_to_freeze and "complete_apps = [%s]" % ( ", ".join(map(repr, apps_to_freeze))) or "" } # Custom Bluebottle # We find and replace the base apps with our mapped models for model in MODEL_MAP: model_map = MODEL_MAP[model] mapping = { 'u"orm[\'{0}\']"'.format(model_map[ 'model']): '"orm[\'{0}\']".format(MODEL_MAP[\'{1}\'][\'model\'])'.format( '{0}', model), 'u\'{0}\''.format( model_map['table']): 'MODEL_MAP[\'{0}\'][\'table\']'.format( model), 'u\'{0}\''.format(model_map[ 'model_lower']): 'MODEL_MAP[\'{0}\'][\'model_lower\']'.format( model), 'u\'{0}\''.format( model_map['app']): 'MODEL_MAP[\'{0}\'][\'app\']'.format( model), '[\'{0}\']'.format( model_map['app']): '[MODEL_MAP[\'{0}\'][\'app\']]'.format( model), 'to=orm[\'{0}\']'.format(model_map[ 'model']): 'to=orm[MODEL_MAP[\'{0}\'][\'model\']]'.format( model), '\'object_name\': \'{0}\''.format(model_map[ 'class']): '\'object_name\': MODEL_MAP[\'{0}\'][\'class\']'.format( model) } file_contents = reduce(lambda x, y: x.replace(y, mapping[y]), mapping, file_contents) # End Custom Bluebottle # Deal with update mode as late as possible, avoid a rollback as long # as something else can go wrong. if update: last_migration = migrations[-1] if MigrationHistory.objects.filter(applied__isnull=False, app_name=app, migration=last_migration.name()): print( "Migration to be updated, %s, is already applied, rolling it back now..." % last_migration.name(), file=sys.stderr) migrate_app(migrations, 'current-1', verbosity=verbosity) for ext in ('py', 'pyc'): old_filename = "%s.%s" % ( os.path.join(migrations.migrations_dir(), last_migration.filename), ext) if os.path.isfile(old_filename): os.unlink(old_filename) migrations.remove(last_migration) # See what filename is next in line. We assume they use numbers. new_filename = migrations.next_filename(name) # - is a special name which means 'print to stdout' if name == "-": print(file_contents) # Write the migration file if the name isn't - else: fp = open(os.path.join(migrations.migrations_dir(), new_filename), "w") fp.write(file_contents) fp.close() verb = 'Updated' if update else 'Created' if empty: print( "%s %s. You must now edit this migration and add the code for each direction." % ( verb, new_filename), file=sys.stderr) else: print( "%s %s. You can now apply this migration with: ./manage.py migrate %s" % ( verb, new_filename, app), file=sys.stderr)
class Migration(SchemaMigration): depends_on = depends_on def forwards(self, orm): # Adding model 'TagStem' db.create_table('tags_tagstem', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('name', self.gf('django.db.models.fields.CharField')(max_length=75)), ('language', self.gf('django.db.models.fields.PositiveIntegerField')( default=39)), ('tag_count', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), )) db.send_create_signal('tags', ['TagStem']) # Adding model 'Tag' db.create_table('tags_tag', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('name', self.gf('django.db.models.fields.CharField')(max_length=75)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('language', self.gf('django.db.models.fields.PositiveIntegerField')( default=39)), ('stem', self.gf('django.db.models.fields.related.ForeignKey')( blank=True, related_name=u'related_tags', null=True, to=orm['tags.TagStem'])), ('author', self.gf('django.db.models.fields.related.ForeignKey')( to=orm[TAG_AUTHOR_MODEL])), ('official', self.gf('django.db.models.fields.BooleanField')(default=False)), ('content_type', self.gf('django.db.models.fields.related.ForeignKey')( related_name=u'tags_tag_tags', to=orm['contenttypes.ContentType'])), ('object_id', self.gf('django.db.models.fields.IntegerField')(db_index=True)), )) db.send_create_signal('tags', ['Tag']) def backwards(self, orm): # Deleting model 'TagStem' db.delete_table('tags_tagstem') # Deleting model 'Tag' db.delete_table('tags_tag') models = { apm_key: freeze_apps(apm_app)[apm_key], 'auth.group': { 'Meta': { 'object_name': 'Group' }, 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '80' }), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }) }, 'auth.permission': { 'Meta': { 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission' }, 'codename': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'content_type': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['contenttypes.ContentType']" }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) }, 'auth.user': { 'Meta': { 'object_name': 'User' }, 'date_joined': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'email': ('django.db.models.fields.EmailField', [], { 'max_length': '75', 'blank': 'True' }), 'first_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'groups': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'is_active': ('django.db.models.fields.BooleanField', [], { 'default': 'True' }), 'is_staff': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'is_superuser': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'last_login': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'last_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'password': ('django.db.models.fields.CharField', [], { 'max_length': '128' }), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }), 'username': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '30' }) }, 'contenttypes.contenttype': { 'Meta': { 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'" }, 'app_label': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'model': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '100' }) }, 'tags.tag': { 'Meta': { 'object_name': 'Tag' }, 'author': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{TAG_AUTHOR_MODEL}']".format( TAG_AUTHOR_MODEL=TAG_AUTHOR_MODEL) }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'content_type': ('django.db.models.fields.related.ForeignKey', [], { 'related_name': "u'tags_tag_tags'", 'to': "orm['contenttypes.ContentType']" }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'language': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '39' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '75' }), 'object_id': ('django.db.models.fields.IntegerField', [], { 'db_index': 'True' }), 'official': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'stem': ('django.db.models.fields.related.ForeignKey', [], { 'blank': 'True', 'related_name': "u'related_tags'", 'null': 'True', 'to': "orm['tags.TagStem']" }) }, 'tags.tagstem': { 'Meta': { 'object_name': 'TagStem' }, 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'language': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '39' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '75' }), 'tag_count': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }) } } complete_apps = ['tags']
class Migration(SchemaMigration): depends_on = depends_on def forwards(self, orm): # Adding model 'TotalScore' db.create_table('score_totalscore', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('value', self.gf('django.db.models.fields.IntegerField')(default=0, db_index=True)), ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(related_name=u'score_totalscore_scores', to=orm['contenttypes.ContentType'])), ('object_id', self.gf('django.db.models.fields.IntegerField')(db_index=True)), )) db.send_create_signal('score', ['TotalScore']) # Adding model 'Vote' db.create_table('score_vote', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), ('total_score', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['score.TotalScore'])), ('voter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm[SCORE_VOTER_MODEL])), ('value', self.gf('django.db.models.fields.IntegerField')(default=1, db_index=True)), ('reason', self.gf('django.db.models.fields.TextField')(default=u'', blank=True)), )) db.send_create_signal('score', ['Vote']) # Adding unique constraint on 'Vote', fields ['total_score', 'voter'] db.create_unique('score_vote', ['total_score_id', 'voter_id']) def backwards(self, orm): # Removing unique constraint on 'Vote', fields ['total_score', 'voter'] db.delete_unique('score_vote', ['total_score_id', 'voter_id']) # Deleting model 'TotalScore' db.delete_table('score_totalscore') # Deleting model 'Vote' db.delete_table('score_vote') models = { apm_key: freeze_apps(apm_app)[apm_key], 'auth.group': { 'Meta': {'object_name': 'Group'}, 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) }, 'auth.permission': { 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, 'auth.user': { 'Meta': {'object_name': 'User'}, 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) }, 'contenttypes.contenttype': { 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) }, 'score.totalscore': { 'Meta': {'object_name': 'TotalScore'}, 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'score_totalscore_scores'", 'to': "orm['contenttypes.ContentType']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}), 'value': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}) }, 'score.vote': { 'Meta': {'unique_together': "([u'total_score', u'voter'],)", 'object_name': 'Vote'}, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'reason': ('django.db.models.fields.TextField', [], {'default': "u''", 'blank': 'True'}), 'total_score': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['score.TotalScore']"}), 'value': ('django.db.models.fields.IntegerField', [], {'default': '1', 'db_index': 'True'}), 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['{SCORE_VOTER_MODEL}']".format(SCORE_VOTER_MODEL=SCORE_VOTER_MODEL)}) } } complete_apps = ['score']
class Migration(SchemaMigration): def forwards(self, orm): # Removing unique constraint on 'Backlink', fields ['url', 'referrer', 'site'] db.delete_unique('activitylog_backlink', ['url', 'referrer', 'site_id']) # Removing unique constraint on 'UserAgent', fields ['name'] db.delete_unique('activitylog_useragent', ['name']) # Adding field 'UserAgent.hash' db.add_column('activitylog_useragent', 'hash', self.gf('django.db.models.fields.IntegerField')( null=True, unique=True, db_index=True), keep_default=False) if not db.dry_run: for ua in orm.UserAgent.objects.all(): ua.hash = self.hash_for_name(ua.name) ua.save() db.alter_column( 'activitylog_useragent', 'hash', self.gf('django.db.models.fields.IntegerField')(unique=True, db_index=True)) db.alter_column( 'activitylog_useragent', 'hash', self.gf('django.db.models.fields.IntegerField')(unique=True, db_index=True)) # Changing field 'UserAgent.name' db.alter_column('activitylog_useragent', 'name', self.gf('django.db.models.fields.TextField')()) # Adding field 'Backlink.hash' db.add_column('activitylog_backlink', 'hash', self.gf('django.db.models.fields.IntegerField')( default=None, null=True, unique=True, db_index=True), keep_default=False) if not db.dry_run: for ua in orm.Backlink.objects.all(): ua.hash = self.hash_for_triple(ua.site, ua.url, ua.referrer) ua.save() db.alter_column( 'activitylog_backlink', 'hash', self.gf('django.db.models.fields.IntegerField')(unique=True, db_index=True)) # Changing field 'Backlink.url' db.alter_column( 'activitylog_backlink', 'url', self.gf('django.db.models.fields.URLField')(max_length=500)) # Changing field 'Backlink.referrer' db.alter_column( 'activitylog_backlink', 'referrer', self.gf('django.db.models.fields.URLField')(max_length=500)) def backwards(self, orm): # Deleting field 'UserAgent.hash' db.delete_column('activitylog_useragent', 'hash') # Changing field 'UserAgent.name' db.alter_column( 'activitylog_useragent', 'name', self.gf('django.db.models.fields.CharField')(max_length=255, unique=True)) # Adding unique constraint on 'UserAgent', fields ['name'] db.create_unique('activitylog_useragent', ['name']) # Deleting field 'Backlink.hash' db.delete_column('activitylog_backlink', 'hash') # Changing field 'Backlink.url' db.alter_column( 'activitylog_backlink', 'url', self.gf('django.db.models.fields.URLField')(max_length=100)) # Changing field 'Backlink.referrer' db.alter_column( 'activitylog_backlink', 'referrer', self.gf('django.db.models.fields.URLField')(max_length=100)) # Adding unique constraint on 'Backlink', fields ['url', 'referrer', 'site'] db.create_unique('activitylog_backlink', ['url', 'referrer', 'site_id']) @classmethod def hash_for_name(cls, name): return zlib.adler32(name) @classmethod def hash_for_triple(cls, site, url, referrer): return zlib.adler32(u'\n'.join( (str(site.id), url, referrer)).encode('utf8')) models = { apm_key: freeze_apps(apm_app)[apm_key], 'activitylog.backlink': { 'Meta': { 'object_name': 'Backlink' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hash': ('django.db.models.fields.IntegerField', [], { 'unique': 'True', 'db_index': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'referrer': ('django.db.models.fields.URLField', [], { 'max_length': '500' }), 'site': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['sites.Site']" }), 'status': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }), 'url': ('django.db.models.fields.URLField', [], { 'max_length': '500' }), 'visits': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }) }, 'activitylog.ip': { 'Meta': { 'object_name': 'IP' }, 'address': ('django.db.models.fields.IPAddressField', [], { 'null': 'True', 'default': 'None', 'max_length': '15', 'blank': 'True', 'unique': 'True', 'db_index': 'True' }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hostname': ('django.db.models.fields.CharField', [], { 'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'number': ('django.db.models.fields.BigIntegerField', [], { 'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True' }), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileIP']", 'symmetrical': 'False' }) }, 'activitylog.profileip': { 'Meta': { 'unique_together': "((u'ip', u'user'), (u'ip', u'profile'))", 'object_name': 'ProfileIP' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'ip': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.IP']" }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }), 'user': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['auth.User']" }) }, 'activitylog.profileuseragent': { 'Meta': { 'unique_together': "((u'agent', u'user'), (u'agent', u'profile'))", 'object_name': 'ProfileUserAgent' }, 'agent': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.UserAgent']" }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }), 'user': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['auth.User']" }) }, 'activitylog.useragent': { 'Meta': { 'object_name': 'UserAgent' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hash': ('django.db.models.fields.IntegerField', [], { 'unique': 'True', 'db_index': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'name': ('django.db.models.fields.TextField', [], {}), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileUserAgent']", 'symmetrical': 'False' }) }, 'auth.group': { 'Meta': { 'object_name': 'Group' }, 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '80' }), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }) }, 'auth.permission': { 'Meta': { 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission' }, 'codename': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'content_type': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['contenttypes.ContentType']" }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) }, 'auth.user': { 'Meta': { 'object_name': 'User' }, 'date_joined': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'email': ('django.db.models.fields.EmailField', [], { 'max_length': '75', 'blank': 'True' }), 'first_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'groups': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'is_active': ('django.db.models.fields.BooleanField', [], { 'default': 'True' }), 'is_staff': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'is_superuser': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'last_login': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'last_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'password': ('django.db.models.fields.CharField', [], { 'max_length': '128' }), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }), 'username': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '30' }) }, 'contenttypes.contenttype': { 'Meta': { 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'" }, 'app_label': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'model': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '100' }) }, 'sites.site': { 'Meta': { 'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'" }, 'domain': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) } } complete_apps = ['activitylog']
class Migration(SchemaMigration): depends_on = depends_on def forwards(self, orm): # Adding model 'UserAgent' db.create_table('activitylog_useragent', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('name', self.gf('django.db.models.fields.CharField')( unique=True, max_length=255, db_index=True)), )) db.send_create_signal('activitylog', ['UserAgent']) # Adding model 'IP' db.create_table('activitylog_ip', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('address', self.gf('django.db.models.fields.IPAddressField')( null=True, default=None, max_length=15, blank=True, unique=True, db_index=True)), ('number', self.gf('django.db.models.fields.BigIntegerField')( default=None, unique=True, null=True, blank=True)), ('hostname', self.gf('django.db.models.fields.CharField')( default=None, max_length=255, null=True, blank=True)), )) db.send_create_signal('activitylog', ['IP']) # Adding model 'Backlink' db.create_table('activitylog_backlink', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('site', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['sites.Site'])), ('url', self.gf('django.db.models.fields.URLField')(max_length=100)), ('referrer', self.gf('django.db.models.fields.URLField')(max_length=100)), ('visits', self.gf('django.db.models.fields.PositiveIntegerField')( default=1)), ('status', self.gf('django.db.models.fields.PositiveIntegerField')( default=1)), )) db.send_create_signal('activitylog', ['Backlink']) # Adding unique constraint on 'Backlink', fields ['site', 'url', 'referrer'] db.create_unique('activitylog_backlink', ['site_id', 'url', 'referrer']) # Adding model 'ProfileIP' db.create_table('activitylog_profileip', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('user', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['auth.User'])), ('profile', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['{ACTIVITYLOG_PROFILE_MODEL}'.format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL)])), ('ip', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['activitylog.IP'])), )) db.send_create_signal('activitylog', ['ProfileIP']) # Adding unique constraint on 'ProfileIP', fields ['ip', 'user'] db.create_unique('activitylog_profileip', ['ip_id', 'user_id']) # Adding unique constraint on 'ProfileIP', fields ['ip', 'profile'] db.create_unique('activitylog_profileip', ['ip_id', 'profile_id']) # Adding model 'ProfileUserAgent' db.create_table('activitylog_profileuseragent', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('created', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('modified', self.gf('django.db.models.fields.DateTimeField')( default=datetime.datetime.now)), ('cache_version', self.gf('django.db.models.fields.PositiveIntegerField')( default=0)), ('user', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['auth.User'])), ('profile', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['{ACTIVITYLOG_PROFILE_MODEL}'.format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL)])), ('agent', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['activitylog.UserAgent'])), )) db.send_create_signal('activitylog', ['ProfileUserAgent']) # Adding unique constraint on 'ProfileUserAgent', fields ['agent', 'user'] db.create_unique('activitylog_profileuseragent', ['agent_id', 'user_id']) # Adding unique constraint on 'ProfileUserAgent', fields ['agent', 'profile'] db.create_unique('activitylog_profileuseragent', ['agent_id', 'profile_id']) def backwards(self, orm): # Removing unique constraint on 'ProfileUserAgent', fields ['agent', 'profile'] db.delete_unique('activitylog_profileuseragent', ['agent_id', 'profile_id']) # Removing unique constraint on 'ProfileUserAgent', fields ['agent', 'user'] db.delete_unique('activitylog_profileuseragent', ['agent_id', 'user_id']) # Removing unique constraint on 'ProfileIP', fields ['ip', 'profile'] db.delete_unique('activitylog_profileip', ['ip_id', 'profile_id']) # Removing unique constraint on 'ProfileIP', fields ['ip', 'user'] db.delete_unique('activitylog_profileip', ['ip_id', 'user_id']) # Removing unique constraint on 'Backlink', fields ['site', 'url', 'referrer'] db.delete_unique('activitylog_backlink', ['site_id', 'url', 'referrer']) # Deleting model 'UserAgent' db.delete_table('activitylog_useragent') # Deleting model 'IP' db.delete_table('activitylog_ip') # Deleting model 'Backlink' db.delete_table('activitylog_backlink') # Deleting model 'ProfileIP' db.delete_table('activitylog_profileip') # Deleting model 'ProfileUserAgent' db.delete_table('activitylog_profileuseragent') models = { apm_key: freeze_apps(apm_app)[apm_key], 'activitylog.backlink': { 'Meta': { 'unique_together': "((u'site', u'url', u'referrer'),)", 'object_name': 'Backlink' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'referrer': ('django.db.models.fields.URLField', [], { 'max_length': '100' }), 'site': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['sites.Site']" }), 'status': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }), 'url': ('django.db.models.fields.URLField', [], { 'max_length': '100' }), 'visits': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '1' }) }, 'activitylog.ip': { 'Meta': { 'object_name': 'IP' }, 'address': ('django.db.models.fields.IPAddressField', [], { 'null': 'True', 'default': 'None', 'max_length': '15', 'blank': 'True', 'unique': 'True', 'db_index': 'True' }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'hostname': ('django.db.models.fields.CharField', [], { 'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'number': ('django.db.models.fields.BigIntegerField', [], { 'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True' }), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileIP']", 'symmetrical': 'False' }) }, 'activitylog.profileip': { 'Meta': { 'unique_together': "((u'ip', u'user'), (u'ip', u'profile'))", 'object_name': 'ProfileIP' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'ip': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.IP']" }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }), 'user': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['auth.User']" }) }, 'activitylog.profileuseragent': { 'Meta': { 'unique_together': "((u'agent', u'user'), (u'agent', u'profile'))", 'object_name': 'ProfileUserAgent' }, 'agent': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['activitylog.UserAgent']" }), 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'profile': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL) }), 'user': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['auth.User']" }) }, 'activitylog.useragent': { 'Meta': { 'object_name': 'UserAgent' }, 'cache_version': ('django.db.models.fields.PositiveIntegerField', [], { 'default': '0' }), 'created': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'modified': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'name': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '255', 'db_index': 'True' }), 'profiles': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['{ACTIVITYLOG_PROFILE_MODEL}']".format( ACTIVITYLOG_PROFILE_MODEL=ACTIVITYLOG_PROFILE_MODEL), 'through': "orm['activitylog.ProfileUserAgent']", 'symmetrical': 'False' }) }, 'auth.group': { 'Meta': { 'object_name': 'Group' }, 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '80' }), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }) }, 'auth.permission': { 'Meta': { 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission' }, 'codename': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'content_type': ('django.db.models.fields.related.ForeignKey', [], { 'to': "orm['contenttypes.ContentType']" }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) }, 'auth.user': { 'Meta': { 'object_name': 'User' }, 'date_joined': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'email': ('django.db.models.fields.EmailField', [], { 'max_length': '75', 'blank': 'True' }), 'first_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'groups': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'is_active': ('django.db.models.fields.BooleanField', [], { 'default': 'True' }), 'is_staff': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'is_superuser': ('django.db.models.fields.BooleanField', [], { 'default': 'False' }), 'last_login': ('django.db.models.fields.DateTimeField', [], { 'default': 'datetime.datetime.now' }), 'last_name': ('django.db.models.fields.CharField', [], { 'max_length': '30', 'blank': 'True' }), 'password': ('django.db.models.fields.CharField', [], { 'max_length': '128' }), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], { 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True' }), 'username': ('django.db.models.fields.CharField', [], { 'unique': 'True', 'max_length': '30' }) }, 'contenttypes.contenttype': { 'Meta': { 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'" }, 'app_label': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'model': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '100' }) }, 'sites.site': { 'Meta': { 'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'" }, 'domain': ('django.db.models.fields.CharField', [], { 'max_length': '100' }), 'id': ('django.db.models.fields.AutoField', [], { 'primary_key': 'True' }), 'name': ('django.db.models.fields.CharField', [], { 'max_length': '50' }) } } complete_apps = ['activitylog']
def handle(self, app=None, name="", added_model_list=None, added_field_list=None, freeze_list=None, initial=False, auto=False, stdout=False, added_index_list=None, verbosity=1, empty=False, update=False, **options): # Any supposed lists that are None become empty lists added_model_list = added_model_list or [] added_field_list = added_field_list or [] added_index_list = added_index_list or [] freeze_list = freeze_list or [] # --stdout means name = - if stdout: name = "-" # Only allow valid names if re.search('[^_\w]', name) and name != "-": self.error( "Migration names should contain only alphanumeric characters and underscores." ) # Make sure options are compatable if initial and (added_model_list or added_field_list or auto): self.error( "You cannot use --initial and other options together\n" + self.usage_str) if auto and (added_model_list or added_field_list or initial): self.error("You cannot use --auto and other options together\n" + self.usage_str) if not app: self.error("You must provide an app to create a migration for.\n" + self.usage_str) # See if the app exists app = app.split(".")[-1] try: app_module = models.get_app(app) except ImproperlyConfigured: print("There is no enabled application matching '%s'." % app) return # Get the Migrations for this app (creating the migrations dir if needed) migrations = Migrations(app, force_creation=True, verbose_creation=int(verbosity) > 0) # What actions do we need to do? if auto: # Get the old migration try: last_migration = migrations[-2 if update else -1] except IndexError: self.error( "You cannot use --auto on an app with no migrations. Try --initial." ) # Make sure it has stored models if migrations.app_label() not in getattr( last_migration.migration_class(), "complete_apps", []): self.error( "You cannot use automatic detection, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label()) # Alright, construct two model dicts to run the differ on. old_defs = dict( (k, v) for k, v in last_migration.migration_class().models.items() if k.split(".")[0] == migrations.app_label()) new_defs = dict((k, v) for k, v in freezer.freeze_apps( [migrations.app_label()]).items() if k.split(".")[0] == migrations.app_label()) change_source = changes.AutoChanges( migrations=migrations, old_defs=old_defs, old_orm=last_migration.orm(), new_defs=new_defs, ) elif initial: # Do an initial migration change_source = changes.InitialChanges(migrations) else: # Read the commands manually off of the arguments if (added_model_list or added_field_list or added_index_list): change_source = changes.ManualChanges( migrations, added_model_list, added_field_list, added_index_list, ) elif empty: change_source = None else: print( "You have not passed any of --initial, --auto, --empty, --add-model, --add-field or --add-index.", file=sys.stderr) sys.exit(1) # Validate this so we can access the last migration without worrying if update and not migrations: self.error("You cannot use --update on an app with no migrations.") # if not name, there's an error if not name: if change_source: name = change_source.suggest_name() if update: name = re.sub(r'^\d{4}_', '', migrations[-1].name()) if not name: self.error("You must provide a name for this migration\n" + self.usage_str) # Get the actions, and then insert them into the actions lists forwards_actions = [] backwards_actions = [] if change_source: for action_name, params in change_source.get_changes(): # Run the correct Action class try: action_class = getattr(actions, action_name) except AttributeError: raise ValueError("Invalid action name from source: %s" % action_name) else: action = action_class(**params) action.add_forwards(forwards_actions) action.add_backwards(backwards_actions) print(action.console_line(), file=sys.stderr) # Nowt happen? That's not good for --auto. if auto and not forwards_actions: self.error("Nothing seems to have changed.") # Work out which apps to freeze apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list) # So, what's in this file, then? file_contents = self.get_migration_template() % { "forwards": "\n".join(forwards_actions or [" pass"]), "backwards": "\n".join(backwards_actions or [" pass"]), "frozen_models": freezer.freeze_apps_to_string(apps_to_freeze), "complete_apps": apps_to_freeze and "complete_apps = [%s]" % (", ".join(map(repr, apps_to_freeze))) or "" } # Deal with update mode as late as possible, avoid a rollback as long # as something else can go wrong. if update: last_migration = migrations[-1] if MigrationHistory.objects.filter( applied__isnull=False, app_name=app, migration=last_migration.name()): print( "Migration to be updated, %s, is already applied, rolling it back now..." % last_migration.name(), file=sys.stderr) migrate_app(migrations, 'current-1', verbosity=verbosity) for ext in ('py', 'pyc'): old_filename = "%s.%s" % (os.path.join( migrations.migrations_dir(), last_migration.filename), ext) if os.path.isfile(old_filename): os.unlink(old_filename) migrations.remove(last_migration) # See what filename is next in line. We assume they use numbers. new_filename = migrations.next_filename(name) # - is a special name which means 'print to stdout' if name == "-": print(file_contents) # Write the migration file if the name isn't - else: fp = open(os.path.join(migrations.migrations_dir(), new_filename), "w") fp.write(file_contents) fp.close() verb = 'Updated' if update else 'Created' if empty: print( "%s %s. You must now edit this migration and add the code for each direction." % (verb, new_filename), file=sys.stderr) else: print( "%s %s. You can now apply this migration with: ./manage.py migrate %s" % (verb, new_filename, app), file=sys.stderr)
class Migration(SchemaMigration): def forwards(self, orm): # Adding model 'Story' db.create_table('stories_story', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('headline', self.gf('django.db.models.fields.CharField')(max_length=100)), ('tease_headline', self.gf('django.db.models.fields.CharField')( default='', max_length=100, blank=True)), ('subhead', self.gf('django.db.models.fields.CharField')( max_length=200, null=True, blank=True)), ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)), ('non_staff_author', self.gf('django.db.models.fields.CharField')( max_length=200, null=True, blank=True)), ('publish_date', self.gf('django.db.models.fields.DateField')( null=True, blank=True)), ('publish_time', self.gf('django.db.models.fields.TimeField')( null=True, blank=True)), ('update_date', self.gf('django.db.models.fields.DateTimeField')( null=True, blank=True)), ('modified_date', self.gf('django.db.models.fields.DateTimeField')( auto_now=True, blank=True)), ('comments', self.gf('django.db.models.fields.BooleanField')(default=True)), ('comment_status', self.gf('django.db.models.fields.IntegerField')(default=1)), ('status', self.gf('django.db.models.fields.IntegerField')(default=1)), ('teaser', self.gf('django.db.models.fields.TextField')(blank=True)), ('kicker', self.gf('django.db.models.fields.CharField')( max_length=50, null=True, blank=True)), ('body', self.gf('django.db.models.fields.TextField')()), ('origin', self.gf('django.db.models.fields.IntegerField')(default=0)), ('site', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['sites.Site'])), )) db.send_create_signal('stories', ['Story']) # Adding unique constraint on 'Story', fields ['publish_date', 'slug'] db.create_unique('stories_story', ['publish_date', 'slug']) # Get the name and column name of the m2m author field field, a, b, c = Story._meta.get_field_by_name('authors') m2m_column_name = field.m2m_reverse_name() field_name = field.m2m_reverse_field_name() # Adding M2M table for field authors on 'Story' db.create_table( 'stories_story_authors', (('id', models.AutoField( verbose_name='ID', primary_key=True, auto_created=True)), ('story', models.ForeignKey(orm['stories.story'], null=False)), (field_name, models.ForeignKey(orm[AUTHOR_MODEL], null=False)))) db.create_unique('stories_story_authors', ['story_id', m2m_column_name]) def backwards(self, orm): # Removing unique constraint on 'Story', fields ['publish_date', 'slug'] db.delete_unique('stories_story', ['publish_date', 'slug']) # Deleting model 'Story' db.delete_table('stories_story') # Removing M2M table for field authors on 'Story' db.delete_table('stories_story_authors') models = freezer.freeze_apps(['stories']) complete_apps = ['stories']