Rectangle 27 7

Like thnee (see her answer), we're using a gentler approach to the South author's (Andrew Godwin) suggestion quoted elsewhere here, and we're separating what we do with the code base from what we do to the database, during deployment, because we need the deployments to be repeatable:

What we do in the code:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

What we do to the database once that code is deployed

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

I think I just did the same thing, but manually deleting database entries, rather than using --delete_ghoist-migrations. Your way is a bit nicer.

What's the recommended approach to resetting migration history using D...

django django-south
Rectangle 27 7

Like thnee (see her answer), we're using a gentler approach to the South author's (Andrew Godwin) suggestion quoted elsewhere here, and we're separating what we do with the code base from what we do to the database, during deployment, because we need the deployments to be repeatable:

What we do in the code:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

What we do to the database once that code is deployed

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

I think I just did the same thing, but manually deleting database entries, rather than using --delete_ghoist-migrations. Your way is a bit nicer.

What's the recommended approach to resetting migration history using D...

django django-south
Rectangle 27 4

Step 4. Add dependencies between the migrations.

The process I've currently settled on since I've been back here a few times and decided to formalise it.

# Caution: This finds OneToOneField and ForeignKey.
# I don't know if this finds all the ways of specifying ManyToManyField.
# Hopefully Django or South throw errors if you have a situation like that.
>>> Cat._meta.get_all_related_objects()
[<RelatedObject: common:toy related to cat>,
 <RelatedObject: identity:microchip related to cat>]

So in this extended case, we have discovered another related model like:

# Inside the "identity" app...
class Microchip(models.Model):

    # In reality we'd probably want a ForeignKey, but to show the OneToOneField
    identifies = models.OneToOneField(Cat)

    ...
# Create the "new"-ly renamed model
# Yes I'm changing the model name in my refactoring too.
python manage.py schemamigration specific create_kittycat --auto

# Drop the old model
python manage.py schemamigration common drop_cat --auto

# Update downstream apps, so South thinks their ForeignKey(s) are correct.
# Can skip models like Toy if the app is already covered
python manage.py schemamigration identity update_microchip_fk --auto

Makes it a more repeatable process if you run into merge conflicts like team mates writing migrations on the updated apps.

Basically create_kittycat depends on the current state of everything, and everything then depends on create_kittycat.

# create_kittycat
class Migration(SchemaMigration):

    ...

    # Hopefully for create_kittycat you only need to change the following
    # 4 strings to go forward cleanly... backwards will need a bit more work.
    old_app = 'common'
    old_model = 'cat'
    new_app = 'specific'
    new_model = 'kittycat'

    # You may also wish to update the ContentType.name,
    # personally, I don't know what its for and
    # haven't seen any side effects from skipping it.

    def forwards(self, orm):

        db.rename_table(
            '%s_%s' % (self.old_app, self.old_model),
            '%s_%s' % (self.new_app, self.new_model),
        )

        if not db.dry_run:
            # For permissions, GenericForeignKeys, etc to work properly after migrating.
            orm['contenttypes.contenttype'].objects.filter(
                app_label=self.old_app,
                model=self.old_model,
            ).update(
                app_label=self.new_app,
                model=self.new_model,
            )

        # Going forwards, should be no problem just updating child foreign keys
        # with the --auto in the other new South migrations

    def backwards(self, orm):

        db.rename_table(
            '%s_%s' % (self.new_app, self.new_model),
            '%s_%s' % (self.old_app, self.old_model),
        )

        if not db.dry_run:
            # For permissions, GenericForeignKeys, etc to work properly after migrating.
            orm['contenttypes.contenttype'].objects.filter(
                app_label=self.new_app,
                model=self.new_model,
            ).update(
                app_label=self.old_app,
                model=self.old_model,
            )

        # Going backwards, you probably should copy the ForeignKey
        # db.alter_column() changes from the other new migrations in here
        # so they run in the correct order.
        #
        # Test it! See Step 6 for more details if you need to go backwards.
        db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['common.Cat']))
        db.alter_column('identity_microchip', 'identifies_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['common.Cat']))


# drop_cat
class Migration(SchemaMigration):

    ...

    def forwards(self, orm):
        # Remove the db.delete_table(), if you don't at Step 7 you'll likely get
        # "django.db.utils.ProgrammingError: table "common_cat" does not exist"

        # Leave existing db.alter_column() statements here
        db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['specific.KittyCat']))

    def backwards(self, orm):
        # Copy/paste the auto-generated db.alter_column()
        # into the create_kittycat migration if you need backwards to work.
        pass


