升级到 PostgreSQL 9.4 后,如何将所有 JSON 列转换为 JSONB 列?
我不介意丢失任何重复的键和空格。
ALTER TABLE t ALTER COLUMN j TYPE jsonb USING j::text::jsonb;
在 Rails 环境中,以下是 ActiveRecord 迁移替代方案:
def change
reversible do |dir|
dir.up { change_column :models, :attribute, 'jsonb USING CAST(attribute AS jsonb)' }
dir.down { change_column :models, :attribute, 'json USING CAST(attribute AS json)' }
end
end
我在一个包含 120,000 条记录的表上对此进行了测试,每条记录都有四个
json
列,我花了大约一分钟来迁移该表。当然,这取决于json
结构的复杂程度。
另请注意,如果您现有的记录具有默认值
{}
,则必须添加到上述语句 default: {}
,因为否则您将拥有 jsonb
列,但默认值仍将保留为 '{}'::json
.
如果有人正在寻找
alembic
的解决方案(具体来说,我使用 flask + alembic + postres 15.3
):
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql
def upgrade():
op.alter_column('system_info', 'phones', type_=postgresql.JSONB, postgresql_using='phones::text::jsonb')
def downgrade():
op.alter_column('system_info', 'phones', type_=sa.JSON(), postgresql_using='phones::json')
不能透露太多,我不是专家,但就我而言,迁移进行得很顺利(这意味着我没有注意到任何数据损坏甚至变化)。您可以在此处找到一些详细信息。我发布
downgrade
也是因为在 alembic
中你需要有回滚策略。