sqlite3でカラムを削除する方法 [SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE “users”]

Railsのマイグレーションでcolumnを追加後にrollbackすると下記のようなエラーができることがある。sqliteにはカラムを削除する方法がないので、一旦テーブルを消して作り直すのだが、外部キー制約のため削除できず、エラーになる。

== 20210802023517 AddJtiToUser: reverting =====================================
-- remove_index(:users, {:column=>:jti})
   -> 0.0022s
-- remove_column(:users, :jti, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "users"


Caused by:
ActiveRecord::InvalidForeignKey: SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "users"だ

だが、しかしsqlite3.35でカラム削除ができるようになったので、最新バージョンを使えば良い。手元のubuntuのsqlite3は、3.31だったので、ソースからコンパイルする。

$ wget https://www.sqlite.org/2021/sqlite-autoconf-3360000.tar.gz
$ tar zxvf sqlite-autoconf-3360000.tar.gz 
$ cd sqlite-autoconf-3360000/
$ ./configure 
$ make

でこのバージョンを使って、

$ sqlite-autoconf-3360000/sqlite3 ~/my_project/db/development.sqlite3

# delete index and then drop column

sqlite> drop index index_users_on_jti;
sqlite> ALTER TABLE users DROP COLUMN jti;

その後、Railsの場合、migration version を消すとrollbackしたことになる。

$ rails db:migrate:status | tail -n 2
   up     20210802023517  Add jti to user

$ sqlite3 db/development.sqlite3
> delete from schema_migrations where version='[version_number]';

 

 

Related Posts