# update_microchip_fk
class Migration(SchemaMigration):

    ...

    def forwards(self, orm):
        # Leave existing db.alter_column() statements here
        db.alter_column('identity_microchip', 'identifies_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['specific.KittyCat']))

    def backwards(self, orm):
        # Copy/paste the auto-generated db.alter_column()
        # into the create_kittycat migration if you need backwards to work.
        pass
# the_one_before_create_kittycat
class Migration(SchemaMigration):

    # You many also need to add more models to South's FakeORM if you run into
    # more KeyErrors, the trade-off chosen was to make going forward as easy as
    # possible, as that's what you'll probably want to do once in QA and once in
    # production, rather than running the following many times:
    #
    # python manage.py migrate specific <the_one_before_create_kittycat>

    models = {
        ...
        # Copied from 'identity' app, 'update_microchip_fk' migration
        u'identity.microchip': {
            'Meta': {'object_name': 'Microchip'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
            'identifies': ('django.db.models.fields.related.OneToOneField', [], {to=orm['specific.KittyCat']})
        },
        ...
    }
python manage.py migrate

# If you need backwards to work
python manage.py migrate specific <the_one_before_create_kittycat>

migration - How do I migrate a model out of one django app and into a ...

django migration django-south
Rectangle 27 31

You can write anything as a migration. That's the point!

South
python manage.py schemamigration myapp --empty my_custom_migration

Open up the XXXX_my_custom_migration.py file in myapp/migrations/ and type in your custom SQL migration there in the forwards method. For example you could use db.execute

class Migration(SchemaMigration):

    def forwards(self, orm):
        db.execute("CREATE FULLTEXT INDEX foo ON bar (foobar)")
        print "Just created a fulltext index..."
        print "And calculated {answer}".format(answer=40+2)


    def backwards(self, orm):
        raise RuntimeError("Cannot reverse this migration.") 
        # or what have you


$ python manage.py migrate myapp XXXX # or just python manage.py migrate.
"Just created fulltext index...."
"And calculated 42"

mysql - Django south migration - Adding FULLTEXT indexes - Stack Overf...

mysql django migration django-south
Rectangle 27 127

Rails creates a table in your database called schema_migrations to keep track of which migrations have run.

The table contains a single column, version. When Rails runs a migration, it takes the leading digits in the migration's file name and inserts a row for that "version", indicating it has been run. If you roll back that migration, Rails will delete the corresponding row from schema_migrations.

For example, running a migration file named 20120620193144_create_users.rb will insert a new row with a version of 20120620193144 into the schema_migrations table.

You are free at any point to introduce migrations with earlier versions. Rails will always run any new migrations for which there is not a corresponding row in schema_migrations. The leading digits don't have to be a timestamp, you could call your migration 001_blah.rb. Earlier versions of Rails used this format, and used sequential numbering for newly generated migrations. Later versions have switched to timestamps to help prevent multiple developers from independently generating migrations with the same number.

Sorry to bump an old answer, but this really explained the "magic" behind migrations. I'm moving my rails database to a new server and spinning up a second instance of the app. I wondered how new migrations would be handled, this answered it. Kudos and thanks!

@cz3ch Typically you wouldn't run every migration,you'd use db:schema:restore to restore the entire database schema at once, from db/schema.rb.

Well in this instance I'm spinning up our existing rails app to a new server so I'm dumping the database from one postgres server to another which should retain the schema_migrations. I need to migrate all of the data from the production server to the new one and keep the schema_migrations table intact.

Especially useful when you are using a mix of a mountable engine and a dummy app

activerecord - How does Rails keep track of which migrations have run ...

ruby-on-rails activerecord
Rectangle 27 121

The Issue: You have mucked up your migrations and you would like to reset it without deleting your existing tables.

The Problem: You can't reset migrations with existing tables in the database as EF wants to create the tables from scratch.

You have now reset your migrations and may continue with normal migrations.

This is the only answer that worked for me. The accepted answer doesn't seem to address the issue of what happens when you run Update-Database or run your application (depending on what kind of initializer you're using). It will try to run the migration and try to make changes that already exist. Unless I'm missing something.

This should be the accepted answer. Works every time.

Reset Entity-Framework Migrations - Stack Overflow

entity-framework database-migration ef-migrations
Rectangle 27 20

At first, I thought that Fiver's method worked for me because the migration worked well until step 4. However, the implicit changes 'ForeignKeyField(Foo)' into 'ForeignKeyField(Bar)' was not related in any migrations. This is why migration failed when I wanted to rename relationship fields (step 5-8). This might be due to the fact that my 'AnotherModel' and 'YetAnotherModel' are dispatched in other apps in my case.

I adapted the method from this and particularly the trick of otranzer.

So like Fiver let's say we have in myapp:

class Foo(models.Model):
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)

