I work on a team of about 5 committers Rails project in a git repo. We often run in to issues with migrations that have run in one branch and not another, or migrations that have run on deploy that aren''t automatically ran down when we roll back our production server to an older version. I think the problem could potentially be resolved if the database stored the code to run the down method of a migration along with the list of migrations that have run. On rake db:migrate, if a migration is missing, it could prompt (or accept an option) to automatically run the down method for the missing migrations. I''d be happy to implement this, the only potential issue I see is the down method in the db getting out of date with the code in the migration file, but maybe that''s not much of an issue. Feedback? Steve
> I think the problem could potentially be resolved if the database > stored the code to run the down method of a migration along with the > list of migrations that have run. On rake db:migrate, if a migration > is missing, it could prompt (or accept an option) to automatically run > the down method for the missing migrations.That''d work only for cases where your down migrations *only* change the schema, they don''t touch models or any other ruby code. Otherwise there''s no guarantee that those models are available when the system tries to downgrade. Why can''t you run the down migration before rolling back the code? That''s the only reliable way you''ll be able to do this. -- Cheers Koz
On Tue, Sep 8, 2009 at 2:01 PM, Michael Koziarski <michael@koziarski.com> wrote:> That''d work only for cases where your down migrations *only* change > the schema, they don''t touch models or any other ruby code. Otherwise > there''s no guarantee that those models are available when the system > tries to downgrade.Doesn''t this same problem exist always - whether you are going down or up, or store your migrations in files or the database? Some would consider it an antipattern to put any models or app classes in your migrations. I''m still not clear on the original poster''s root problem and solution, but I don''t think the possibility of outdated non-schema migration code is a good reason to reject the idea. -- Chad
I see sublime elegance in having the DB store the DDL to revert migrations. I haven''t worked with large teams in years, but I see the dilemma Steven is addressing: The common DB is at Rev N User (or branch) A migrates common DB up to Rev N + 1 User (or branch) B is "checked out" and expects common DB to be at Rev N. Result: User/branch B is stuck: code to rollback the DB to Rev N exists only in User/branch A. Sorry if that was obvious to most, but I needed to clarify at least one scenario where this technique could be useful. On Sep 8, 1:23 pm, Steven Soroka <ssorok...@gmail.com> wrote:> I work on a team of about 5 committers Rails project in a git repo. > We often run in to issues with migrations that have run in one branch > and not another, or migrations that have run on deploy that aren''t > automatically ran down when we roll back our production server to an > older version. > > I think the problem could potentially be resolved if the database > stored the code to run the down method of a migration along with the > list of migrations that have run. On rake db:migrate, if a migration > is missing, it could prompt (or accept an option) to automatically run > the down method for the missing migrations. > > I''d be happy to implement this, the only potential issue I see is the > down method in the db getting out of date with the code in the > migration file, but maybe that''s not much of an issue. > > Feedback? > > Steve
On Wed, Sep 9, 2009 at 5:03 AM, Chris <cch1@hapgoods.com> wrote:> > I see sublime elegance in having the DB store the DDL to revert > migrations. I haven''t worked with large teams in years, but I see the > dilemma Steven is addressing: > > The common DB is at Rev N > User (or branch) A migrates common DB up to Rev N + 1 > User (or branch) B is "checked out" and expects common DB to be at Rev > N. > Result: User/branch B is stuck: code to rollback the DB to Rev N > exists only in User/branch A.In this case, I would say that user (or branch) B should not be running outdated code against the ''common'' database at Rev N +1. The +1 migration probably had some associated code changes to support the schema changes, and if user/branch B does not have that code yet, they shouldn''t be running against that database. Either use a separate database, or cherry-pick the migration and associated changes from branch A. I think the concept of a "common" DB is the root problem here. Each developer should have their own DB in development, and in demo/staging/production, you should only be running a single branch (preferably a tag of a green CI build) against the DB at any given time. -- Chad
Since database.yml gets ERB''d, I''ve seen a trick where the database name is lazy evaluated w/ the output from a git branch command. This way each branch has a seperate DB. There is a bit of manual work involved to make sure you create the database each time you create a new branch, but that''s solvable with a shell alias (or rake task) that creates the branch and DB for you. -Ryan On Wed, Sep 9, 2009 at 12:19 PM, Chad Woolley <thewoolleyman@gmail.com>wrote:> > On Wed, Sep 9, 2009 at 5:03 AM, Chris <cch1@hapgoods.com> wrote: > > > > I see sublime elegance in having the DB store the DDL to revert > > migrations. I haven''t worked with large teams in years, but I see the > > dilemma Steven is addressing: > > > > The common DB is at Rev N > > User (or branch) A migrates common DB up to Rev N + 1 > > User (or branch) B is "checked out" and expects common DB to be at Rev > > N. > > Result: User/branch B is stuck: code to rollback the DB to Rev N > > exists only in User/branch A. > > In this case, I would say that user (or branch) B should not be > running outdated code against the ''common'' database at Rev N +1. The > +1 migration probably had some associated code changes to support the > schema changes, and if user/branch B does not have that code yet, they > shouldn''t be running against that database. Either use a separate > database, or cherry-pick the migration and associated changes from > branch A. I think the concept of a "common" DB is the root problem > here. Each developer should have their own DB in development, and in > demo/staging/production, you should only be running a single branch > (preferably a tag of a green CI build) against the DB at any given > time. > > -- Chad > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
> Doesn''t this same problem exist always - whether you are going down or > up, or store your migrations in files or the database? Some would > consider it an antipattern to put any models or app classes in your > migrations.Some would be wrong if they considered that an anti pattern ;). The vast bulk of migrations in my projects are model-dependent for things like cleaning up a data problem in production, initialising counter fields based on non-sql-calculatable fields (e.g. API calls) If you store the migrations in your version control system you can recover the state of the migrations at any point in time. For a particularly tricky down migration you can always step back revisiion by revision. The database would have no such history and could never provide the same level of fidelity or reliability that your SCM can.> I''m still not clear on the original poster''s root problem and > solution, but I don''t think the possibility of outdated non-schema > migration code is a good reason to reject the idea.The specific case mentioned was rolling back when the checkout is at an older version and doesn''t have the down migration. The solution there is to rollback from the original revision. If there''s another case I''d be happy to re-evaluate but the power of migrations is in their simplicity they''re not some darcs-ish patch algebra for DDL, they''re little scripts that you run in order in which you can do whatever you want. -- Cheers Koz
On Wed, Sep 9, 2009 at 6:31 PM, Michael Koziarski<michael@koziarski.com> wrote:> >> Doesn''t this same problem exist always - whether you are going down or >> up, or store your migrations in files or the database? Some would >> consider it an antipattern to put any models or app classes in your >> migrations. > > Some would be wrong if they considered that an anti pattern ;). The > vast bulk of migrations in my projects are model-dependent for things > like cleaning up a data problem in production, initialising counter > fields based on non-sql-calculatable fields (e.g. API calls)My normal practice when writing migrations which depend on model code is to put a migration specific model clase in the migration file itself, scoped inside the migration. The model mimics a subset of the one in app/models including only necessary attribute declarations and methods.> If you store the migrations in your version control system you can > recover the state of the migrations at any point in time. For a > particularly tricky down migration you can always step back revisiion > by revision. The database would have no such history and could never > provide the same level of fidelity or reliability that your SCM can.Absolutely true. And the technique I described decouples the running of migrations from the current state of the models, which facilitates recovering the state of the migrations without requiring incremental steps of get a revision, run migrations, get the next revision run migrations... if that makes sense.>> I''m still not clear on the original poster''s root problem and >> solution, but I don''t think the possibility of outdated non-schema >> migration code is a good reason to reject the idea. > > The specific case mentioned was rolling back when the checkout is at > an older version and doesn''t have the down migration. The solution > there is to rollback from the original revision.I have to say that I never understood the proposed solution, frankly it scared the bejesus out of me, but maybe that''s just me.> If there''s another case I''d be happy to re-evaluate but the power of > migrations is in their simplicity they''re not some darcs-ish patch > algebra for DDL, they''re little scripts that you run in order in which > you can do whatever you want. >Amen -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale
On Wed, Sep 9, 2009 at 4:02 PM, Rick DeNatale <rick.denatale@gmail.com> wrote:> My normal practice when writing migrations which depend on model code > is to put a migration specific model clase in the migration file > itself, scoped inside the migration. The model mimics a subset of the > one in app/models including only necessary attribute declarations and > methods.Great idea, thanks...
On Sep 9, 2009, at 5:56 PM, Chad Woolley wrote:> On Wed, Sep 9, 2009 at 4:02 PM, Rick DeNatale > <rick.denatale@gmail.com> wrote: >> My normal practice when writing migrations which depend on model code >> is to put a migration specific model clase in the migration file >> itself, scoped inside the migration. The model mimics a subset of >> the >> one in app/models including only necessary attribute declarations and >> methods. > > Great idea, thanks...This is also great way to define "don''t exist anymore" associations - so you can rely on them being there for that migration whether they exist or not in your actual models. Just make sure to heed Rick''s advice and put it inside your migration, otherwise dark spirits will come and steal your soul while you sleep. -- Jason