ActiveRecord6(복수 DB 연결)을 Rails가 아닌 환경에서 사용

15593 단어 Rails6ActiveRecord
ActiveRecord를 Rails가 아닌 환경에서 사용(2019년판)
htps : // 코 m / 유스 케이 와키 / ms / b009 3465fd8 1868d6

다중 DB 버전. 「일차로 집계한 결과는, 다른 DB에 보관하고 싶다♪」라고 해도 곤란하지 않게 준비다.

※이것은, 완전하게 시험으로, 자신용도입니다.

docker-compose에 다른 MySQL 컨테이너 추가



docker-compose.yml 변경
diff --git a/docker-compose.yml b/docker-compose.yml
index 026ffba..6c93bb6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -7,6 +7,13 @@ services:
     volumes:
       - mysql-data:/var/lib/mysql

+  datacenter:
+    image: mysql:5.7
+    environment:
+      MYSQL_ROOT_PASSWORD: fugafuga
+    volumes:
+      - datacenter-data:/var/lib/mysql
+
   workspace:
     image: ruby:2.6
     stdin_open: true
@@ -14,10 +21,14 @@ services:
     environment:
       MYSQL_HOST: mysql
       MYSQL_PASSWORD: hogehoge
+      DATACENTER_MYSQL_HOST: datacenter
+      DATACENTER_MYSQL_PASSWORD: fugafuga
     depends_on:
       - mysql
+      - datacenter
     links:
       - mysql
+      - datacenter
     volumes:
       - .:/usr/src/app
     working_dir: /usr/src/app
@@ -25,3 +36,5 @@ services:
 volumes:
   mysql-data:
     driver: local
+  datacenter-data:
+    driver: local

Gemfile 업데이트



2019/07/12 현재라면, 버전 무지정에서는 5.2.3이 내려오므로, 버전을 지정한다.

Gemfile 변경
diff --git a/Gemfile b/Gemfile
index 9e56d8b..21c64ad 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,6 +4,6 @@ source "https://rubygems.org"

 git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

-gem 'activerecord'
+gem 'activerecord', '~> 6.0.0.rc1'
 gem 'mysql2'
 gem 'rake'

db:create



데이터 집계용 DB는 config/database.yml에 어떻게 쓰면 어때? 와서
https://魏Tub. 작은 m/온 ls/오 ls/bぉb/V6.0.0. RC1/아c지베레코rd/ぃb/아c지베_레코rd/다른sks/타다바시_그 외sks. rb
당 소스를 보면 보통 config/database.yml의 해시를 1계층 깊게 하는 것만으로 움직일 것 같았다.

config/database.yml
development:
  data:
    adapter: mysql2
    encoding: utf8mb4
    database: ar_without_rails_playground
    pool: 5
    username: root
    password: <%= ENV['MYSQL_PASSWORD'] %>
    host: <%= ENV['MYSQL_HOST'] %>

  datacenter:
    adapter: mysql2
    encoding: utf8mb4
    database: ar_without_rails_aggregation
    pool: 5
    username: root
    password: <%= ENV['DATACENTER_MYSQL_PASSWORD'] %>
    host: <%= ENV['DATACENTER_MYSQL_HOST'] %>
root@2bf5bdca9402:/usr/src/app# bundle exec rake db:create    
Database 'ar_without_rails_playground' already exists
Created database 'ar_without_rails_aggregation'

오!

만약을 위해, mysql 커멘드로 올바르게 만들어지고 있을지도 보았지만
root@2bf5bdca9402:/usr/src/app# echo 'SHOW DATABASES;' | mysql -h datacenter -u root -pfugafuga
Database
information_schema
ar_without_rails_aggregation
mysql
performance_schema
sys
root@2bf5bdca9402:/usr/src/app# echo 'SHOW DATABASES;' | mysql -h mysql -u root -phogehoge
Database
information_schema
ar_without_rails_playground
mysql
performance_schema
sys

기대대로 mysql 컨테이너는 변하지 않고 datacenter 쪽에 ar_without_rails_aggregation 데이터베이스가 만들어지고 있다.

db:migrate



마이그레이션 파일은 어떻게 작성하면 어떻습니까? 되었다.

ActiveRecord::Tasks::DatabaseTasks를 다시 살펴보면 migration_context 라는 궁금한 단어를 발견.
blame 그러면 ... htps : // 기주 b. 코 m/라이 ls/라이 ls/푸 l/31727 이런 것을 발견.

migrations_paths 사용할 수 있고 썼다. 호! ! !

config/database.yml에 추가
diff --git a/config/database.yml b/config/database.yml
index 7833f19..0473892 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -16,3 +16,4 @@ development:
     username: root
     password: <%= ENV['DATACENTER_MYSQL_PASSWORD'] %>
     host: <%= ENV['DATACENTER_MYSQL_HOST'] %>
+    migrations_paths: db/migrate_for_datacenter

db/migrate_for_datacenter/20190712230727_create_daily_aggregation_results.rb
class CreateDailyAggregationResults < ActiveRecord::Migration[6.0]
  def up
    create_table :daily_aggregation_results do |t|
      t.date :target_date, null: false
      t.integer :count, null: false
      t.datetime :aggregated_at, null: false, index: true
    end
  end

  def down
    drop_table :daily_aggregation_results
  end

그러면 ...
root@2bf5bdca9402:/usr/src/app# bundle exec rake db:migrate
== 20190712230727 CreateDailyAggregationResults: migrating ====================
-- create_table(:daily_aggregation_results)
   -> 0.0089s
== 20190712230727 CreateDailyAggregationResults: migrated (0.0090s) ===========