Transform every OntToOneField(Foo) or ForeignKeyField(Foo) into IntegerField(). (This will keep the id of related Foo object as value of the integerfield).

class Bar(models.Model):  # <-- changed model name
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)

Transform Back your IntegerField() into their previous ForeignKeyField, OneToOneField but with the new Bar Model. (The previous integerfield was storing the id, so django understand that and reestablish the connection, which is cool.)

Very importantly, at this step you have to modify every new migrations and add the dependency on the RenameModel Foo-> Bar migrations. So if both AnotherModel and YetAnotherModel are in myotherapp the created migration in myotherapp must look like this:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '00XX_the_migration_of_myapp_with_renamemodel_foo_bar'),
        ('myotherapp', '00xx_the_migration_of_myotherapp_with_integerfield'),
    ]

    operations = [
        migrations.AlterField(
            model_name='anothermodel',
            name='foo',
            field=models.ForeignKey(to='myapp.Bar'),
        ),
        migrations.AlterField(
            model_name='yetanothermodel',
            name='foo',
            field=models.ForeignKey(to='myapp.Bar')
        ),
    ]
class AnotherModel(models.Model):
    bar = models.ForeignKey(Bar) <------- Renamed fields
    is_awesome = models.BooleanField()


class YetAnotherModel(models.Model):
    bar = models.ForeignKey(Bar) <------- Renamed fields
    is_ridonkulous = models.BooleanField()
python manage.py makemigrations

(django should ask you if you actually renamed the modelname, say yes)

python manage.py migrate

Thank you! That was extremely helpful. But a note - I also had to rename and/or remove PostgreSQL field indexes by hand because, after renaming Foo to Bar, I created a new model named Bar.

Thank you for this! I think that the key part is converting all foreign keys, in or out of the model to be renamed, to IntegerField. This worked perfectly for me, and has the added advantage that they get recreated with the correct name. Naturally I would advise reviewing all migrations before actually running them!

Django migration strategy for renaming a model and relationship fields...

django django-migrations
Rectangle 27 211

Further to a migration of my Xcode project, from Xcode 6.4 to Xcode 7, I get the warning message below (after compilation) for the Test target :

directory not found for option '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.0.sdk/Developer/Library/Frameworks'

Actually I found something when comparing a new project vs an older one...

In the old project, the warning was only being produced by the test target of my projects. Under 'Search Paths', I found it was including two items under 'Framework Search Paths':

$(SDKROOT)/Developer/Library/Frameworks
$(inherited)

Deleting those entries in my older project then removed the warning.

I have not exhaustively compared settings, so there may be additional differences.

Also, just in case if one day you re-encounter one of the two following warning messages, just remember that you will have to do that: if the warning is for option '-L/...' that is Library Search Paths, delete the stuff there. However if the warning is for option '-F/...' that is Framework Search Paths, delete the stuff there.

The above is correct. However, if you use CocoaPods, I found that it's also possible for the entry to reside in the *.xcconfig files it creates. Solution is identical: remove it, in this case from the FRAMEWORK_SEARCH_PATHS line in your *.xcconfig file(s).

I have the exact same problem (-F/...) and I already deleted the stuff in Framework Search Paths, but the warning is still showing up.

