Active Record 連線處理
- C
- E
- L
- P
- R
- S
- W
常數
DEFAULT_ENV | = | -> { RAILS_ENV.call || "default_env" } |
RAILS_ENV | = | -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence } |
屬性
[W] | connection_specification_name |
個體公用方法
clear_query_caches_for_current_thread() 連結
清除與目前執行緒關聯的全部連線的快取查詢。
connected?() 連結
如果 Active Record 已連線,則傳回 true
。
connected_to(role: nil, shard: nil, prevent_writes: false, &blk) 連結
在區塊持續期間,連線至角色 (例如:撰寫、讀取或自訂角色) 和/或分片。區塊結尾時,連線會返回至原始角色/分片。
如果僅傳入一個角色,Active Record 會根據要求的角色來尋找連線。如果要求未建立的角色,將會傳回 ActiveRecord::ConnectionNotEstablished
錯誤。
ActiveRecord::Base.connected_to(role: :writing) do
Dog.create! # creates dog using dog writing connection
end
ActiveRecord::Base.connected_to(role: :reading) do
Dog.create! # throws exception because we're on a replica
end
換至分片時,也必須傳入角色。如果傳入不存在的分片,將會傳回 ActiveRecord::ConnectionNotEstablished
錯誤。
當傳入分片與角色時,Active Record 會先尋找角色,再根據分片索引尋找連線。
ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one_replica) do
Dog.first # finds first Dog record stored on the shard one replica
end
# File activerecord/lib/active_record/connection_handling.rb, line 136 def connected_to(role: nil, shard: nil, prevent_writes: false, &blk) if self != Base && !abstract_class raise NotImplementedError, "calling `connected_to` is only allowed on ActiveRecord::Base or abstract classes." end if !connection_class? && !primary_class? raise NotImplementedError, "calling `connected_to` is only allowed on the abstract class that established the connection." end unless role || shard raise ArgumentError, "must provide a `shard` and/or `role`." end with_role_and_shard(role, shard, prevent_writes, &blk) end
connected_to?(role:, shard: ActiveRecord::Base.default_shard) 連結
如果角色是目前連線的角色和/或目前連線的分片,則傳回 true。如果未傳入分片,則會使用預設值。
ActiveRecord::Base.connected_to(role: :writing) do
ActiveRecord::Base.connected_to?(role: :writing) #=> true
ActiveRecord::Base.connected_to?(role: :reading) #=> false
end
ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one) do
ActiveRecord::Base.connected_to?(role: :reading, shard: :shard_one) #=> true
ActiveRecord::Base.connected_to?(role: :reading, shard: :default) #=> false
ActiveRecord::Base.connected_to?(role: :writing, shard: :shard_one) #=> true
end
connected_to_all_shards(role: nil, prevent_writes: false, &blk) 連結
將區塊傳遞至模型設定為連線的各個 shard
的 connected_to
(若有任何),並在陣列中傳回結果。
也可以傳遞 role
和/或 prevent_writes
,將會轉送到每個 connected_to
呼叫。
connected_to_many(*classes, role:, shard: nil, prevent_writes: false) 連結
將角色和/或分片連線到指定的連線名稱。也可以傳遞 prevent_writes
以在連線禁止寫入。 reading
會自動將 prevent_writes
設為 true。
connected_to_many
是深入巢狀 connected_to
區塊的替代方法。
用法
ActiveRecord::Base.connected_to_many(AnimalsRecord, MealsRecord, role: :reading) do
Dog.first # Read from animals replica
Dinner.first # Read from meals replica
Person.first # Read from primary writer
end
# File activerecord/lib/active_record/connection_handling.rb, line 165 def connected_to_many(*classes, role:, shard: nil, prevent_writes: false) classes = classes.flatten if self != Base || classes.include?(Base) raise NotImplementedError, "connected_to_many can only be called on ActiveRecord::Base." end prevent_writes = true if role == ActiveRecord.reading_role append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: classes) yield ensure connected_to_stack.pop end
connecting_to(role: default_role, shard: default_shard, prevent_writes: false) 連結
使用指定的連接。
這個方法可用於確保使用特定的連線。例如,在唯讀模式下啟動主控台。
不建議在要求中使用這個方法,因為它不會像 connected_to
一樣讓出區塊。
# File activerecord/lib/active_record/connection_handling.rb, line 199 def connecting_to(role: default_role, shard: default_shard, prevent_writes: false) prevent_writes = true if role == ActiveRecord.reading_role append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: [self]) end
connection() 連結
已逐步淘汰。改用 #with_connection
或 #lease_connection
。
# File activerecord/lib/active_record/connection_handling.rb, line 274 def connection pool = connection_pool if pool.permanent_lease? case ActiveRecord.permanent_connection_checkout when :deprecated ActiveRecord.deprecator.warn <<~MESSAGE Called deprecated `ActiveRecord::Base.connection` method. Either use `with_connection` or `lease_connection`. MESSAGE when :disallowed raise ActiveRecordError, <<~MESSAGE Called deprecated `ActiveRecord::Base.connection` method. Either use `with_connection` or `lease_connection`. MESSAGE end pool.lease_connection else pool.active_connection end end
connection_db_config() 連結
從關聯的連線傳回 db_config 物件
ActiveRecord::Base.connection_db_config
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
@name="primary", @config={pool: 5, timeout: 5000, database: "storage/development.sqlite3", adapter: "sqlite3"}>
只供讀取使用。
connection_pool() 連結
connection_specification_name() 連結
從目前的類別或其父類別傳回連線規格名稱。
connects_to(database: {}, shards: {}) 連結
將模型與指定的資料庫連線。 database
關鍵字會取得包含 role
和 database_key
的雜湊。
這會使用 database_key
查詢資料庫設定並建立連線至該設定。
class AnimalsModel < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :primary, reading: :primary_replica }
end
connects_to
也支援水準分片。水準分片 API 也支援讀取副本。你可以這樣連線一個模式到分片清單中
class AnimalsModel < ApplicationRecord
self.abstract_class = true
connects_to shards: {
default: { writing: :primary, reading: :primary_replica },
shard_two: { writing: :primary_shard_two, reading: :primary_shard_replica_two }
}
end
傳回一個資料庫連線陣列。
來源: 顯示 | 在 GitHub 上
# File activerecord/lib/active_record/connection_handling.rb, line 81 def connects_to(database: {}, shards: {}) raise NotImplementedError, "`connects_to` can only be called on ActiveRecord::Base or abstract classes" unless self == Base || abstract_class? if database.present? && shards.present? raise ArgumentError, "`connects_to` can only accept a `database` or `shards` argument, but not both arguments." end connections = [] @shard_keys = shards.keys if shards.empty? shards[:default] = database end self.default_shard = shards.keys.first shards.each do |shard, database_keys| database_keys.each do |role, database_key| db_config = resolve_config_for_connection(database_key) self.connection_class = true connections << connection_handler.establish_connection(db_config, owner_name: self, role: role, shard: shard.to_sym) end end connections end
establish_connection(config_or_env = nil) 連結
建立與資料庫之間的連線。接受一個雜湊作為輸入,其中必定會包含 :adapter
鍵,並輸入一個資料庫傳輸器(小寫)名稱,範例為一般資料庫(MySQL、PostgreSQL 等)
ActiveRecord::Base.establish_connection(
adapter: "mysql2",
host: "localhost",
username: "myuser",
password: "mypass",
database: "somedatabase"
)
針對 SQLite 資料庫的範例
ActiveRecord::Base.establish_connection(
adapter: "sqlite3",
database: "path/to/dbfile"
)
也可以接受字串作為鍵(例如解析自 YAML)
ActiveRecord::Base.establish_connection(
"adapter" => "sqlite3",
"database" => "path/to/dbfile"
)
或者是一個 URL
ActiveRecord::Base.establish_connection(
"postgres://myuser:mypass@localhost/somedatabase"
)
如果 ActiveRecord::Base.configurations 已設定(Rails 會自動載入 config/database.yml 的內容),也可以提供一個字元作為參數,代表組態雜湊中的一個鍵
ActiveRecord::Base.establish_connection(:production)
例外 AdapterNotSpecified
、AdapterNotFound
和 ArgumentError
可以在錯誤發生時傳回。
來源: 顯示 | 在 GitHub 上
# File activerecord/lib/active_record/connection_handling.rb, line 50 def establish_connection(config_or_env = nil) config_or_env ||= DEFAULT_ENV.call.to_sym db_config = resolve_config_for_connection(config_or_env) connection_handler.establish_connection(db_config, owner_name: self, role: current_role, shard: current_shard) end
lease_connection() 連結
傳回目前與類別關聯的連線。這也可以用來「借用」連線,以執行與任何特定 Active Records 無關的資料庫工作。連線會在整個要求或工作期間保持外借,或直到呼叫了 #release_connection
。
來源: 顯示 | 在 GitHub 上
# File activerecord/lib/active_record/connection_handling.rb, line 269 def lease_connection connection_pool.lease_connection end
prohibit_shard_swapping(enabled = true) 連結
禁止在傳遞區塊中交換分片。
在某些情況下,你可能希望能夠交換分片,但卻不允許嵌套呼叫 connected_to
或 connected_to_many
再次交換。這在你使用分片來提供每次請求的資料庫隔離的情況下會很有用。
來源: 顯示 | 在 GitHub 上
# File activerecord/lib/active_record/connection_handling.rb, line 211 def prohibit_shard_swapping(enabled = true) prev_value = ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = enabled yield ensure ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = prev_value end
release_connection() 連結
將目前外借的連線歸還到池中
來源: 顯示 | 在 GitHub 上
# File activerecord/lib/active_record/connection_handling.rb, line 298 def release_connection connection_pool.release_connection end
remove_connection() 連結
# File activerecord/lib/active_record/connection_handling.rb, line 355 def remove_connection name = @connection_specification_name if defined?(@connection_specification_name) # if removing a connection that has a pool, we reset the # connection_specification_name so it will use the parent # pool. if connection_handler.retrieve_connection_pool(name, role: current_role, shard: current_shard) self.connection_specification_name = nil end connection_handler.remove_connection_pool(name, role: current_role, shard: current_shard) end
retrieve_connection() 連結
shard_keys() 連結
shard_swapping_prohibited?() 連結
判斷分片交換是否目前被禁止
sharded?() 連結
while_preventing_writes(enabled = true, &block) 連結
防止寫入資料庫,不論角色為何。
在某些情況下,您可能想要防止寫入資料庫,即使您正在可寫入的資料庫上。while_preventing_writes
將在區塊持續時間內防止寫入資料庫。
此方法並不提供與唯讀使用者相同的保護,而旨在避免意外寫入。
有關此方法封鎖的查詢,請參閱 READ_QUERY
。
with_connection(prevent_permanent_checkout: false, &block) 連結
從池中取出連線、回傳並放回。如果連線已經透過 lease_connection
或父級呼叫 with_connection
租用。相同的連線將回傳。如果在區塊內呼叫 lease_connection
,連線不會放回。如果在區塊內呼叫 connection
,除非 prevent_permanent_checkout
參數設定為 true
,否則連線不會放回。