datamapper / dm-migrations Goto Github PK
View Code? Open in Web Editor NEWDataMapper plugin for writing and speccing migrations
Home Page: http://datamapper.org/
License: MIT License
DataMapper plugin for writing and speccing migrations
Home Page: http://datamapper.org/
License: MIT License
I'm not sure if things should work this way, but when a model is subclassed and the descendent model changes self.storage_names it will still update the parent model when calling auto_migrate/auto_upgrade.
example: http://gist.github.com/303755
I attached a patch but I'll leave up to you guys if it's something that needs to be changed :)
Created by Kabari - 2010-02-14 01:14:47 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1198
This makes it difficult to use dm-migrations with non-SQL based databases.
Created by Postmodern - 2010-06-19 00:36:44 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1333
My migration looks like:
migration 1, :modify_url_length do
up do
modify_table :hotels do
change_column :url, String, :length => 1..255
end
end
down do
modify_table :hotels do
change_column :url, String, :length => 1..255
end
end
end
However, the migration fails with the error: ERROR: syntax error at or near "VARCHAR".
Seems to me that the SQL being ran is:
ALTER TABLE "hotels" ALTER COLUMN "url" VARCHAR(1 AND 255)
when it needs to be
ALTER TABLE "hotels" ALTER COLUMN "url" TYPE VARCHAR(1 AND 255)
The default syntax used to rename a column is not compatible with MySQL. From the docs it should instead be
ALTER TABLE tbl_name CHANGE [COLUMN] old_col_name new_col_name column_definition
Created by Phil - 2008-12-01 06:38:33 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/680
This was resolved once and came back: http://datamapper.lighthouseapp.com/projects/20609/tickets/1410-dm-migrations-dm-mysql-adapter-undefined-method
This monkey patch still fixes the problem:
repository.adapter.class.class_eval do
def show_variable(name)
select('SELECT variable_value FROM information_schema.session_variables WHERE LOWER(variable_name) = ?', name).first
end
end
Hi,
Not sure if this is an issue with dm-migrations or dm-sqlserver-adapter but db:autoupgrade
is using double quotes instead of single:
> rake db:autoupgrade
(in C:/Work/myproject/src/myapp)
~ [datamapper] Setting up the "development" environment:
~ [datamapper] Setting up :default repository: 'MY_DB;instance=SQL' on sqlserver
~ Invalid column name 'table'. (code: 207, sql state: 42S22, query: SELECT c.name FROM sysobjects as o JOIN syscolumns AS c ON o.id = c.id WHERE o.name = "table" AND c.name LIKE 'id', uri: )
~ Invalid column name 'table'. (code: 207, sql state: 42S22, query: SELECT c.name FROM sysobjects as o JOIN syscolumns AS c ON o.id = c.id WHERE o.name = "table" AND c.name LIKE 'id', uri: )
rake aborted!
Invalid column name 'table'.
Cheers,
Corin
To reproduce:
Result:
ERROR - [25/Mar/2011 18:14:56] "ORA-01758: table must be empty to add mandatory (NOT NULL) column
(code: 1758, sql state: 42000, query: ALTER TABLE "LOCATIONS" ADD "TITLE" VARCHAR2(100) NOT NULL, uri: )"
rake aborted!
ORA-01758: table must be empty to add mandatory (NOT NULL) column
@Raimonds I believe this is an inherent limitation of Oracle?
Created by Alex Coles - 2011-03-25 17:13:49 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1499
I started my project using sqlite, and now it's starting to struggle.
What the method to migrate to PostgreSQL, I'm using the same models, but I have data that needs to be moved.
I'm willing to pay Bitcoin to the person who finds the answer to this issue.
When using auto_upgrade! length is not taken into account.
It can be non destructively upgraded under PostgreSQL (I do not know about other dbs) using ALTER TABLE ALTER TYPE.
I attach an example which shows the problem.
Created by Roman - 2009-06-17 07:48:03 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/908
Hey,
I have app using mysql and mongo adapters and when I try to run auto_upgrade it gives following error:
Created by Marcin Kulik - 2010-06-05 11:51:38 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1305
For example:
DataMapper.setup(:x, :adapter => 'sqlite', :database=> ':memory:')
DataMapper.repository(:x).auto_migrate!
outputs only:
~ (0.000229) PRAGMA table_info("servers")
~ (0.000023) PRAGMA table_info("customers")
~ (0.204847) SET sql_auto_is_null = 0
~ (0.206043) SET SESSION sql_mode = 'ANSI,NO_BACKSLASH_ESCAPES,NO_DIR_IN_CREATE,NO_ENGINE_SUBSTITUTION,NO_UNSIGNED_SUBTRACTION,TRADITIONAL'
Doesn't really upgrade anything.
There is example code that shows how to write and run specs for migrations. Unfortunately the code uses some custom hack lib/spec/example/migration_example_group.rb that is not made available to the Gem in general and hence users cannot use it.
I am not exactly sure how to go about resolving this. If there are any pointers, would be happy to send a pull request.
I Tried
class A
include DataMapper::Resource
property :id, Serial
property :no_recipes_with, Object, default: ""
end
and when autoupgrade :
rake db:autoupgrade
rake aborted!
BLOB/TEXT column 'no_recipes_with' can't have a default value
(mysql)
But if I remove the default value, upgrade the database, and put the default value again back, it works.
Wouldn't be a better fall back if it uses de default value in model objects in this cases?
Or I'm not supposed to use default value if upgrade fails?
How to reproduce...
Give a Postgres database in a Sinatra app using DataMapper and auto_upgrade! is not called when the application starts up.
Given the following new Model:
class MyModel
include DataMapper::Resource
property :id, Serial
property :name, String
end
The following call to DataMapper...
MyModel!.auto_upgrade!
will execute the following, correct sql against the Postgres database.
CREATE TABLE "my_models" ("id" SERIAL NOT NULL, "name" VARCHAR(50), PRIMARY KEY("id"))
However, if you create a migration and call auto_upgrade from the migration like the following...
migration '20110908-103200', :create_my_model do
up do
MyModel.auto_upgrade!
end
down do
end
end
then the following, incorrect SQL is executed against the Postgres database...
CREATE TABLE "my_models" ( SERIAL PRIMARY KEY, "name" VARCHAR(50), PRIMARY KEY("id"))
which produces the following error...
~ ERROR: syntax error at or near "PRIMARY"
LINE 1: CREATE TABLE "my_models" ( SERIAL PRIMARY KEY, "name" VARCHA...
SERIAL PRIMARY KEY should be preceded by "id" and PRIMARY KEY("id") should be removed if the primary key is to be set in that style. The correct SQL above creates the id column and sets the primary key in two separate places.
Correct SQL from above:
CREATE TABLE "my_models" ("id" SERIAL NOT NULL, "name" VARCHAR(50), PRIMARY KEY("id"))
What I found out from debugging...
When the code is run in a migration setup! in migration.rb cause SQL::Postgres module to extend the adapter (See line 294). property_schema_statement method is overwritten to create this different primary key statement using SERIAL PRIMARY KEY. It relies, however, on schema[:quote_column_name] which isn't set in this case. That value is only set in table_creator.rb which isn't called in this case.
Question...
Why do we need a different create table syntax for the migrations? If the existing data mapper adapter syntax is used for postgres then everything works just fine. Would it be possible to delete the property_schema_statement in postgres.rb and have everything work?
Workaround...
When I call DataMapper.auto_upgrade! from our Sinatra rb file, then the migration runs through. I think this is what you're supposed to do anyway. That's probably why no one else has reported this yet.
Thanks for your help.
I have a model like the following
class Task
include DataMapper::Resource
property :id, Serial
has n, :things
end
I run automigrate and this table syncs fine. I change it to the following:
class Task
include DataMapper::Resource
property :id, Serial
has n, :things, :required => false
end
And autoupgrade fails on a hard to parse error.
(in /home/me/xyz)
DataMapper::Sweatshop::Unique - ParseTree could not be loaded, anonymous uniques will not be allowed
rake aborted!
Cannot add a NOT NULL column with default value NULL
(See full trace by running task with --trace)
AFAIK I am not changing the column to "NOT NULL". In fact I am changing it to allow null values, not remove them.
Other migration engines (such as South) handle this change pretty gracefully.
Attempted running the dm-migrations specs against mysql. Instead I received the following exception multiple times:
DataObjects::SQLError in 'DataMapper::Migrations with default adapter#auto_migrate NumericString property before(:all)' You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PRIMARY KEY, `number` VARCHAR(50) DEFAULT '0', PRIMARY KEY(`id`)) ENGINE = MyISA' at line 1 /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/adapters/dm-do-adapter.rb:100:in `execute_non_query' /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/adapters/dm-do-adapter.rb:100:in `block (2 levels) in create_model_storage' /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/adapters/dm-do-adapter.rb:98:in `each' /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/adapters/dm-do-adapter.rb:98:in `block in create_model_storage' /home/hal/.rvm/gems/ruby-1.9.3-p0/bundler/gems/dm-do-adapter-d295d77f3e4b/lib/dm-do-adapter/adapter.rb:276:in `with_connection' /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/adapters/dm-do-adapter.rb:93:in `create_model_storage' /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/auto_migration.rb:81:in `create_model_storage' /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/auto_migration.rb:177:in `auto_migrate_up!' /vault/1/code/forks/dm/dm-migrations/lib/dm-migrations/auto_migration.rb:132:in `auto_migrate!' spec/integration/auto_migration_spec.rb:300:in `block (6 levels) in ' spec/integration/auto_migration_spec.rb:8:in `capture_log' spec/integration/auto_migration_spec.rb:300:in `block (5 levels) in ' 747 examples, 158 failures, 4 pending
I kept running into this bug in a dm-rails app where explicit migrations could not resolve Property constants under Ruby 1.8.7, but work as expected under 1.9.2.
rails new dm-bug -m http://datamapper.org/templates/rails.rb
Add an explicit migration:
migration 1, :create_users do
up do
create_table :users do
column :id, Serial
column :name, String
column :bio, Text
end
end
down do
drop_table :users
end
end
rake db:migrate:up
$ rake db:migrate:up --trace ** Invoke db:migrate:up (first_time) ** Invoke db:migrate:load (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute db:migrate:load ** Execute db:migrate:up == Performing Up Migration #1: create_users rake aborted! uninitialized constant Serial ./db/migrate/001_create_users.rb:4:in `(root)' /home/hal/.rvm/gems/jruby-1.6.4/gems/dm-migrations-1.1.0/lib/dm-migrations/sql/table_creator.rb:17:in `instance_eval' /home/hal/.rvm/gems/jruby-1.6.4/gems/dm-migrations-1.1.0/lib/dm-migrations/sql/table_creator.rb:17:in `initialize' /home/hal/.rvm/gems/jruby-1.6.4/gems/dm-migrations-1.1.0/lib/dm-migrations/migration.rb:142:in `create_table' ./db/migrate/001_create_users.rb:3:in `(root)'
I have successfully reproduced this bug under MRI 1.8.7 and JRuby 1.6.4.
If i run a drop_column statement on sqlite I got the following error:
== Performing Down Migration #2: add_state_to_websites
ALTER TABLE "websites" DROP COLUMN "state"
rake aborted!
near "DROP": syntax error
When using a type from dm-types in migrations I get the following error: can't convert nil into Hash
when running rake db:migrate
. This is a rails project. Is it maybe related to #31, which is already closed?
The migration:
migration 1, :foo do
up do
create_table :rekenservices do
column :id, DataMapper::Property::Serial, :key => true
column :webaddress, URI, :required => true
end
end
end
Gemfile
source 'https://rubygems.org'
RAILS_VERSION = '~> 3.2.11'
DM_VERSION = '~> 1.2.0'
gem 'activesupport', RAILS_VERSION, :require => 'active_support'
gem 'actionpack', RAILS_VERSION, :require => 'action_pack'
gem 'actionmailer', RAILS_VERSION, :require => 'action_mailer'
gem 'activeresource', RAILS_VERSION, :require => 'active_resource'
gem 'railties', RAILS_VERSION, :require => 'rails'
gem 'tzinfo', '~> 0.3.32'
gem 'rails-i18n'
# gem 'rich_pluralization'
gem 'devise'
gem 'devise-encryptable'
gem 'dm-rails', '~> 1.2.1'
gem 'dm-sqlite-adapter', DM_VERSION
gem 'dm-migrations', DM_VERSION
gem 'dm-types', DM_VERSION
gem 'dm-validations', DM_VERSION #:git => '[email protected]:spockz/dm-validations.git', :branch => 'compat'
gem 'dm-constraints', DM_VERSION
gem 'dm-transactions', DM_VERSION
gem 'dm-aggregates', DM_VERSION
gem 'dm-timestamps', DM_VERSION
gem 'dm-observer', DM_VERSION
gem 'dm-devise', '~> 2.1.0'
gem 'dm-is-read_only'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.2.5'
gem 'coffee-rails', '~> 3.2.2'
gem 'uglifier', '~> 1.2.4'
end
gem 'jquery-rails', '~> 2.0.1'
gem 'rdiscount'
gem "dm-paperclip", :git => 'git://github.com/phillbaker/dm-paperclip.git', :branch => "bug-dm1.2.0-rails3.2.8-ruby1.8.7"
# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.1'
# Use unicorn as the web server
# gem 'unicorn', '~> 4.2.1'
# Deploy with Capistrano
# gem 'capistrano', '~> 2.11.2'
# To use debugger
# gem 'ruby-debug19', '~> 0.11.6', :require => 'ruby-debug'
group :test do
# Pretty printed test output
gem 'turn', '~> 0.9.4', :require => false
end
gem "libv8", "3.11.8.7"
gem "therubyracer"
gem "less-rails"
gem "twitter-bootstrap-rails", :git => 'git://github.com/seyhunak/twitter-bootstrap-rails.git'
gem 'cancan'
gem "airbrake"
Error log:
rake aborted!
can't convert nil into Hash
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/sql/table_creator.rb:90:in `update'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/sql/table_creator.rb:90:in `build_type'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/sql/table_creator.rb:60:in `initialize'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/sql/table_creator.rb:25:in `new'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/sql/table_creator.rb:25:in `column'
db/migrate/rekenservices.rb:26:in `block (3 levels) in <top (required)>'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/sql/table_creator.rb:17:in `instance_eval'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/sql/table_creator.rb:17:in `initialize'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration.rb:142:in `new'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration.rb:142:in `create_table'
db/migrate/rekenservices.rb:15:in `block (2 levels) in <top (required)>'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration.rb:103:in `call'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration.rb:103:in `block in perform_up'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration.rb:190:in `block in say_with_time'
/Users/alessandro/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/benchmark.rb:280:in `measure'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration.rb:190:in `say_with_time'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration.rb:102:in `perform_up'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration_runner.rb:57:in `block in migrate_up!'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration_runner.rb:55:in `each'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-migrations-1.2.0/lib/dm-migrations/migration_runner.rb:55:in `migrate_up!'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-rails-1.2.1/lib/dm-rails/railties/database.rake:68:in `block (3 levels) in <top (required)>'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:228:in `call'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:228:in `block in execute'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:223:in `each'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:223:in `execute'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:166:in `block in invoke_with_call_chain'
/Users/alessandro/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:159:in `invoke_with_call_chain'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:152:in `invoke'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/dm-rails-1.2.1/lib/dm-rails/railties/database.rake:85:in `block (2 levels) in <top (required)>'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:228:in `call'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:228:in `block in execute'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:223:in `each'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:223:in `execute'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:166:in `block in invoke_with_call_chain'
/Users/alessandro/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:159:in `invoke_with_call_chain'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/task.rb:152:in `invoke'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:143:in `invoke_task'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:101:in `block (2 levels) in top_level'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:101:in `each'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:101:in `block in top_level'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:110:in `run_with_threads'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:95:in `top_level'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:73:in `block in run'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:160:in `standard_exception_handling'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/lib/rake/application.rb:70:in `run'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/gems/rake-10.0.3/bin/rake:33:in `<top (required)>'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/bin/rake:23:in `load'
/Users/alessandro/.rvm/gems/ruby-1.9.3-p327/bin/rake:23:in `<main>'
Tasks: TOP => db:migrate:up
It appears that DataMapper.auto_upgrade! is attempting to re-create the columns of a base STI model, for every descendent of that base model. This results in duplicate column errors when calling auto_upgrade!. This error does not occurr when running DataMapper.auto_migrate!.
Gemfile
source 'http://rubygems.org'
datamapper = 'git://github.com/datamapper'
gem 'activesupport', '~> 3.0.0.beta3'
gem 'dm-do-adapter', '~> 1.0.0.rc2', :git => "#{datamapper}/dm-do-adapter.git"
gem 'dm-sqlite-adapter', '~> 1.0.0.rc2', :git => "#{datamapper}/dm-sqlite-adapter.git"
gem 'dm-core', '~> 1.0.0.rc2', :git => "#{datamapper}/dm-core.git"
gem 'dm-migrations', '~> 1.0.0.rc2', :git => "#{datamapper}/dm-migrations.git"
test.rb
require 'dm-core'
require 'dm-migrations'
class BaseModel
include DataMapper::Resource
include DataMapper::Migrations
property :id, Serial
property :type, Discriminator
property :x, Integer
end
class ModelOne < BaseModel
property :y, Integer
end
class ModelTwo < BaseModel
property :z, Integer
end
DataMapper.setup(:default, "sqlite3://test.db")
DataMapper.auto_upgrade!
Created by Postmodern - 2010-05-24 01:54:27 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1289
When running auto migrate, all data is destroyed. Why is this necessary? If auto migrate works as if each table starts from scratch, just drop and create the tables that have been edited.
The development process for auto:upgrades isn't flawless. In fact, most of the schema changes I make with auto upgrade fail. I then have to run auto migrate and all my data is destroyed.
Hi there!
Thanks for taking the time to write this, however I have no idea how it should be used. If you've got time, documentation would be really nice :)
Thanks!
Dan
When I change type of property (e.g. from Integer
to String
) auto_upgrade!
does not catch such change, and there is no way to migrate my db.
Created by knapo - 2010-12-27 15:16:20 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1461
Just lost a few years off my life trying to figure out a problem with a few of my apps using mysql and datamapper running under passenger that were calling auto_upgrade! during the application's boot process.
When the passenger processes are initialized calling auto_upgrade! will cause some of the subsequent database requests to throw error 2013. From what I can tell this is only seen in multi process servers like passenger and when using mysql.
If auto_upgrade! is not intended for production deployments it would be helpful if this was highlighted in the documentation.
I know that one of them (auto_migrate!) is destructive but I have to lookup the semantic everytime because the naming is not intuitive and leads to confusion. I lost my development data already 4 times when I did not lookup the meaning. I think, I am not the only one. Please add an alias that is not so confusing. It would help if the non-destructive method would not end with"!". That both methods begin with "auto_" does not help either. I know, it's a bikeshed, but... thank you!
Given an initial model Foo
:
class Rekenservice
include DataMapper::Resource
property :prop1, Integer
end
We perform a rake db:setup && rake db:migrate
and all is fine. Now later in development we add a new
property to our column :prop2
.
class Rekenservice
include DataMapper::Resource
property :prop1, Integer
property :prop2, Integer
end
We write a migration for this that reads as follows:
migration 1, :add_prop2 do
up do
modify_table :foos do
add_column :prop2, Integer
end
end
end
Subsequently calling rake db:migrate
is no problem. However, now when we run rake db:setup && rake db:migrate
again after deleting our database we get the following error:
duplicate column name: prop2
This because auto_migrate! in rake db:setup
already created the column for :prop2
.
What to do about this?
please see http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
you need to change the sql syntax to look like this:
"ALTER TABLE #{quoted_table_name} CHANGE #{quote_column_name(name)} #{quote_column_name(new_name)}"
According to the docs this is correct syntax, also try running the current syntax via a ui or command line and you will get an error.
The following migration:
modify_table :persons do
change_column :name, String, :length => 255
end
Produces this invalid SQL on PostgreSQL (version 8.4):
ALTER TABLE "persons" ALTER COLUMN "persons" TYPE "name" VARCHAR(255)
It should produce:
ALTER TABLE "persons" ALTER COLUMN "name" TYPE VARCHAR(255)
System info:
jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_24) [darwin-x86_64-java]
postgres (PostgreSQL) 8.4.4
Please contact me at [email protected], my company and I are interested in taking over maintenance of this gem. We use it daily in production and have our own set of patches we use internally, and we'd like to share our work with everyone.
I'm starting to work on it right now.
As reported directly to Dan directly some users point us to an issue with dm-migrations:
In previous version of DM 1.0. for get migrations working with @text@ , @boolean@ etc... types we need to use some like this:
create_table :posts do
column :id, 'INTEGER', :serial => true
column :title, 'STRING'
column :description, 'TEXT'
column :draft, 'BOOLEAN'
end
But now seem this hack have some problems almost with @mysql@ adapter:
CREATE TABLE `posts` (`id` SERIAL PRIMARY KEY, `title` STRING, `description` TEXT, `draft` BOOLEAN) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci
rake aborted!
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'STRING, `description` TEXT, `draft` BOOLEAN) ENGINE = InnoDB CHARACTER SET utf8 ' at line 1
So we reverted migrations to:
create_table :posts do
column :id, Integer, :serial => true
column :title, String
column :description, Text
column :draft, Boolean
end
But we get:
Performing Up Migration #1: create_posts
rake aborted!
uninitialized constant Text
So now I can't find a way for run correctly migrations.
Then I tried to inspect if we have same problem on dm-rails but on my env Im unable to create/drop databases. I think is a problem of ` here: http://github.com/datamapper/dm-rails/blob/master/lib/dm-rails/storage.rb#L120
I tried to replace this:
"CREATE DATABASE `#{database}` DEFAULT CHARACTER SET #{charset} DEFAULT COLLATE #{collation}"
into this:
"CREATE DATABASE #{database} DEFAULT CHARACTER SET #{charset} DEFAULT COLLATE #{collation}"
And worked.
I also need to change this:
@database ||= config['database'] || config['path']
Into this:
@database ||= config['database'] || config['path'].sub(/\//,'')
Consider that now I dropped my rvm rails machine so Im not be able to reproduce all of them.
I made some fixes for our padrino-tasks here: http://github.com/padrino/padrino-framework/blob/master/padrino-gen/lib/padrino-gen/padrino-tasks/datamapper.rb
Created by DAddYE - 2010-06-16 10:07:50 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1323
So if I do something like:
property :a_date, Date, :required => true
dm-migration doesn't like it. raise an erro:
Incorrect date value: '0000-00-00' for column 'a_date' at row 1
But if I run alter table directly in mysql, it runs fine
i was just wondering if it's maybe "safer" to issue a warning and don't auto_upgrade a not nullable column that has no explicitly given default value .. it can be argued that the developer should be knowing all that, but well ...
i think the defaults that the storage engine creates if no explicit ones were given will almost always be useless (wrong) .. if one overlooks something, then at least the tables (possibly production since it's auto_upgrade) don't get stuffed with trashdata
Created by Martin Gamsjaeger (snusnu) - 2009-08-20 05:54:49 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1014
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.