Clean and re-build the Xcode project and the warning message should disappear.

xcode7 - Xcode 7 Library search path warning - Stack Overflow

xcode xcode7
Rectangle 27 208

Further to a migration of my Xcode project, from Xcode 6.4 to Xcode 7, I get the warning message below (after compilation) for the Test target :

directory not found for option '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.0.sdk/Developer/Library/Frameworks'

Actually I found something when comparing a new project vs an older one...

In the old project, the warning was only being produced by the test target of my projects. Under 'Search Paths', I found it was including two items under 'Framework Search Paths':

$(SDKROOT)/Developer/Library/Frameworks
$(inherited)

Deleting those entries in my older project then removed the warning.

I have not exhaustively compared settings, so there may be additional differences.

Also, just in case if one day you re-encounter one of the two following warning messages, just remember that you will have to do that: if the warning is for option '-L/...' that is Library Search Paths, delete the stuff there. However if the warning is for option '-F/...' that is Framework Search Paths, delete the stuff there.

The above is correct. However, if you use CocoaPods, I found that it's also possible for the entry to reside in the *.xcconfig files it creates. Solution is identical: remove it, in this case from the FRAMEWORK_SEARCH_PATHS line in your *.xcconfig file(s).

I have the exact same problem (-F/...) and I already deleted the stuff in Framework Search Paths, but the warning is still showing up.

Clean and re-build the Xcode project and the warning message should disappear.

xcode7 - Xcode 7 Library search path warning - Stack Overflow

xcode xcode7
Rectangle 27 61

Rolling back a migration and re-editing it is only safe if that migration is local and has not been pushed out to any repository. Editing a migration that others have applied may cause issues.

rails g migration add_public_and_private_to_document public:string private:string

If you use the add_[column_names]_to_[model] naming convention, rails will work out the appropriate table and create the migration you want.

ruby on rails 3 - Adding multiple columns in one migration - Stack Ove...

ruby-on-rails-3 migration
Rectangle 27 17

I just had a similar issue with my app, I got the issue after a migration of the DB, after trying many options, the one that helped me was this:

heroku restart

I was getting the same error code and mine used to work but this all of a sudden started happening. The "heroku restart" command cleared this up for me.

node.js - First Heroku deploy failed `error code=H10` - Stack Overflow

node.js heroku express
Rectangle 27 7

For the migration of old data part, I've done some work.

  • how to check old db exist or not, I use below code to check. if ([fileManager fileExistsAtPath:[storeURL path]]) { NSLog(@"old single app db exist."); targetURL = storeURL; needMigrate = true; } // storeURL is the store url return by: - (NSURL *)applicationDocumentsDirectory { return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; }

If the old data store exist, and the group data store not exist, I use below code do the migrate:

if (needMigrate) {
    NSError *error = nil;
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [context setPersistentStoreCoordinator:__persistentStoreCoordinator];
    [__persistentStoreCoordinator migratePersistentStore:store toURL:groupURL options:options withType:NSSQLiteStoreType error:&error];
    if (error != nil) {
        NSLog(@"Error when migration to groupd url %@, %@", error, [error userInfo]);
        abort();
    }
}

the needMigrate flag is set by checking if old data exist.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
       return __persistentStoreCoordinator;
    }

bool needMigrate = false;
bool needDeleteOld  = false;

NSString *kDbName = @"xxx.sqlite";

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:kDbName];

NSURL *groupURL = [[self applicationGroupDocumentDirectory] URLByAppendingPathComponent:kDbName];

NSURL *targetURL =  nil;

NSFileManager *fileManager = [NSFileManager defaultManager];

if ([fileManager fileExistsAtPath:[storeURL path]]) {
    NSLog(@"old single app db exist.");
    targetURL = storeURL;
    needMigrate = true;
}


if ([fileManager fileExistsAtPath:[groupURL path]]) {
       NSLog(@"group db exist");
       needMigrate = false;
       targetURL = groupURL;

    if ([fileManager fileExistsAtPath:[storeURL path]]) {
        needDeleteOld = true;
    }
}

if (targetURL == nil)
    targetURL = groupURL;

NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @(YES),
                            NSInferMappingModelAutomaticallyOption: @(YES)};

NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];


NSPersistentStore *store;
store = [__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:targetURL options:options error:&error];

if (!store)
{
    /*
     Replace this implementation with code to handle the error appropriately.

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

     Typical reasons for an error here include:
     * The persistent store is not accessible;
     * The schema for the persistent store is incompatible with current managed object model.
     Check the error message to determine what the actual problem was.


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

     If you encounter schema incompatibility errors during development, you can reduce their frequency by:
     * Simply deleting the existing store:
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
     [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.

     */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

// do the migrate job from local store to a group store.
if (needMigrate) {
    NSError *error = nil;
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [context setPersistentStoreCoordinator:__persistentStoreCoordinator];
    [__persistentStoreCoordinator migratePersistentStore:store toURL:groupURL options:options withType:NSSQLiteStoreType error:&error];
    if (error != nil) {
        NSLog(@"Error when migration to groupd url %@, %@", error, [error userInfo]);
        abort();
    }
}

return __persistentStoreCoordinator;
}

/**
 Returns the URL to the application's Documents directory.
 */
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSURL *)applicationGroupDocumentDirectory
{
return [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.kzjeef.shitf.scheduler"];
}

In swift, by default, persistentStoreCoordinator is created as a lazy var, that seems to cause this code to run a hundred times. Where it tries to open the files to check their existence and eventually errors out "too many files open"

ios - coredata - move to app group target - Stack Overflow

ios core-data ios8-today-widget
Rectangle 27 16

What you are doing when you setting :rails_env, "staging" environment is setting the environment for the migration. In other words, it's a environment that is only set when you're running capistrano. If I understand you correctly, you want to change the environment when running your app, not deploying.

Given that you're in a shared environment, you'll probably want to go with the .htaccess route.

I don't start it as such, phusion passenger handles that.

Ah, good to know. You'll need to edit your RAILS_ENV for Passenger. Read this: modrails.com/documentation/ Given that you're in a shared environment, you'll probably want to go with the .htaccess route.

deployment - Setting the Ruby on Rails application environment using C...

ruby-on-rails deployment passenger capistrano
Rectangle 27 12

If you really want to rollback all of the migrations, and not just take the database to a pristine state or to the last schema, you have to run:

rake db:migrate VERSION=0

This will actually rollback all the way down every migration and ensure that every migration is reversible.

rake db:migrate:status

you will see that all the migrations are still there but they are in a 'down' (not applied) state.

Other commands that imply a rake db:reset or rake db:drop (such as in the answers by @Orlando or @Alex Falke) won't do any rollback at all: that is, they won't ensure that every migration is reversible.

Moreover, rake db:drop cannot be run while the database is being accessed by other users, while rollbacks can be performed live (even if this is generally not recommended). And last but not least, simply dropping and recreating the database will also delete the schema migrations table: if someone runs rake db:migrate:status after the database has been dropped, he will be replied with "Schema migrations table does not exist yet" and will have no clues about which migrations can be applied (unless he knows it yet or can list them).

ruby on rails - Rake db:migrate - how do I undo all migrations and red...

ruby-on-rails database ruby-on-rails-3 migration
Rectangle 27 446

You'll probably want to use a DECIMAL type in your database. In your migration, do something like this:

# precision is the total number of digits
# scale is the number of digits to the right of the decimal point
add_column :items, :price, :decimal, :precision => 8, :scale => 2

In Rails, the :decimal type is returned as BigDecimal, which is great for price calculation.

If you insist on using integers, you will have to manually convert to and from BigDecimals everywhere, which will probably just become a pain.

As pointed out by mcl, to print the price, use:

number_to_currency(price, :unit => "")
#=> 1,234.01

Actually, it's much safer and easier to use an integer in combination with acts_as_dollars. Have you ever been bitten by floating-point comparison? If not, don't make this your first experience. :) With acts_as_dollars, you put stuff in in 12.34 format, it's stored as 1234, and it comes out as 12.34.

It's important not to just copy this answer blindly - precision 8, scale 2 gives you a maximum value of 999,999.99. If you need a number greater than a million then increase the precision!

It's also important to not just blindly use a scale of 2 if you're handling different currencies some north-african and arab currencies like the Omani Rial or the Tunisian Dinar have a scale of 3, so precision 8 scale 3 is more appropriate there.

ruby on rails - What is the best method of handling currency/money? - ...

ruby-on-rails ruby currency
Rectangle 27 445

You'll probably want to use a DECIMAL type in your database. In your migration, do something like this:

# precision is the total number of digits
# scale is the number of digits to the right of the decimal point
add_column :items, :price, :decimal, :precision => 8, :scale => 2

In Rails, the :decimal type is returned as BigDecimal, which is great for price calculation.

If you insist on using integers, you will have to manually convert to and from BigDecimals everywhere, which will probably just become a pain.

As pointed out by mcl, to print the price, use:

number_to_currency(price, :unit => "")
#=> 1,234.01

Actually, it's much safer and easier to use an integer in combination with acts_as_dollars. Have you ever been bitten by floating-point comparison? If not, don't make this your first experience. :) With acts_as_dollars, you put stuff in in 12.34 format, it's stored as 1234, and it comes out as 12.34.

It's important not to just copy this answer blindly - precision 8, scale 2 gives you a maximum value of 999,999.99. If you need a number greater than a million then increase the precision!

It's also important to not just blindly use a scale of 2 if you're handling different currencies some north-african and arab currencies like the Omani Rial or the Tunisian Dinar have a scale of 3, so precision 8 scale 3 is more appropriate there.

ruby on rails - What is the best method of handling currency/money? - ...

ruby-on-rails ruby currency
Rectangle 27 43

You could copy and paste schema.rb into a migration and back-date it (e.g. change the date) so that no existing databases will run it. After you create this migration you can delete all your old migrations.

I disagree with Andrew that you should never delete migrations. Migrations break unexpectedly all the time based on model classes changing and it is very non-trivial to fix them. Since I'm sure you are using version control, you can always look back in the history if you need them for reference.

I humbly suggest that migrations should not depend on model classes, or they will be guaranteed to break over time as your models change. If you need the power of a model, you can include a simplistic, disposable model definition in the migration itself.

While nice in principle, this is hard to enforce in practice.

@ghempton, thank you for actually answering the question as written instead of saying, "there is no need to do this". There are always needs and reasons to do something with which others may disagree.

I inserted the timestamp part of the rails migration file directly into the 'schema_migrations' table under column 'version' for the server I did not need to run the migration created from the schema.

ruby on rails - Generate a migration file from schema.rb - Stack Overf...

ruby-on-rails ruby ruby-on-rails-3 migration
Rectangle 27 47

South is more than able to do this migration for you, but you need to be smart and do it in stages. Here's the step-by-step guide: (This guide presupposed you subclass AbstractUser, not AbstractBaseUser)

