Hello community, here is the log from the commit of package python-South for openSUSE:Factory checked in at 2012-08-26 11:34:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-South (Old) and /work/SRC/openSUSE:Factory/.python-South.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-South", Maintainer is "" Changes: -------- --- /work/SRC/openSUSE:Factory/python-South/python-South.changes 2012-05-29 10:36:04.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-South.new/python-South.changes 2012-08-26 11:34:12.000000000 +0200 @@ -1,0 +2,12 @@ +Sat Aug 4 14:16:39 UTC 2012 - [email protected] + +- Update to 0.7.6: + - There is now a new --update switch, which you can use with + schemamigration to merge updates you've just done into your + most recent migration and then reverse and re-apply that + migration to the database. + - Note that this will only work with migrations that aren't yet + committed into a VCS - once that occurs, you should create a + new migration rather than running --update on the current one. + +------------------------------------------------------------------- Old: ---- South-0.7.5.tar.gz New: ---- South-0.7.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-South.spec ++++++ --- /var/tmp/diff_new_pack.LTGKLT/_old 2012-08-26 11:34:14.000000000 +0200 +++ /var/tmp/diff_new_pack.LTGKLT/_new 2012-08-26 11:34:14.000000000 +0200 @@ -17,7 +17,7 @@ Name: python-South -Version: 0.7.5 +Version: 0.7.6 Release: 0 Url: http://south.aeracode.org/ Summary: South: Migrations for Django ++++++ South-0.7.5.tar.gz -> South-0.7.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/PKG-INFO new/South-0.7.6/PKG-INFO --- old/South-0.7.5/PKG-INFO 2012-05-08 18:25:01.000000000 +0200 +++ new/South-0.7.6/PKG-INFO 2012-08-02 12:24:54.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: South -Version: 0.7.5 +Version: 0.7.6 Summary: South: Migrations for Django Home-page: http://south.aeracode.org/ Author: Andrew Godwin & Andy McCurdy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/South.egg-info/PKG-INFO new/South-0.7.6/South.egg-info/PKG-INFO --- old/South-0.7.5/South.egg-info/PKG-INFO 2012-05-08 18:25:01.000000000 +0200 +++ new/South-0.7.6/South.egg-info/PKG-INFO 2012-08-02 12:24:52.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: South -Version: 0.7.5 +Version: 0.7.6 Summary: South: Migrations for Django Home-page: http://south.aeracode.org/ Author: Andrew Godwin & Andy McCurdy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/setup.py new/South-0.7.6/setup.py --- old/South-0.7.5/setup.py 2012-05-08 18:24:16.000000000 +0200 +++ new/South-0.7.6/setup.py 2012-07-08 12:02:15.000000000 +0200 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Use setuptools if we can try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/__init__.py new/South-0.7.6/south/__init__.py --- old/South-0.7.5/south/__init__.py 2012-05-08 12:28:24.000000000 +0200 +++ new/South-0.7.6/south/__init__.py 2012-08-02 12:14:45.000000000 +0200 @@ -2,7 +2,7 @@ South - Useable migrations for Django apps """ -__version__ = "0.7.5" +__version__ = "0.7.6" __authors__ = [ "Andrew Godwin <[email protected]>", "Andy McCurdy <[email protected]>" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/db/__init__.py new/South-0.7.6/south/db/__init__.py --- old/South-0.7.5/south/db/__init__.py 2012-03-17 13:25:06.000000000 +0100 +++ new/South-0.7.6/south/db/__init__.py 2012-07-08 12:02:15.000000000 +0200 @@ -18,6 +18,9 @@ 'django.contrib.gis.db.backends.spatialite': 'sqlite3', 'django.contrib.gis.db.backends.mysql': 'mysql', 'django.contrib.gis.db.backends.oracle': 'oracle', + 'doj.backends.zxjdbc.postgresql': 'postgresql_psycopg2', #django-jython + 'doj.backends.zxjdbc.mysql': 'mysql', #django-jython + 'doj.backends.zxjdbc.oracle': 'oracle', #django-jython } # First, work out if we're multi-db or not, and which databases we have diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/db/firebird.py new/South-0.7.6/south/db/firebird.py --- old/South-0.7.5/south/db/firebird.py 2012-04-13 16:45:45.000000000 +0200 +++ new/South-0.7.6/south/db/firebird.py 2012-08-02 12:09:04.000000000 +0200 @@ -86,6 +86,7 @@ columns.append(col) if isinstance(field, models.AutoField): + field_name = field.db_column or field.column autoinc_sql = connection.ops.autoinc_sql(table_name, field_name) sql = 'CREATE TABLE %s (%s);' % (qn, ', '.join([col for col in columns])) @@ -147,6 +148,8 @@ default = "'%s'" % default.replace("'", "''") elif isinstance(default, (datetime.date, datetime.time, datetime.datetime)): default = "'%s'" % default + elif isinstance(default, bool): + default = int(default) # Escape any % signs in the output (bug #317) if isinstance(default, basestring): default = default.replace("%", "%%") @@ -285,7 +288,7 @@ for sql, values in sqls: try: self.execute("ALTER TABLE %s %s;" % (self.quote_name(table_name), sql), values) - except DatabaseError as e: + except DatabaseError, e: print e diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/db/generic.py new/South-0.7.6/south/db/generic.py --- old/South-0.7.5/south/db/generic.py 2012-05-08 12:27:44.000000000 +0200 +++ new/South-0.7.6/south/db/generic.py 2012-07-08 12:02:15.000000000 +0200 @@ -338,6 +338,10 @@ if len(table_name) > 63: print " ! WARNING: You have a table name longer than 63 characters; this will not fully work on PostgreSQL or MySQL." + # avoid default values in CREATE TABLE statements (#925) + for field_name, field in fields: + field._suppress_default = True + columns = [ self.column_sql(table_name, field_name, field) for field_name, field in fields diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/db/sql_server/pyodbc.py new/South-0.7.6/south/db/sql_server/pyodbc.py --- old/South-0.7.5/south/db/sql_server/pyodbc.py 2012-05-03 16:54:05.000000000 +0200 +++ new/South-0.7.6/south/db/sql_server/pyodbc.py 2012-07-08 12:02:15.000000000 +0200 @@ -6,6 +6,7 @@ from south.db.generic import delete_column_constraints, invalidate_table_constraints, copy_column_constraints from south.exceptions import ConstraintDropped from django.utils.encoding import smart_unicode +from django.core.management.color import no_style class DatabaseOperations(generic.DatabaseOperations): """ @@ -169,6 +170,11 @@ sch = qn(self._get_schema_name()) tab = qn(table_name) table = ".".join([sch, tab]) + try: + self.delete_foreign_key(table_name, name) + except ValueError: + # no FK constraint on this field. That's OK. + pass constraints = self._find_constraints_for_column(table_name, name, False) for constraint in constraints.keys(): params = dict(table_name = table, @@ -214,6 +220,9 @@ field.rel.to._meta.get_field(field.rel.field_name).column ) ) + model = self.mock_model("FakeModelForIndexCreation", table_name) + for stmt in self._get_connection().creation.sql_indexes_for_field(model, field, no_style()): + self.execute(stmt) return ret_val @@ -420,6 +429,6 @@ schema = self._get_schema_name() indexes = self.execute(find_index_sql, [schema, table_name, column]) qn = self.quote_name - for index in (i[0] for i in indexes): + for index in (i[0] for i in indexes if i[0]): # "if i[0]" added because an empty name may return self.execute("DROP INDEX %s on %s.%s" % (qn(index), qn(schema), qn(table_name) )) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/hacks/django_1_0.py new/South-0.7.6/south/hacks/django_1_0.py --- old/South-0.7.5/south/hacks/django_1_0.py 2011-03-16 12:52:11.000000000 +0100 +++ new/South-0.7.6/south/hacks/django_1_0.py 2012-08-02 12:09:04.000000000 +0200 @@ -3,9 +3,8 @@ """ from django.conf import settings -from django.db import models from django.db.backends.creation import BaseDatabaseCreation -from django.db.models.loading import AppCache, cache +from django.db.models.loading import cache from django.core import management from django.core.management.commands.flush import Command as FlushCommand from django.utils.datastructures import SortedDict @@ -49,14 +48,13 @@ """ Used to repopulate AppCache after fiddling with INSTALLED_APPS. """ - a = AppCache() - a.loaded = False - a.handled = {} - a.postponed = [] - a.app_store = SortedDict() - a.app_models = SortedDict() - a.app_errors = {} - a._populate() + cache.loaded = False + cache.handled = {} + cache.postponed = [] + cache.app_store = SortedDict() + cache.app_models = SortedDict() + cache.app_errors = {} + cache._populate() def clear_app_cache(self): @@ -81,6 +79,12 @@ """ cache._populate() + def store_app_cache_state(self): + self.stored_app_cache_state = dict(**cache.__dict__) + + def restore_app_cache_state(self): + cache.__dict__ = self.stored_app_cache_state + def patch_flush_during_test_db_creation(self): """ Patches BaseDatabaseCreation.create_test_db to not flush database diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/management/commands/migrate.py new/South-0.7.6/south/management/commands/migrate.py --- old/South-0.7.5/south/management/commands/migrate.py 2011-10-14 13:27:52.000000000 +0200 +++ new/South-0.7.6/south/management/commands/migrate.py 2012-07-08 12:02:15.000000000 +0200 @@ -7,6 +7,7 @@ from django.core.management.base import BaseCommand from django.conf import settings +from django.utils.importlib import import_module from south import migration from south.migration import Migrations @@ -59,7 +60,7 @@ # we need apps to behave correctly. for app_name in settings.INSTALLED_APPS: try: - __import__(app_name + '.management', {}, {}, ['']) + import_module('.management', app_name) except ImportError, exc: msg = exc.args[0] if not msg.startswith('No module named') or 'management' not in msg: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/management/commands/schemamigration.py new/South-0.7.6/south/management/commands/schemamigration.py --- old/South-0.7.5/south/management/commands/schemamigration.py 2012-04-07 01:12:49.000000000 +0200 +++ new/South-0.7.6/south/management/commands/schemamigration.py 2012-07-08 12:02:15.000000000 +0200 @@ -20,7 +20,8 @@ from django.db import models from django.conf import settings -from south.migration import Migrations +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 @@ -39,11 +40,13 @@ help='Attempt to automatically detect differences from the last migration.'), make_option('--empty', action='store_true', dest='empty', default=False, help='Make a blank migration.'), + make_option('--update', action='store_true', dest='update', default=False, + help='Update the most recent migration instead of creating a new one. Rollback this migration if it is already applied.'), ) help = "Creates a new template schema migration for the given app" usage_str = "Usage: ./manage.py schemamigration appname migrationname [--empty] [--initial] [--auto] [--add-model ModelName] [--add-field ModelName.field_name] [--stdout]" - 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): + 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 [] @@ -70,13 +73,13 @@ 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) + 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[-1] + 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 @@ -116,17 +119,20 @@ else: print >>sys.stderr, "You have not passed any of --initial, --auto, --empty, --add-model, --add-field or --add-index." 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) - # 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 = [] @@ -157,7 +163,23 @@ "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 >>sys.stderr, "Migration to be updated, %s, is already applied, rolling it back now..." % last_migration.name() + 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 @@ -166,10 +188,11 @@ 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 >>sys.stderr, "Created %s. You must now edit this migration and add the code for each direction." % new_filename + print >>sys.stderr, "%s %s. You must now edit this migration and add the code for each direction." % (verb, new_filename) else: - print >>sys.stderr, "Created %s. You can now apply this migration with: ./manage.py migrate %s" % (new_filename, app) + print >>sys.stderr, "%s %s. You can now apply this migration with: ./manage.py migrate %s" % (verb, new_filename, app) MIGRATION_TEMPLATE = """# -*- coding: utf-8 -*- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/migration/__init__.py new/South-0.7.6/south/migration/__init__.py --- old/South-0.7.5/south/migration/__init__.py 2011-11-13 19:15:57.000000000 +0100 +++ new/South-0.7.6/south/migration/__init__.py 2012-07-26 21:06:58.000000000 +0200 @@ -166,16 +166,10 @@ Migrations.calculate_dependencies() # Check there's no strange ones in the database - applied_all = MigrationHistory.objects.filter(applied__isnull=False).order_by('applied') - applied = applied_all.filter(app_name=app_label) - # If we're using a different database, use that - if database != DEFAULT_DB_ALIAS: - applied_all = applied_all.using(database) - applied = applied.using(database) - south.db.db = south.db.dbs[database] - # We now have to make sure the migrations are all reloaded, as they'll - # have imported the old value of south.db.db. - Migrations.invalidate_all_modules() + applied_all = MigrationHistory.objects.filter(applied__isnull=False).order_by('applied').using(database) + applied = applied_all.filter(app_name=app_label).using(database) + south.db.db = south.db.dbs[database] + Migrations.invalidate_all_modules() south.db.db.debug = (verbosity > 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/migration/base.py new/South-0.7.6/south/migration/base.py --- old/South-0.7.5/south/migration/base.py 2012-01-23 21:23:09.000000000 +0100 +++ new/South-0.7.6/south/migration/base.py 2012-07-08 12:02:15.000000000 +0200 @@ -7,6 +7,7 @@ from django.core.exceptions import ImproperlyConfigured from django.db import models from django.conf import settings +from django.utils import importlib from south import exceptions from south.migration.utils import depends, dfs, flatten, get_app_label @@ -111,11 +112,11 @@ """ module_path = self.migrations_module() try: - module = __import__(module_path, {}, {}, ['']) + module = importlib.import_module(module_path) except ImportError: # There's no migrations module made yet; guess! try: - parent = __import__(".".join(module_path.split(".")[:-1]), {}, {}, ['']) + parent = importlib.import_module(".".join(module_path.split(".")[:-1])) except ImportError: # The parent doesn't even exist, that's an issue. raise exceptions.InvalidMigrationModule( @@ -149,12 +150,12 @@ self._application = application if not hasattr(application, 'migrations'): try: - module = __import__(self.migrations_module(), {}, {}, ['']) + module = importlib.import_module(self.migrations_module()) self._migrations = application.migrations = module except ImportError: if force_creation: self.create_migrations_directory(verbose_creation) - module = __import__(self.migrations_module(), {}, {}, ['']) + module = importlib.import_module(self.migrations_module()) self._migrations = application.migrations = module else: raise exceptions.NoMigrations(application) @@ -274,6 +275,9 @@ def __eq__(self, other): return self.app_label() == other.app_label() and self.name() == other.name() + def __hash__(self): + return hash(str(self)) + def app_label(self): return self.migrations.app_label() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/__init__.py new/South-0.7.6/south/tests/__init__.py --- old/South-0.7.5/south/tests/__init__.py 2012-05-03 16:54:05.000000000 +0200 +++ new/South-0.7.6/south/tests/__init__.py 2012-08-02 12:09:04.000000000 +0200 @@ -1,11 +1,36 @@ -import unittest +#import unittest import os import sys from functools import wraps from django.conf import settings from south.hacks import hacks +# Make sure skipping tests is available. +try: + # easiest and best is unittest included in Django>=1.3 + from django.utils import unittest +except ImportError: + # earlier django... use unittest from stdlib + import unittest +# however, skipUnless was only added in Python 2.7; +# if not available, we need to do something else +try: + skipUnless = unittest.skipUnless #@UnusedVariable +except AttributeError: + def skipUnless(condition, message): + def decorator(testfunc): + @wraps(testfunc) + def wrapper(self): + if condition: + # Apply method + testfunc(self) + else: + # The skip exceptions are not available either... + print "Skipping", testfunc.__name__,"--", message + return wrapper + return decorator + # Add the tests directory so fakeapp is on sys.path test_root = os.path.dirname(__file__) sys.path.append(test_root) @@ -31,43 +56,21 @@ pass return fake - def setUp(self): """ Changes the Django environment so we can run tests against our test apps. """ - if getattr(self, 'installed_apps', None): + if hasattr(self, 'installed_apps'): + hacks.store_app_cache_state() hacks.set_installed_apps(self.installed_apps) - - + def tearDown(self): """ Undoes what setUp did. """ - if getattr(self, 'installed_apps', None): + if hasattr(self, 'installed_apps'): hacks.reset_installed_apps() - -# Make sure skipUnless is available. -try: - # skipUnless added in Python 2.7; - from unittest import skipUnless -except ImportError: - try: - # django.utils.unittest added in Django 1.3; - from django.utils.unittest import skipUnless - except ImportError: - def skipUnless(condition, message): - def decorator(testfunc): - @wraps(testfunc) - def wrapper(self): - if condition: - # Apply method - testfunc(self) - else: - # The skip exceptions are not available either... - print "Skipping", testfunc.__name__,"--", message - return wrapper - return decorator + hacks.restore_app_cache_state() # Try importing all tests if asked for (then we can run 'em) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/autodetection.py new/South-0.7.6/south/tests/autodetection.py --- old/South-0.7.5/south/tests/autodetection.py 2012-05-08 12:25:41.000000000 +0200 +++ new/South-0.7.6/south/tests/autodetection.py 2012-07-08 12:02:15.000000000 +0200 @@ -1,4 +1,4 @@ -import unittest +from south.tests import unittest from south.creator.changes import AutoChanges, InitialChanges from south.migration.base import Migrations diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/db.py new/South-0.7.6/south/tests/db.py --- old/South-0.7.5/south/tests/db.py 2012-05-03 16:54:05.000000000 +0200 +++ new/South-0.7.6/south/tests/db.py 2012-07-08 17:43:39.000000000 +0200 @@ -1,10 +1,9 @@ import datetime -import unittest from south.db import db, generic -from django.db import connection, models +from django.db import connection, models, IntegrityError -from south.tests import skipUnless +from south.tests import unittest, skipUnless # Create a list of error classes from the various database libraries errors = [] @@ -265,8 +264,9 @@ # Add a FK with keep_default=False (#69) User = db.mock_model(model_name='User', db_table='auth_user', db_tablespace='', pk_field_name='id', pk_field_type=models.AutoField, pk_field_args=[], pk_field_kwargs={}) # insert some data so we can test the default value of the added fkey - db.execute("INSERT INTO test_addc (eggs, add1) VALUES (1, 2)") + db.execute("INSERT INTO test_addc (spam, eggs, add1) VALUES (%s, 1, 2)", [False]) db.add_column("test_addc", "user", models.ForeignKey(User, null=True), keep_default=False) + db.execute_deferred_sql() # try selecting from the user_id column to make sure it was actually created val = db.execute("SELECT user_id FROM test_addc")[0][0] self.assertEquals(val, None) @@ -286,7 +286,7 @@ # Add a column with a default db.add_column("test_addnbc", "add2", models.NullBooleanField(default=True)) # insert some data so we can test the default values of the added column - db.execute("INSERT INTO test_addnbc (eggs) VALUES (1)") + db.execute("INSERT INTO test_addnbc (spam, eggs) VALUES (%s, 1)", [False]) # try selecting from the new columns to make sure they were properly created false, null, true = db.execute("SELECT spam,add1,add2 FROM test_addnbc")[0][0:3] self.assertTrue(true) @@ -302,9 +302,12 @@ ('spam', models.BooleanField(default=False)), ('eggs', models.IntegerField()), ]) + db.execute_deferred_sql() # Change eggs to be a FloatField db.alter_column("test_alterc", "eggs", models.FloatField()) + db.execute_deferred_sql() db.delete_table("test_alterc") + db.execute_deferred_sql() def test_alter_char_default(self): """ @@ -368,6 +371,7 @@ db.create_table("test_alterc", [ ('num', models.PositiveIntegerField()), ]) + db.execute_deferred_sql() # Add in some test values db.execute("INSERT INTO test_alterc (num) VALUES (1)") db.execute("INSERT INTO test_alterc (num) VALUES (2)") @@ -382,6 +386,7 @@ self.fail("Could insert a negative integer into a PositiveIntegerField.") # Alter it to a normal IntegerField db.alter_column("test_alterc", "num", models.IntegerField()) + db.execute_deferred_sql() # It should now work db.execute("INSERT INTO test_alterc (num) VALUES (-3)") db.delete_table("test_alterc") @@ -405,26 +410,28 @@ ('eggs', models.IntegerField()), ('ham', models.ForeignKey(db.mock_model('Unique2', 'test_unique2'))), ]) + db.execute_deferred_sql() # Add a constraint db.create_unique("test_unique", ["spam"]) + db.execute_deferred_sql() # Shouldn't do anything during dry-run db.dry_run = True db.delete_unique("test_unique", ["spam"]) db.dry_run = False db.delete_unique("test_unique", ["spam"]) db.create_unique("test_unique", ["spam"]) - db.commit_transaction() - db.start_transaction() - # Special preparations for Sql Server if db.backend_name == "pyodbc": db.execute("SET IDENTITY_INSERT test_unique2 ON;") + db.execute("INSERT INTO test_unique2 (id) VALUES (1)") + db.execute("INSERT INTO test_unique2 (id) VALUES (2)") + db.commit_transaction() + db.start_transaction() + # Test it works TRUE = (True,) FALSE = (False,) - db.execute("INSERT INTO test_unique2 (id) VALUES (1)") - db.execute("INSERT INTO test_unique2 (id) VALUES (2)") db.execute("INSERT INTO test_unique (spam, eggs, ham_id) VALUES (%s, 0, 1)", TRUE) db.execute("INSERT INTO test_unique (spam, eggs, ham_id) VALUES (%s, 1, 2)", FALSE) try: @@ -535,8 +542,10 @@ db.create_table("test_text_to_char", [ ('textcol', models.TextField()), ]) + db.execute_deferred_sql() db.execute("INSERT INTO test_text_to_char VALUES (%s)", [value]) db.alter_column("test_text_to_char", "textcol", models.CharField(max_length=100)) + db.execute_deferred_sql() after = db.execute("select * from test_text_to_char")[0][0] self.assertEqual(value, after, "Change from text to char altered value [ %s != %s ]" % (`value`,`after`)) @@ -548,8 +557,10 @@ db.create_table("test_char_to_text", [ ('textcol', models.CharField(max_length=100)), ]) + db.execute_deferred_sql() db.execute("INSERT INTO test_char_to_text VALUES (%s)", [value]) db.alter_column("test_char_to_text", "textcol", models.TextField()) + db.execute_deferred_sql() after = db.execute("select * from test_char_to_text")[0][0] after = unicode(after) # Oracle text fields return a sort of lazy string -- force evaluation self.assertEqual(value, after, "Change from char to text altered value [ %s != %s ]" % (`value`,`after`)) @@ -574,9 +585,21 @@ ('col1', models.DateTimeField(default=end_of_world)), ('col2', models.DateTimeField(null=True)), ]) + db.execute_deferred_sql() db.alter_column("test_datetime_def", "col2", models.DateTimeField(default=end_of_world)) db.add_column("test_datetime_def", "col3", models.DateTimeField(default=end_of_world)) - db.execute("insert into test_datetime_def (col0) values (null)") + db.execute_deferred_sql() + # There should not be a default in the database for col1 + db.commit_transaction() + db.start_transaction() + self.assertRaises( + IntegrityError, + db.execute, "insert into test_datetime_def (col0) values (null)" + ) + db.rollback_transaction() + db.start_transaction() + # There should be for the others + db.execute("insert into test_datetime_def (col0, col1) values (null, %s)", [end_of_world]) ends = db.execute("select col1,col2,col3 from test_datetime_def")[0] self.failUnlessEqual(len(ends), 3) for e in ends: @@ -621,12 +644,14 @@ # remove constraint db.alter_column("test_column_constraint", "spam", models.IntegerField()) + db.execute_deferred_sql() # make sure the insertion works now db.execute('INSERT INTO test_column_constraint VALUES (-42)') db.execute('DELETE FROM test_column_constraint') # add it back again db.alter_column("test_column_constraint", "spam", models.PositiveIntegerField()) + db.execute_deferred_sql() # it should fail again db.start_transaction() try: @@ -676,6 +701,23 @@ if sql_test_str not in sql: self.fail("default sql value was not properly generated for field %r.\nSql was %s" % (field, sql)) + def test_make_added_foreign_key_not_null(self): + # Table for FK to target + User = db.mock_model(model_name='User', db_table='auth_user', db_tablespace='', pk_field_name='id', pk_field_type=models.AutoField, pk_field_args=[], pk_field_kwargs={}) + # Table with no foreign key + db.create_table("test_fk", [ + ('eggs', models.IntegerField()), + ]) + db.execute_deferred_sql() + + # Add foreign key + db.add_column("test_fk", 'foreik', models.ForeignKey(User, null=True), + keep_default = False) + db.execute_deferred_sql() + + # Make the FK null + db.alter_column("test_fk", "foreik_id", models.ForeignKey(User)) + db.execute_deferred_sql() class TestCacheGeneric(unittest.TestCase): base_ops_cls = generic.DatabaseOperations diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/db_mysql.py new/South-0.7.6/south/tests/db_mysql.py --- old/South-0.7.5/south/tests/db_mysql.py 2012-01-13 14:23:05.000000000 +0100 +++ new/South-0.7.6/south/tests/db_mysql.py 2012-07-08 12:02:15.000000000 +0200 @@ -1,7 +1,8 @@ # Additional MySQL-specific tests # Written by: F. Gabriel Gosselin <[email protected]> # Based on tests by: aarranz -import unittest +from south.tests import unittest + from south.db import db, generic, mysql from django.db import connection, models diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/freezer.py new/South-0.7.6/south/tests/freezer.py --- old/South-0.7.5/south/tests/freezer.py 2011-07-03 20:41:13.000000000 +0200 +++ new/South-0.7.6/south/tests/freezer.py 2012-07-08 12:02:15.000000000 +0200 @@ -1,4 +1,4 @@ -import unittest +from south.tests import unittest from south.creator.freezer import model_dependencies from south.tests.fakeapp import models diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/inspector.py new/South-0.7.6/south/tests/inspector.py --- old/South-0.7.5/south/tests/inspector.py 2012-05-03 16:54:05.000000000 +0200 +++ new/South-0.7.6/south/tests/inspector.py 2012-05-08 19:42:56.000000000 +0200 @@ -1,15 +1,14 @@ -from south.tests import Monkeypatcher -from south.modelsinspector import * + +from south.tests import Monkeypatcher, skipUnless +from south.modelsinspector import (convert_on_delete_handler, get_value, + IsDefault, models, value_clean) + from fakeapp.models import HorribleModel, get_sentinel_object -from django.utils.functional import wraps on_delete_is_available = hasattr(models, "PROTECT") # models here is django.db.models - -from south.tests import skipUnless skipUnlessOnDeleteAvailable = skipUnless(on_delete_is_available, "not testing on_delete -- not available on Django<1.3") - class TestModelInspector(Monkeypatcher): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/logger.py new/South-0.7.6/south/tests/logger.py --- old/South-0.7.5/south/tests/logger.py 2012-01-13 14:33:51.000000000 +0100 +++ new/South-0.7.6/south/tests/logger.py 2012-07-08 12:02:15.000000000 +0200 @@ -1,7 +1,7 @@ import logging import os import tempfile -import unittest +from south.tests import unittest import StringIO import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/South-0.7.5/south/tests/logic.py new/South-0.7.6/south/tests/logic.py --- old/South-0.7.5/south/tests/logic.py 2011-05-09 10:44:35.000000000 +0200 +++ new/South-0.7.6/south/tests/logic.py 2012-07-08 12:02:15.000000000 +0200 @@ -1,4 +1,4 @@ -import unittest +from south.tests import unittest import datetime import sys -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
