def get_mutations(app, evolution_labels, database): """ Obtain the list of mutations described by the named evolutions. """ # For each item in the evolution sequence. Check each item to see if it is # a python file or an sql file. try: app_name = '.'.join(app.__name__.split('.')[:-1]) if app_name in BUILTIN_SEQUENCES: module_name = 'django_evolution.builtin_evolutions' else: module_name = '%s.evolutions' % app_name evolution_module = __import__(module_name, {}, {}, ['']) except ImportError: return [] mutations = [] for label in evolution_labels: directory_name = os.path.dirname(evolution_module.__file__) # The first element is used for compatibility purposes. filenames = [ os.path.join(directory_name, label + '.sql'), os.path.join(directory_name, "%s_%s.sql" % (database, label)), ] found = False for filename in filenames: if os.path.exists(filename): sql = [] sql_file = open(sql_file_name) for line in sql_file: sql.append(line) mutations.append(SQLMutation(label, sql)) found = True break if not found: try: module_name = [evolution_module.__name__, label] module = __import__('.'.join(module_name), {}, {}, [module_name]) mutations.extend(module.MUTATIONS) except ImportError: raise EvolutionException( 'Error: Failed to find an SQL or Python evolution named %s' % label) if is_multi_db(): latest_version = Version.objects.using(database).latest('when') else: latest_version = Version.objects.latest('when') app_label = app.__name__.split('.')[-2] old_proj_sig = pickle.loads(str(latest_version.signature)) proj_sig = create_project_sig(database) if app_label in old_proj_sig and app_label in proj_sig: # We want to go through now and make sure we're only applying # evolutions for models where the signature is different between # what's stored and what's current. # # The reason for this is that we may have just installed a baseline, # which would have the up-to-date signature, and we might be trying # to apply evolutions on top of that (which would already be applied). # These would generate errors. So, try hard to prevent that. old_app_sig = old_proj_sig[app_label] app_sig = proj_sig[app_label] changed_models = set() # Find the list of models in the latest signature of this app # that aren't in the old signature. for model_name, model_sig in app_sig.iteritems(): if (model_name not in old_app_sig or old_app_sig[model_name] != model_sig): changed_models.add(model_name) # Now do the same for models in the old signature, in case the # model has been deleted. for model_name, model_sig in old_app_sig.iteritems(): if model_name not in app_sig: changed_models.add(model_name) # We should now have a full list of which models changed. Filter # the list of mutations appropriately. mutations = [ mutation for mutation in mutations if (not hasattr(mutation, 'model_name') or mutation.model_name in changed_models) ] return mutations
def evolution(app, created_models, verbosity=1, **kwargs): """ A hook into syncdb's post_syncdb signal, that is used to notify the user if a model evolution is necessary. """ default_db = None if is_multi_db(): from django.db.utils import DEFAULT_DB_ALIAS default_db = DEFAULT_DB_ALIAS db = kwargs.get('db', default_db) proj_sig = create_project_sig(db) signature = pickle.dumps(proj_sig) using_args = {} if is_multi_db(): using_args['using'] = db try: if is_multi_db(): latest_version = \ django_evolution.Version.objects.using(db).latest('when') else: latest_version = django_evolution.Version.objects.latest('when') except django_evolution.Version.DoesNotExist: # We need to create a baseline version. if verbosity > 0: print "Installing baseline version" latest_version = django_evolution.Version(signature=signature) latest_version.save(**using_args) for a in get_apps(): install_baseline(a, latest_version, using_args, verbosity) unapplied = get_unapplied_evolutions(app, db) if unapplied: print style.NOTICE('There are unapplied evolutions for %s.' % app.__name__.split('.')[-2]) # Evolutions are checked over the entire project, so we only need to check # once. We do this check when Django Evolutions itself is synchronized. if app == django_evolution: old_proj_sig = pickle.loads(str(latest_version.signature)) # If any models or apps have been added, a baseline must be set # for those new models changed = False new_apps = [] for app_name, new_app_sig in proj_sig.items(): if app_name == '__version__': # Ignore the __version__ tag continue old_app_sig = old_proj_sig.get(app_name, None) if old_app_sig is None: # App has been added old_proj_sig[app_name] = proj_sig[app_name] new_apps.append(app_name) changed = True else: for model_name, new_model_sig in new_app_sig.items(): old_model_sig = old_app_sig.get(model_name, None) if old_model_sig is None: # Model has been added old_proj_sig[app_name][model_name] = \ proj_sig[app_name][model_name] changed = True if changed: if verbosity > 0: print "Adding baseline version for new models" latest_version = \ django_evolution.Version(signature=pickle.dumps(old_proj_sig)) latest_version.save(**using_args) for app_name in new_apps: install_baseline(get_app(app_name), latest_version, using_args, verbosity) # TODO: Model introspection step goes here. # # If the current database state doesn't match the last # # saved signature (as reported by latest_version), # # then we need to update the Evolution table. # actual_sig = introspect_project_sig() # acutal = pickle.dumps(actual_sig) # if actual != latest_version.signature: # nudge = Version(signature=actual) # nudge.save() # latest_version = nudge diff = Diff(old_proj_sig, proj_sig) if not diff.is_empty(): print style.NOTICE( 'Project signature has changed - an evolution is required') if verbosity > 1: old_proj_sig = pickle.loads(str(latest_version.signature)) print diff
def evolution(app, created_models, verbosity=1, **kwargs): """ A hook into syncdb's post_syncdb signal, that is used to notify the user if a model evolution is necessary. """ default_db = DEFAULT_DB_ALIAS db = kwargs.get('db', default_db) proj_sig = create_project_sig(db) signature = pickle.dumps(proj_sig) using_args = { 'using': db, } try: latest_version = \ django_evolution.Version.objects.current_version(using=db) except django_evolution.Version.DoesNotExist: # We need to create a baseline version. if verbosity > 0: print "Installing baseline version" latest_version = django_evolution.Version(signature=signature) latest_version.save(**using_args) for a in get_apps(): install_baseline(a, latest_version, using_args, verbosity) unapplied = get_unapplied_evolutions(app, db) if unapplied: print style.NOTICE('There are unapplied evolutions for %s.' % app.__name__.split('.')[-2]) # Evolutions are checked over the entire project, so we only need to check # once. We do this check when Django Evolutions itself is synchronized. if app == django_evolution: old_proj_sig = pickle.loads(str(latest_version.signature)) # If any models or apps have been added, a baseline must be set # for those new models changed = False new_apps = [] for app_name, new_app_sig in proj_sig.items(): if app_name == '__version__': # Ignore the __version__ tag continue old_app_sig = old_proj_sig.get(app_name, None) if old_app_sig is None: # App has been added old_proj_sig[app_name] = proj_sig[app_name] new_apps.append(app_name) changed = True else: for model_name, new_model_sig in new_app_sig.items(): old_model_sig = old_app_sig.get(model_name, None) if old_model_sig is None: # Model has been added old_proj_sig[app_name][model_name] = \ proj_sig[app_name][model_name] changed = True if changed: if verbosity > 0: print "Adding baseline version for new models" latest_version = \ django_evolution.Version(signature=pickle.dumps(old_proj_sig)) latest_version.save(**using_args) for app_name in new_apps: app = get_app(app_name, True) if app: install_baseline(app, latest_version, using_args, verbosity) # TODO: Model introspection step goes here. # # If the current database state doesn't match the last # # saved signature (as reported by latest_version), # # then we need to update the Evolution table. # actual_sig = introspect_project_sig() # acutal = pickle.dumps(actual_sig) # if actual != latest_version.signature: # nudge = Version(signature=actual) # nudge.save() # latest_version = nudge diff = Diff(old_proj_sig, proj_sig) if not diff.is_empty(): print style.NOTICE( 'Project signature has changed - an evolution is required') if verbosity > 1: old_proj_sig = pickle.loads(str(latest_version.signature)) print diff
'executing evolutions.') try: app_list = [get_app(app_label) for app_label in app_labels] except (ImproperlyConfigured, ImportError), e: raise CommandError("%s. Are you sure your INSTALLED_APPS " "setting is correct?" % e) else: app_list = get_apps() # Iterate over all applications running the mutations evolution_required = False simulated = True sql = [] new_evolutions = [] current_proj_sig = create_project_sig(database) current_signature = pickle.dumps(current_proj_sig) try: if is_multi_db(): latest_version = Version.objects.using(database).latest('when') else: latest_version = Version.objects.latest('when') database_sig = pickle.loads(str(latest_version.signature)) diff = Diff(database_sig, current_proj_sig) except Evolution.DoesNotExist: raise CommandError("Can't evolve yet. Need to set an " "evolution baseline.") try:
def get_mutations(app, evolution_labels, database): """ Obtain the list of mutations described by the named evolutions. """ # For each item in the evolution sequence. Check each item to see if it is # a python file or an sql file. try: app_name = '.'.join(app.__name__.split('.')[:-1]) if app_name in BUILTIN_SEQUENCES: module_name = 'django_evolution.builtin_evolutions' else: module_name = '%s.evolutions' % app_name evolution_module = __import__(module_name, {}, {}, ['']) except ImportError: return [] mutations = [] for label in evolution_labels: directory_name = os.path.dirname(evolution_module.__file__) # The first element is used for compatibility purposes. filenames = [ os.path.join(directory_name, label + '.sql'), os.path.join(directory_name, "%s_%s.sql" % (database, label)), ] found = False for filename in filenames: if os.path.exists(filename): sql = [] sql_file = open(sql_file_name) for line in sql_file: sql.append(line) mutations.append(SQLMutation(label, sql)) found = True break if not found: try: module_name = [evolution_module.__name__, label] module = __import__('.'.join(module_name), {}, {}, [module_name]); mutations.extend(module.MUTATIONS) except ImportError: raise EvolutionException( 'Error: Failed to find an SQL or Python evolution named %s' % label) if is_multi_db(): latest_version = Version.objects.using(database).latest('when') else: latest_version = Version.objects.latest('when') app_label = app.__name__.split('.')[-2] old_proj_sig = pickle.loads(str(latest_version.signature)) proj_sig = create_project_sig(database) if app_label in old_proj_sig and app_label in proj_sig: # We want to go through now and make sure we're only applying # evolutions for models where the signature is different between # what's stored and what's current. # # The reason for this is that we may have just installed a baseline, # which would have the up-to-date signature, and we might be trying # to apply evolutions on top of that (which would already be applied). # These would generate errors. So, try hard to prevent that. old_app_sig = old_proj_sig[app_label] app_sig = proj_sig[app_label] changed_models = set() # Find the list of models in the latest signature of this app # that aren't in the old signature. for model_name, model_sig in app_sig.iteritems(): if (model_name not in old_app_sig or old_app_sig[model_name] != model_sig): changed_models.add(model_name) # Now do the same for models in the old signature, in case the # model has been deleted. for model_name, model_sig in old_app_sig.iteritems(): if model_name not in app_sig: changed_models.add(model_name) # We should now have a full list of which models changed. Filter # the list of mutations appropriately. mutations = [ mutation for mutation in mutations if (not hasattr(mutation, 'model_name') or mutation.model_name in changed_models) ] return mutations
try: app_list = [get_app(app_label) for app_label in app_labels] except (ImproperlyConfigured, ImportError), e: raise CommandError("%s. Are you sure your INSTALLED_APPS " "setting is correct?" % e) else: app_list = get_apps() # Iterate over all applications running the mutations evolution_required = False #j--------------------变更请求 simulated = True sql = [] do_actions = [] new_evolutions = [] current_proj_sig = create_project_sig( database) #j-------------------当前版本的数据库整体结构 current_signature = pickle.dumps(current_proj_sig) try: if is_multi_db(): latest_version = Version.objects.using(database).latest('when') else: latest_version = Version.objects.latest('when') database_sig = pickle.loads(str(latest_version.signature) ) #j-------------------得到上一个版本的数据库整体结构 diff = Diff(database_sig, current_proj_sig) except Evolution.DoesNotExist: raise CommandError("Can't evolve yet. Need to set an " "evolution baseline.")
if execute: raise CommandError('Cannot specify an application name when executing evolutions.') try: app_list = [get_app(app_label) for app_label in app_labels] except (ImproperlyConfigured, ImportError), e: raise CommandError("%s. Are you sure your INSTALLED_APPS setting is correct?" % e) else: app_list = get_apps() # Iterate over all applications running the mutations evolution_required = False simulated = True sql = [] new_evolutions = [] current_proj_sig = create_project_sig() current_signature = pickle.dumps(current_proj_sig) try: latest_version = Version.objects.latest('when') database_sig = pickle.loads(str(latest_version.signature)) diff = Diff(database_sig, current_proj_sig) except Evolution.DoesNotExist: print self.style.ERROR("Can't evolve yet. Need to set an evolution baseline.") sys.exit(1) try: for app in app_list: app_label = app.__name__.split('.')[-2] if hint: evolutions = []
try: app_list = [get_app(app_label) for app_label in app_labels] except (ImproperlyConfigured, ImportError), e: raise CommandError("%s. Are you sure your INSTALLED_APPS " "setting is correct?" % e) else: app_list = get_apps() # Iterate over all applications running the mutations evolution_required = False #j--------------------变更请求 simulated = True sql = [] do_actions=[] new_evolutions = [] current_proj_sig = create_project_sig(database) #j-------------------当前版本的数据库整体结构 current_signature = pickle.dumps(current_proj_sig) try: if is_multi_db(): latest_version = Version.objects.using(database).latest('when') else: latest_version = Version.objects.latest('when') database_sig = pickle.loads(str(latest_version.signature)) #j-------------------得到上一个版本的数据库整体结构 diff = Diff(database_sig, current_proj_sig) except Evolution.DoesNotExist: raise CommandError("Can't evolve yet. Need to set an " "evolution baseline.") try:
def evolution(app, created_models, verbosity=1, **kwargs): """ A hook into syncdb's post_syncdb signal, that is used to notify the user if a model evolution is necessary. """ proj_sig = create_project_sig() signature = pickle.dumps(proj_sig) try: latest_version = django_evolution.Version.objects.latest('when') except django_evolution.Version.DoesNotExist: # We need to create a baseline version. if verbosity > 0: print "Installing baseline version" latest_version = django_evolution.Version(signature=signature) latest_version.save() for a in get_apps(): app_label = a.__name__.split('.')[-2] sequence = get_evolution_sequence(a) if sequence: if verbosity > 0: print 'Evolutions in %s baseline:' % app_label,', '.join(sequence) for evo_label in sequence: evolution = django_evolution.Evolution(app_label=app_label, label=evo_label, version=latest_version) evolution.save() unapplied = get_unapplied_evolutions(app) if unapplied: print style.NOTICE('There are unapplied evolutions for %s.' % app.__name__.split('.')[-2]) # Evolutions are checked over the entire project, so we only need to # check once. We do this check when Django Evolutions itself is synchronized. if app == django_evolution: old_proj_sig = pickle.loads(str(latest_version.signature)) # If any models have been added, a baseline must be set # for those new models changed = False for app_name, new_app_sig in proj_sig.items(): if app_name == '__version__': # Ignore the __version__ tag continue old_app_sig = old_proj_sig.get(app_name, None) if old_app_sig is None: # App has been added old_proj_sig[app_name] = proj_sig[app_name] changed = True continue for model_name, new_model_sig in new_app_sig.items(): old_model_sig = old_app_sig.get(model_name, None) if old_model_sig is None: # Model has been added old_proj_sig[app_name][model_name] = proj_sig[app_name][model_name] changed = True if changed: if verbosity > 0: print "Adding baseline version for new models" latest_version = django_evolution.Version(signature=pickle.dumps(old_proj_sig)) latest_version.save() # TODO: Model introspection step goes here. # # If the current database state doesn't match the last # # saved signature (as reported by latest_version), # # then we need to update the Evolution table. # actual_sig = introspect_project_sig() # acutal = pickle.dumps(actual_sig) # if actual != latest_version.signature: # nudge = Version(signature=actual) # nudge.save() # latest_version = nudge diff = Diff(old_proj_sig, proj_sig) if not diff.is_empty(): print style.NOTICE('Project signature has changed - an evolution is required') if verbosity > 1: old_proj_sig = pickle.loads(str(latest_version.signature)) print diff
def evolution(app, created_models, verbosity=1, **kwargs): """ A hook into syncdb's post_syncdb signal, that is used to notify the user if a model evolution is necessary. """ proj_sig = create_project_sig() signature = pickle.dumps(proj_sig) try: latest_version = django_evolution.Version.objects.latest('when') except django_evolution.Version.DoesNotExist: # We need to create a baseline version. if verbosity > 0: print "Installing baseline version" latest_version = django_evolution.Version(signature=signature) latest_version.save() for a in get_apps(): app_label = a.__name__.split('.')[-2] sequence = get_evolution_sequence(a) if sequence: if verbosity > 0: print 'Evolutions in %s baseline:' % app_label, ', '.join( sequence) for evo_label in sequence: evolution = django_evolution.Evolution(app_label=app_label, label=evo_label, version=latest_version) evolution.save() unapplied = get_unapplied_evolutions(app) if unapplied: print style.NOTICE('There are unapplied evolutions for %s.' % app.__name__.split('.')[-2]) # Evolutions are checked over the entire project, so we only need to # check once. We do this check when Django Evolutions itself is synchronized. if app == django_evolution: old_proj_sig = pickle.loads(str(latest_version.signature)) # If any models have been added, a baseline must be set # for those new models changed = False for app_name, new_app_sig in proj_sig.items(): if app_name == '__version__': # Ignore the __version__ tag continue old_app_sig = old_proj_sig.get(app_name, None) if old_app_sig is None: # App has been added old_proj_sig[app_name] = proj_sig[app_name] changed = True continue for model_name, new_model_sig in new_app_sig.items(): old_model_sig = old_app_sig.get(model_name, None) if old_model_sig is None: # Model has been added old_proj_sig[app_name][model_name] = proj_sig[app_name][ model_name] changed = True if changed: if verbosity > 0: print "Adding baseline version for new models" latest_version = django_evolution.Version( signature=pickle.dumps(old_proj_sig)) latest_version.save() # TODO: Model introspection step goes here. # # If the current database state doesn't match the last # # saved signature (as reported by latest_version), # # then we need to update the Evolution table. # actual_sig = introspect_project_sig() # acutal = pickle.dumps(actual_sig) # if actual != latest_version.signature: # nudge = Version(signature=actual) # nudge.save() # latest_version = nudge diff = Diff(old_proj_sig, proj_sig) if not diff.is_empty(): print style.NOTICE( 'Project signature has changed - an evolution is required') if verbosity > 1: old_proj_sig = pickle.loads(str(latest_version.signature)) print diff
try: app_list = [get_app(app_label) for app_label in app_labels] except (ImproperlyConfigured, ImportError), e: raise CommandError( "%s. Are you sure your INSTALLED_APPS setting is correct?" % e) else: app_list = get_apps() # Iterate over all applications running the mutations evolution_required = False simulated = True sql = [] new_evolutions = [] current_proj_sig = create_project_sig() current_signature = pickle.dumps(current_proj_sig) try: latest_version = Version.objects.latest('when') database_sig = pickle.loads(str(latest_version.signature)) diff = Diff(database_sig, current_proj_sig) except Evolution.DoesNotExist: print self.style.ERROR( "Can't evolve yet. Need to set an evolution baseline.") sys.exit(1) try: for app in app_list: app_label = app.__name__.split('.')[-2] if hint: