You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行Active Storage迁移时遭遇ORA-00955错误:对象名称已被占用

解决Active Storage迁移时的ORA-00955错误

问题诊断

你碰到的这个ActiveRecord::StatementInvalid: OCIError: ORA-00955错误其实很直白——Oracle数据库里已经存在ACTIVE_STORAGE_BLOBS表了,迁移脚本执行CREATE TABLE时自然就冲突报错了。

解决方案

根据你的实际情况,你可以选下面几种处理方式:

1. 先确认表的真实状态

先登录Oracle数据库,执行这两句查询,确认两张表是不是真的存在:

-- 检查active_storage_blobs表
SELECT table_name FROM user_tables WHERE table_name = 'ACTIVE_STORAGE_BLOBS';
-- 检查active_storage_attachments表
SELECT table_name FROM user_tables WHERE table_name = 'ACTIVE_STORAGE_ATTACHMENTS';

2. 场景一:表无业务数据,直接清理后重跑迁移

如果查询结果显示表存在,而且里面没有任何需要保留的数据,直接删表再执行迁移就好:

-- 先删依赖的attachments表(因为有外键关联,不能先删blobs表)
DROP TABLE ACTIVE_STORAGE_ATTACHMENTS;
-- 再删blobs表
DROP TABLE ACTIVE_STORAGE_BLOBS;

回到Rails项目里,执行迁移命令:

rails db:migrate

3. 场景二:表已有数据,不能删除

如果表里面已经存了业务数据,绝对不能删,那你得修改迁移文件,添加if_not_exists: true参数,让迁移只在表不存在的时候才创建:
修改你的CreateActiveStorageTables迁移文件:

# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
  def change
    create_table :active_storage_blobs, if_not_exists: true do |t|
      t.string :key, null: false
      t.string :filename, null: false
      t.string :content_type
      t.text :metadata
      t.bigint :byte_size, null: false
      t.string :checksum, null: false
      t.datetime :created_at, null: false

      t.index [ :key ], unique: true
    end

    create_table :active_storage_attachments, if_not_exists: true do |t|
      t.string :name, null: false
      t.references :record, null: false, polymorphic: true, index: false
      t.references :blob, null: false
      t.datetime :created_at, null: false

      t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
      t.foreign_key :active_storage_blobs, column: :blob_id
    end
  end
end

改完之后重新执行迁移就行。

4. 检查迁移执行状态

你也可以先看看这个迁移的状态,确认它是不是已经被标记为执行过了:

rails db:migrate:status

如果状态显示up,但表是之前手动创建的,那你完全不用再跑迁移;如果状态是down但表已经存在,可以手动把迁移标记为已执行:

rails db:migrate:up VERSION=20170806125915

(注意把VERSION换成你迁移文件名里的那个版本号)


补充的问题信息

你的环境配置:

  • Rails版本:5.2.0
  • activerecord-oracle_enhanced-adapter版本:5.2.0
  • ruby-oci8版本:2.2.6.1
  • Ruby版本:2.6.0
  • Oracle数据库版本:10.2.0.1.0

你遇到的完整错误信息:

ActiveRecord::StatementInvalid: OCIError: ORA-00955: name is already used by an existing object: CREATE TABLE "ACTIVE_STORAGE_BLOBS" ("ID" NUMBER(38) NOT NULL PRIMARY KEY, "KEY" VARCHAR2(255) NOT NULL, "FILENAME" VARCHAR2(255) NOT NULL, "CONTENT_TYPE" VARCHAR2(255), "METADATA" CLOB, "BYTE_SIZE" NUMBER(19) NOT NULL, "CHECKSUM" VARCHAR2(255) NOT NULL, "CREATED_AT" TIMESTAMP NOT NULL)

你使用的迁移文件:

# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
  def change
    create_table :active_storage_blobs do |t|
      t.string :key, null: false
      t.string :filename, null: false
      t.string :content_type
      t.text :metadata
      t.bigint :byte_size, null: false
      t.string :checksum, null: false
      t.datetime :created_at, null: false

      t.index [ :key ], unique: true
    end

    create_table :active_storage_attachments do |t|
      t.string :name, null: false
      t.references :record, null: false, polymorphic: true, index: false
      t.references :blob, null: false
      t.datetime :created_at, null: false

      t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
      t.foreign_key :active_storage_blobs, column: :blob_id
    end
  end
end

内容的提问来源于stack exchange,提问作者Vishal Pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:47:50