- DBがないとエラー
- 空のDBでexportしても何も起きない
- apply
- 変更がない場合はNochange
- 差分がない時は何も起きない
- カラム削除
- カラム追加
- ただ単に
.schema
を削除した場合はSchemafile
のrequire
でエラーになる - ファイル削除した場合でもDROPされずに
Nochange
になる - DROPの場合
.schema
が残っていてもSchemafile
のrequire
を削除しただけでDROPされる - データが入っている状態で、apply(カラム追加)してもデータは残る
- データが入っている状態で、apply(カラム名変更)すると空になる
- データが入っている状態で、既存のカラムが空の状態で
null:false
に変更するとエラーになる - データが入っている状態で、
null:false
で新規カラム追加しようとするとエラーになる - データがある状態で
null:false
のカラム追加でもdefault
があれば可能
その他
DBがないとエラー
# bundle exec rake ridgepole:export
[ERROR] We could not find your database: vwc_dev. Which can be found in the database configuration file located at config/database.yml.
To resolve this issue:
- Did you create the database for this app, or delete it? You may need to create your database.
- Has the database name changed? Check your database.yml config has the correct database name.
To create your database, run:
bin/rails db:create
/usr/local/bundle/gems/activerecord-7.0.3/lib/active_record/connection_adapters/postgresql_adapter.rb:81:in `rescue in new_client'
空のDBでexportしても何も起きない
# bin/rails db:create
Created database 'vwc_dev'
Database 'vwc_test' already exists
#
#
# bundle exec rake ridgepole:export
# Export Schema
#
apply
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
-- create_table("fund_details")
-> 0.1828s
-- create_table("fund_financial_tradings")
-> 0.0643s
-- create_table("fund_headlines")
-> 0.0634s
-- create_table("fund_real_estate_specifieds")
-> 0.0705s
-- create_table("product_categories")
-> 0.0738s
-- create_table("products")
-> 0.0421s
-- create_table("tenant_booths")
-> 0.1862s
-- create_table("tenants")
-> 0.0693s
変更がない場合はNochange
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
No change
差分がない時は何も起きない
exportされてるっぽいけど、差分がないので何も起きない
1ファイル削除してから実行しても表示は同じだが、削除したファイルが復活する
# bundle exec rake ridgepole:export
Export Schema
write `db/schemas/fund_details.schema`
write `db/schemas/fund_financial_tradings.schema`
write `db/schemas/fund_headlines.schema`
write `db/schemas/fund_real_estate_specifieds.schema`
write `db/schemas/product_categories.schema`
write `db/schemas/products.schema`
write `db/schemas/tenant_booths.schema`
write `db/schemas/tenants.schema`
write `db/schemas/Schemafile`
カラム削除
fund_details.schema
のt.string "display_link"
を削除してから実行
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
-- remove_column("fund_details", "display_link")
-> 0.0335s
カラム追加
fund_details.schema
にt.string "add_column"
を追加してから実行
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
[WARNING] PostgreSQL doesn't support adding a new column except for the last position. fund_details.add_column will be added to the last.
-- add_column("fund_details", "add_column", :string)
-> 0.0029s
ただ単に.schema
を削除した場合はSchemafile
のrequire
でエラーになる
fund_details.schema
を削除してから実行
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
bundler: failed to load command: ridgepole (/usr/local/bundle/bin/ridgepole)
/usr/local/bundle/gems/ridgepole-1.1.0/lib/ridgepole/dsl_parser/context.rb:102:in `require': cannot load such file -- fund_details.schema (LoadError)
ファイル削除した場合でもDROPされずにNochange
になる
Schemafile
のrequire 'fund_details.schema'
を削除してから実行
明示的に--drop-table
しないとDROPされない
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
No change
DROPの場合.schema
が残っていてもSchemafile
のrequire
を削除しただけでDROPされる
Schemafile
のrequire 'fund_details.schema'
を削除してから実行
# bundle exec rake ridgepole:drop
Apply `db/schemas/Schemafile`
-- drop_table("fund_details")
-> 0.0732s
データが入っている状態で、apply(カラム追加)してもデータは残る
tenants.schema
にt.string "add_column"
を追加してから実行
# rails db:seed
rails aborted!
ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "tenants_pkey"
DETAIL: Key (id)=(9999) already exists.
/work/db/seeds.rb:1:in `block in <main>'
/work/db/seeds.rb:1:in `each'
/work/db/seeds.rb:1:in `<main>'
Caused by:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "tenants_pkey"
DETAIL: Key (id)=(9999) already exists.
/work/db/seeds.rb:1:in `block in <main>'
/work/db/seeds.rb:1:in `each'
/work/db/seeds.rb:1:in `<main>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)
#
#
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
[WARNING] PostgreSQL doesn't support adding a new column except for the last position. tenants.add_column will be added to the last.
-- add_column("tenants", "add_column", :string)
-> 0.0101s
カラム追加前
vwc_dev=# select * from tenants;
id | tenant_name | tenant_log_image | created_at | updated_at
------+-------------+-----------------------------------+----------------------------+----------------------------
9999 | test tenant | financial_street/lobby_sample.png | 2022-07-13 15:47:43.044591 | 2022-07-13 15:47:43.044591
(1 row)
カラム追加後
vwc_dev=# select * from tenants;
id | tenant_name | tenant_log_image | created_at | updated_at | add_column
------+-------------+-----------------------------------+----------------------------+----------------------------+------------
9999 | test tenant | financial_street/lobby_sample.png | 2022-07-13 15:47:43.044591 | 2022-07-13 15:47:43.044591 |
(1 row)
データが入っている状態で、apply(カラム名変更)すると空になる
tenants.schema
のt.string "tenant_name"
をt.string "tenant_name_cange_name"
に変更してから実行
remove_column & add_columnになる
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
[WARNING] PostgreSQL doesn't support adding a new column except for the last position. tenants.tenant_name_cange_name will be added to the last.
-- add_column("tenants", "tenant_name_cange_name", :string)
-> 0.0080s
-- remove_column("tenants", "tenant_name")
-> 0.0081s
変更後
vwc_dev=# select * from tenants;
id | tenant_log_image | created_at | updated_at | add_column | tenant_name_cange_name
------+-----------------------------------+----------------------------+----------------------------+------------+------------------------
9999 | financial_street/lobby_sample.png | 2022-07-13 15:47:43.044591 | 2022-07-13 15:47:43.044591 | |
(1 row)
データが入っている状態で、既存のカラムが空の状態でnull:false
に変更するとエラーになる
tenants.schema
のt.string "add_column"
をt.string "add_column", null: false
に変更してから実行
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
-- change_column("tenants", "add_column", :string, {:null=>false, :default=>nil})
[ERROR] PG::NotNullViolation: ERROR: column "add_column" of relation "tenants" contains null values
* 1: change_column("tenants", "add_column", :string, **{:null=>false, :default=>nil})
/usr/local/bundle/gems/activerecord-7.0.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:48:in `exec'
データが入っている状態で、null:false
で新規カラム追加しようとするとエラーになる
tenants.schema
にt.string "not_null_column", null: false
を追加してから実行
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
[WARNING] PostgreSQL doesn't support adding a new column except for the last position. tenants.not_null_column will be added to the last.
-- add_column("tenants", "not_null_column", :string, {:null=>false})
[ERROR] PG::NotNullViolation: ERROR: column "not_null_column" of relation "tenants" contains null values
* 1: add_column("tenants", "not_null_column", :string, **{:null=>false})
/usr/local/bundle/gems/activerecord-7.0.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:48:in `exec'
データがある状態でnull:false
のカラム追加でもdefault
があれば可能
tenants.schema
にt.string "not_null_column", null: false, default: 'hello'
を追加してから実行
# bundle exec rake ridgepole:apply
Apply `db/schemas/Schemafile`
[WARNING] PostgreSQL doesn't support adding a new column except for the last position. tenants.not_null_column will be added to the last.
-- add_column("tenants", "not_null_column", :string, {:null=>false, :default=>"hello"})
-> 0.0193s
## その他
dotenvなどの導入時要注意
CF. dotenv 付きの config/database.yml と相性が悪い
ER図の自動生成
voormedia/rails-erd
※ migrationファイルがなくても動作を確認
actionsに追加したい
- name: Generete ER図
run: bundle exec erd --filetype=png --title=${{ github.sha }}
- name: push to tech-doc
run: push
DBが共有だからER図も一つで良い気もするが、modelの情報(has_manyとか)も必要だから別々?
そもそも(今更)だが、foreign_key
指定しなくても問題ないのでしょうか? <= ちゃんと指定してDBに反映してあればER図も簡単説
(er図)[https://github.com/VirtualWallC/tech_doc/blob/develop/vwc_tenant/ER%E5%9B%B3/%E5%8E%9F%E6%9C%AC/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%20ER%20%E5%9B%B3.jpeg]と実際のDBが一致していないので、やはりER図は手動作成でない方が良いかと思われる。
ex) tenant_log_image
schemaspy
docker run -v "$PWD/db/schema:/output" --net="host" schemaspy/schemaspy:6.1.0 -t pgsql -host localhost:5432 -db vwc_dev -u postgres -p pass
migrationファイルの復活方法はない
1. 手動でmigrationファイルを復活させてdb:migrate
手動でmigrationファイルを復活させてから実行
pg_dump -U postgres -p 5432 --data-only vwc_dev > vwc_dev.dmp
rails db:migrate:reset
psql -U postgres -p 5432 vwc_dev < vwc_dev.dmp
2. db:bump
でdb/schema.rb
で運用する
rails db:reset
はdb/schema.rb
を元にDB作成します。db/migrate/**.rb
は使われません。
pg_dump -U postgres -p 5432 --data-only vwc_dev > vwc_dev.dmp
rails db:bump
rails db:reset
psql -U postgres -p 5432 vwc_dev < vwc_dev.dmp
CF. 24.1. SQLによるダンプ
migrationファイル削除コミット
modelをgenerateする時は、--skip-migration
を付けるのを忘れずに
ex)
rails g model Foo --skip-migration
導入例
クックパッドにおける最近のActiveRecord運用事情
すでに動いているシステムでridgepoleを使うためのメモ