Łączenie Rails 3.1 z wieloma bazami danych
W ShowNearby wykonaliśmy bardzo dużą migrację do RoR 3.1 z PHP i mamy do czynienia z kilkoma problemami, które być może niektórzy z Was już rozwiązali.
Mamy duże ilości danych i postanowiliśmy podzielić nasze DB na kilka DB, które możemy obsłużyć osobno. Na przykład nasze konta, miejsca, dzienniki i inne są podzielone na kilka baz danych
Musimy zrobić migracje, oprawy, modele, aby grać ładnie, a do tej pory było dość niechlujnie. Niektóre z naszych wymagania dotyczące dopuszczalnego rozwiązania:
- Jeden model powinien odnosić się do jednej tabeli w jednej z baz danych.
- rake db : drop - powinien upuścić całą bazę danych ENV, którą podajemy w bazie danych.yml
- rake db: create - należy utworzyć całą bazę danych ENV, którą podamy w bazie danych.yml
- rake db: migrate-powinno uruchamiać migracje do różnych baz danych
- rake db: test - należy chwycić uchwyty i wrzucić je do różnych baz danych i przetestować unit / function / etc
Rozważamy ustawienie oddzielnych projektów rails dla każdej bazy danych i połączenie ich z ActiveResource, ale uważamy, że nie jest to zbyt efektywne. Czy ktoś z Was miał wcześniej podobny problem?
Wielkie dzięki!!
6 answers
Aby uzyskać odpowiedź Wukerplank, możesz również umieścić szczegóły połączenia w bazie danych.yml jak zwykle z taką nazwą:
log_database_production:
adapter: mysql
host: other_host
username: logmein
password: supersecret
database: logs
Następnie w Twoim specjalnym modelu:
class AccessLog < ActiveRecord::Base
establish_connection "log_database_#{Rails.env}".to_sym
end
Żeby te brzydkie poświadczenia nie znalazły się w Twoim kodzie aplikacyjnym.
Edit: Jeśli chcesz ponownie użyć tego połączenia w wielu modelach, powinieneś utworzyć nową abstrakcyjną klasę i dziedziczyć z niej, ponieważ połączenia są ściśle powiązane z klasami (jak wyjaśniono tutaj, tutaj , i tutaj ), a nowe połączenia będą tworzone dla każdej klasy.
Jeśli tak jest, Ustaw rzeczy tak:
class LogDatabase < ActiveRecord::Base
self.abstract_class = true
establish_connection "log_database_#{Rails.env}".to_sym
end
class AccessLog < LogDatabase
end
class CheckoutLog < LogDatabase
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-14 15:47:01
Łączenie się z różnymi bazami danych jest dość łatwe:
# model in the "default" database from database.yml
class Person < ActiveRecord::Base
# ... your stuff here
end
# model in a different database
class Place < ActiveRecord::Base
establish_connection (
:adapter => "mysql",
:host => "other_host",
:username => "username",
:password => "password",
:database => "other_db"
)
end
Byłbym ostrożny w konfigurowaniu wielu projektów Rails, ponieważ dodasz wiele narzutu do pobierania danych dla swoich kontrolerów, co może spowolnić działanie.
Jeśli chodzi o Twoje pytania dotyczące migracji, osprzętu, modeli itp.: Myślę, że nie będzie łatwego sposobu, więc proszę pisać osobne pytania i być jak najbardziej szczegółowym.
Konsolidacja DBs w jeden nie wchodzi w grę? To uczyniłoby twoje życie dużo łatwiej!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-25 10:06:06
Znalazłem świetny post, który wskaże innym właściwy sposób zrobienia tego Sprawdź http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html
Ustaw coś takiego:
Baza Danych.yml (plik konfiguracyjny db)
support_development:
adapter: blah
database: blah
username: blah
password: blah
Support_base.rb (plik modelu)
class SupportBase < ActiveRecord::Base
self.abstract_class = true #important!
establish_connection("support_development")
end
Tst_test.rb (plik modelu)
class TstTest < SupportBase
#SupportBase not ActiveRecord is important!
self.table_name = 'tst_test'
def self.get_test_name(id)
if id = nil
return ''
else
query = "select tst_name from tst_test where tst_id = \'#{id}\'"
tst = connection.select_all(query) #select_all is important!
return tst[0].fetch('tst_name')
end
end
end
PS, to naprawdę nie obejmuje migracji, nie sądzę, że można zrobić migracje na więcej niż jeden DB z rake (chociaż nie jestem oczywiście, że jest to trudne "nie można", to może być możliwe). To był po prostu świetny sposób na łączenie się i odpytywanie innych DBs, których nie kontrolujesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-28 00:34:39
Możesz również dodać środowisko Rails, więc Twoje bazy danych programistycznych i testowych nie są takie same.
establish_connection "legacy_#{Rails.env}"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-16 13:18:50
Następujący artykuł sugeruje zdefiniowanie nowych zadań Rake w celu uzyskania migracji z wielu baz danych. Każde zadanie tworzy własne połączenie, a następnie wykonuje migrację z tym połączeniem i określonym folderem bazy danych.
Definiuje również znane db:migrate
, które wywołuje dwa pozostałe zadania.
W tym miejscu link staje się niedostępny:
desc "Migrate the database through scripts in db/migrate directory."
namespace :db do
task :migrate do
Rake::Task["db:migrate_db1"].invoke
Rake::Task["db:migrate_db2"].invoke
end
task :migrate_db1 do
ActiveRecord::Base.establish_connection DB1_CONF
ActiveRecord::Migrator.migrate("db/migrate/db1/")
end
task :migrate_db2 do
ActiveRecord::Base.establish_connection DB2_CONF
ActiveRecord::Migrator.migrate("db/migrate/db2/")
end
end
Źródło: Ruby on Rails łączy się z wieloma bazami danych i migracjami
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-17 14:30:45
Hej ten post jest stary, ale znalazłem rozwiązanie działające na Rails 3.2, które może komuś pomóc. https://stackoverflow.com/a/16542724/1447654
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:34