Before making the switch, make sure that south support is enabled in the application that contains your custom user model (for the sake of the guide, we'll call it accounts and the model User). At this point you should not yet have a custom user model.

$ ./manage.py schemamigration accounts --initial
Creating migrations directory at 'accounts/migrations'...
Creating __init__.py in 'accounts/migrations'...
Created 0001_initial.py.

$ ./manage.py migrate accounts [--fake if you've already syncdb'd this app]
 Running migrations for accounts:
 - Migrating forwards to 0001_initial.
 > accounts:0001_initial
 - Loading initial data for accounts.
  • Create a new, blank user migration in the accounts app. $ ./manage.py schemamigration accounts --empty switch_to_custom_user Created 0002_switch_to_custom_user.py.

Create your custom User model in the accounts app, but make sure it is defined as:

class SiteUser(AbstractUser): pass
  • Fill in the blank migration with the following code. # encoding: utf-8 from south.db import db from south.v2 import SchemaMigration class Migration(SchemaMigration): def forwards(self, orm): # Fill in the destination name with the table name of your model db.rename_table('auth_user', 'accounts_user') db.rename_table('auth_user_groups', 'accounts_user_groups') db.rename_table('auth_user_user_permissions', 'accounts_user_user_permissions') def backwards(self, orm): db.rename_table('accounts_user', 'auth_user') db.rename_table('accounts_user_groups', 'auth_user_groups') db.rename_table('accounts_user_user_permissions', 'auth_user_user_permissions') models = { ....... } # Leave this alone
  • Run the migration $ ./manage.py migrate accounts - Migrating forwards to 0002_switch_to_custom_user. > accounts:0002_switch_to_custom_user - Loading initial data for accounts.
# settings.py
AUTH_USER_MODEL = 'accounts.User'

# accounts/models.py
class SiteUser(AbstractUser):
    site = models.ForeignKey(Site, null=True)
  • create and run migrations for this change $ ./manage.py schemamigration accounts --auto + Added field site on accounts.User Created 0003_auto__add_field_user_site.py. $ ./manage.py migrate accounts - Migrating forwards to 0003_auto__add_field_user_site. > accounts:0003_auto__add_field_user_site - Loading initial data for accounts.

Honestly, If you already have good knowledge of your setup and already use south, It should be as simple as adding the following migration to your accounts module.

# encoding: utf-8
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Fill in the destination name with the table name of your model
        db.rename_table('auth_user', 'accounts_user')
        db.rename_table('auth_user_groups', 'accounts_user_groups')
        db.rename_table('auth_user_permissions', 'accounts_user_permissions')
        # == YOUR CUSTOM COLUMNS ==
        db.add_column('accounts_user', 'site_id',
            models.ForeignKey(orm['sites.Site'], null=True, blank=False)))

    def backwards(self, orm):
        db.rename_table('accounts_user', 'auth_user')
        db.rename_table('accounts_user_groups', 'auth_user_groups')
        db.rename_table('accounts_user_user_permissions', 'auth_user_user_permissions')
        # == YOUR CUSTOM COLUMNS ==
        db.remove_column('accounts_user', 'site_id')

    models = { ....... } # Leave this alone

EDIT 2/5/13: added rename for auth_user_group table. FKs will auto update to point at the correct table due to db constraints, but M2M fields' table names are generated from the names of the 2 end tables and will need manual updating in this manner.

Enjoy your bounty! I ended up doing this with dumpdata/loaddata (and manipulating the dumped data in between) and it worked simply but this would have certainly worked had I had this understanding a bit earlier.

It was a "problem" with the frozen orm from 0002 -- it needs an 'accounts.user' entry so south won't think that model is new for the next migration. I did the schemamigration --auto, copied the 'accounts.user' entry from 0003 to 0002, deleted 0003 and re-created it, now all it wants to do is update the FKs. +1

aren't auth_user_groups and auth_user_permissions to be migrated too?

I think the example still misses renaming the auth_user_user_permissions table. Anyway it's the best 1.5 user model migration guide I found so far.

@eternicode: Hint, the copy-from 0003 creation can be generated with --stdout so no real file is created and does not need to be deleted.

postgresql - Migrating existing auth.User data to new Django 1.5 custo...

django postgresql django-south django-1.5
Rectangle 27 23

There's a change_column method, just execute it in your migration with datetime as a new type.

change_column(:my_table, :my_column, :my_new_type)

does this preserve the original data?

mysql - Change a column type from Date to DateTime during ROR migratio...

mysql ruby-on-rails ruby ruby-on-rails-3 migration
Rectangle 27 33

When Rails serializes a hash to save in the db, all it does is convert it to YAML so that it can be stored as a string. To get this to work in the migration, all you need to do is convert the hash to yaml...

t.string :dimensions_in, :default => {:width => 0, :height => 0, :depth => 0}.to_yaml

Or, alternatively, set it in the model after initialization...

class ShippingProfile < ActiveRecord::Base

  after_initialize :set_default_dimensions

  private

    def set_default_dimensions
      self.dimensions_in ||= {:width => 0, :height => 0, :depth => 0}
    end

end

great to know about the yaml trick in migrations as well, thanks!

Unfortunately in my case this won't work. I'm using MySQL and a text field type and the combination won't support a default value.

Be wary of after_initialize solutions as you might incur significant performance overhead when instantiating lots of objects such as from an ActiveRecord finder query. The most performant approach is to overwrite the accessor as detailed by @DragonStar - although see my comment to get it to work for serialized attributes.

ruby on rails - default for serialized column in activerecord migratio...

ruby-on-rails activerecord migration