我在一个Rails应用程序中将MySQL数据库转换为PostgreSQL,并且在PostgreSQL中将MySQL double
列转换为double precision
列。
问题是,即使PostgreSQL结构的此列具有默认值“0 :: double precision”,rake db:schema:dump
也不会添加此默认值。
因此,在创建模型实例时,默认值不会自动分配,而是其值为nil
。
现在,我正在使用Rails 4.1.6,这是因为列类型未列出here(AFAIK)。奇怪(对我来说)是为什么还没有添加。
这里推荐的方法是什么?在PostgreSQL中更改列类型?
\d payments
内的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)
和schema.rb
的相应部分说:
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
答案 0 :(得分:1)
我认为你在ActiveRecord中的extract_value_from_default
问题是正确的; AR倾向于忽略它不理解的数据库中的任何内容,并且它不理解::double precision
定义中的amount
强制转换,因此AR假定没有默认值。
用于将MySQL模式和数据库转换为PostgreSQL的工具也是有问题的。不需要类型转换,PostgreSQL可以将整数转换为双精度,只需:
amount double precision default 0
就足够了。如果您想在默认情况下使用某种类型的提醒,那么您可以使用:
amount double precision default 0.0
AR应该了解其中任何一个。
最简单的解决方案是修复数据库中的默认值并删除类型转换。落后AR的后面并做一个手动的ALTER TABLE就足够了。从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
应该包含零金额。
另外,您可能希望在数据库中切换到numeric
类型(AR调用此t.decimal
)。使用浮动点赚钱很少结束。