Ruby on rails MySQL双精度到PostgreSQL双精度可以工作,但schema.rb dump中不存在默认列值
我在Rails应用程序中将一个MySQL数据库转换为PostgreSQL,在PostgreSQL中将MySQLRuby on rails MySQL双精度到PostgreSQL双精度可以工作,但schema.rb dump中不存在默认列值,ruby-on-rails,postgresql,rails-activerecord,Ruby On Rails,Postgresql,Rails Activerecord,我在Rails应用程序中将一个MySQL数据库转换为PostgreSQL,在PostgreSQL中将MySQLdouble列转换为double precision列 问题是,即使PostgreSQL结构的此列具有默认值“0::double precision”,rake db:schema:dump也不会添加此默认值 因此,创建模型实例时,默认值不是自动指定的,而是nil 现在,我使用的是Rails 4.1.6,这是因为列类型未列出(AFAIK)。(对我来说)奇怪的是为什么还没有添加这个 这里推
double
列转换为double precision
列
问题是,即使PostgreSQL结构的此列具有默认值“0::double precision”,rake db:schema:dump也不会添加此默认值
因此,创建模型实例时,默认值不是自动指定的,而是nil
现在,我使用的是Rails 4.1.6,这是因为列类型未列出(AFAIK)。(对我来说)奇怪的是为什么还没有添加这个
这里推荐的方法是什么?是否更改PostgreSQL中的列类型
A\d从内部支付psql
说明:
Table "public.payments"
Column | Type | Modifiers
----------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('payments_id_seq'::regclass)
credit_card_id | integer | not null default 0
order_id | integer | not null default 0
amount | double precision | not null default 0::double precision
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
authorization | character varying(510) | default NULL::character varying
Indexes:
"payments_pkey" PRIMARY KEY, btree (id)
"credit_card_id" btree (credit_card_id)
"purchase_order_id_1" btree (order_id)
create_table "payments", force: true do |t|
t.integer "credit_card_id", default: 0, null: false
t.integer "order_id", default: 0, null: false
t.float "amount", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "authorization", limit: 510
end
而schema.rb
的相应部分则表示:
Table "public.payments"
Column | Type | Modifiers
----------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('payments_id_seq'::regclass)
credit_card_id | integer | not null default 0
order_id | integer | not null default 0
amount | double precision | not null default 0::double precision
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
authorization | character varying(510) | default NULL::character varying
Indexes:
"payments_pkey" PRIMARY KEY, btree (id)
"credit_card_id" btree (credit_card_id)
"purchase_order_id_1" btree (order_id)
create_table "payments", force: true do |t|
t.integer "credit_card_id", default: 0, null: false
t.integer "order_id", default: 0, null: false
t.float "amount", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "authorization", limit: 510
end
我认为你在ActiveRecord内部的extract\u value\u from\u default
中的问题是对的;AR倾向于忽略数据库中它不理解的任何内容,也不理解::双精度强制转换金额的定义,因此AR假设没有默认值
无论您使用什么工具将MySQL模式和数据库转换为PostgreSQL,都有一定的缺陷。不需要类型转换,PostgreSQL可以自行将整数转换为双精度,因此:
amount double precision default 0
这就足够了。如果您希望在默认情况下提醒您正在处理浮点运算,则可以使用:
amount double precision default 0.0
AR应该理解其中任何一个
最简单的解决方案是修复数据库中的默认值并删除类型转换。在AR的背后做一个手动更改表就足够了。从psql
,您可以说:
alter table payments alter column amount set default 0;
或者在迁移中:
def up
connection.execute('alter table payments alter column amount set default 0')
end
在此之后,您的db:schema:dump
应该包含新的默认值,并且新创建的Payment
s应该有一个零的值
另外,您可能希望切换到数据库中的numeric
类型(AR称之为t.decimal
)。对货币使用浮点很少有好结果。PostgreSQL认为该表是什么样子的?通过命令行中的psql
和\d table\u name
连接数据库。表在schema.rb
中是什么样子的?psql:schema.rb:我指的列是amount
。谢谢,你太棒了!:实际上,我正在使用它,所以我将修改它以添加AR可识别的默认值。你对专栏类型的看法绝对正确,当然不适合赚钱。这是rails 1到rails 4的迁移。。。