daily_aggregation_results 테이블이 만들어졌다.
root@2bf5bdca9402:/usr/src/app# mysql -h mysql -u root -phogehoge ar_without_rails_playground
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 33
Server version: 5.7.26 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [ar_without_rails_playground]> SHOW TABLES;
+---------------------------------------+
| Tables_in_ar_without_rails_playground |
+---------------------------------------+
| ar_internal_metadata                  |
| schema_migrations                     |
| todo_items                            |
+---------------------------------------+
3 rows in set (0.001 sec)

MySQL [ar_without_rails_playground]> exit
Bye
root@2bf5bdca9402:/usr/src/app# mysql -h datacenter -u root -pfugafuga ar_without_rails_aggregation
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 18
Server version: 5.7.26 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [ar_without_rails_aggregation]> SHOW TABLES;
+----------------------------------------+
| Tables_in_ar_without_rails_aggregation |
+----------------------------------------+
| ar_internal_metadata                   |
| daily_aggregation_results              |
| schema_migrations                      |
+----------------------------------------+
3 rows in set (0.001 sec)

예상대로 테이블이 만들어진다.

모델



app/models/daily_aggregation_result.rb
class DailyAggregationResult < ActiveRecord::Base
end

만들지만, 이것만으로
  • DailyAggregationResult는 datacenter (ar_without_rails_aggregation 데이터베이스) 테이블
  • TodoItem은 data (ar_without_rails_playground 데이터베이스) 테이블

  • 를 각각 보러 가야 한다는 선언이 어디에도 없고, 에러가 되어 버린다.

    connected_to를 사용하여 명시 적으로 "○○에 연결"이라고 쓰는 방법



    집계 스크립트라면 전부 집계가 끝난 데이터를 DB를 바꾸어 쓴다는 것이므로 이 방법이 간단하다고 생각된다.

    code/init.rb 변경
    diff --git a/config/init.rb b/config/init.rb
    index 843dd41..7345dbe 100644
    --- a/config/init.rb
    +++ b/config/init.rb
    @@ -9,7 +9,7 @@ config_database_yml = YAML::load(ERB.new(File.read(config_database_yml_file)).re
    
     # データベース接続の定義. created_at などで ActiveSupport::TimeWithZone を返してもらうための設定。
     Time.zone = 'Tokyo'
    -ActiveRecord::Base.establish_connection(config_database_yml['development'])
    +ActiveRecord::Base.configurations = config_database_yml['development']
     ActiveRecord::Base.time_zone_aware_attributes = true
    
     # モデルのクラスをrequireしておく
    

    처럼, establish_connection은 하지 않고 configurations= 로 YAML 를 건네주는 것만으로 한다.
    (이것 단독으로는 DB 접속하지 않는다)

    그래서 집계 스크립트에서

    scripts/aggregate_todo_count_by_date.rb
    require './config/init.rb'
    
    # 日ごとの件数を数えてハッシュに入れる。
    results =
      ActiveRecord::Base.connected_to(database: :data) do
        TodoItem.group("DATE_FORMAT(created_at, '%Y-%m-%d')").count
      end
    
    # 集計結果テーブルにbulk insertする
    data = results.map do |created_at, count|
      { target_date: created_at, count: count, aggregated_at: Time.current }
    end
    ActiveRecord::Base.connected_to(database: :datacenter) do
      DailyAggregationResult.insert_all(data)
    end
    

    라는 느낌으로, 매번 어느 접속처를 명기하도록 하면,
    irb(main):005:0> ActiveRecord::Base.connected_to(database: :datacenter){ puts DailyAggregationResult.all.map(&:attributes) }
    {"id"=>1, "target_date"=>Sun, 07 Jul 2019, "count"=>12, "aggregated_at"=>Sat, 13 Jul 2019 00:25:16 JST +09:00}
    {"id"=>2, "target_date"=>Mon, 08 Jul 2019, "count"=>15, "aggregated_at"=>Sat, 13 Jul 2019 00:25:16 JST +09:00}
    {"id"=>3, "target_date"=>Tue, 09 Jul 2019, "count"=>10, "aggregated_at"=>Sat, 13 Jul 2019 00:25:16 JST +09:00}
    {"id"=>4, "target_date"=>Wed, 10 Jul 2019, "count"=>12, "aggregated_at"=>Sat, 13 Jul 2019 00:25:16 JST +09:00}
    {"id"=>5, "target_date"=>Thu, 11 Jul 2019, "count"=>18, "aggregated_at"=>Sat, 13 Jul 2019 00:25:16 JST +09:00}
    {"id"=>6, "target_date"=>Fri, 12 Jul 2019, "count"=>33, "aggregated_at"=>Sat, 13 Jul 2019 00:25:16 JST +09:00}
    

    집계 자료는 다른 DB에 안전하게 쓴다.

    connects_to를 사용하여 "이 모델은이 DB를 참조하라"고 지정하는 방법



    만지는 모델이 많거나 2개의 DB의 모델을 동시에 만져야 한다면 이 방법을 사용할 필요가 있다.

    하지만 이번에는 그 필요성까지는 느끼지 않으므로 시도하지 않았습니다 : swea

    어쩌면 htps : // 기주 b. 코 m / 라이 ls / 라이 ls / 푸 l / 34052 / 후 ぇ s에 쓰여 있다면 움직이는 것이 아닐까? (무책임 w)

    요약



    우선, 6.0의 정식 릴리스 될 때까지 기다린다. 그렇다면 여러 사람이 반드시 조사해 줄 것이다. (무책임 w)

    이번에 만든 소스 코드는
    htps : // 기주 b. 코 m / 유스 케이 이와키 / 아

    좋은 웹페이지 즐겨찾기