Soru Çoklu Veritabanlarıyla 3.1 Bağlama Bağlantısı


ShowNearby'de PHP'den RoR 3.1'e çok büyük bir göç yapıyoruz ve daha önce çözdüğünüz bazı problemlerle karşılaşıyoruz.

Büyük miktarda veriye sahibiz ve DB'mizi ayrı ele alabileceğimiz birkaç DB'ye ayırmaya karar verdik. Örneğin, hesaplarımız, yerlerimiz, günlüklerimiz ve diğer sitelerimiz çeşitli veritabanlarına ayrılmıştır.

Güzelce oynamak için göçler, fikstürler, modeller elde etmeliyiz ve şimdiye kadar oldukça dağınık. Bir çözümün kabul edilebilir olması için bazı gereksinimlerimiz:

  • Bir model veritabanlarından birinde bir tablo ile ilgili olmalıdır.
  • rake db: drop - database.yml içinde belirttiğimiz tüm veritabanı env bırakmalı
  • rake db: create - database.yml içinde belirttiğimiz tüm veritabanı env oluşturmalı
  • komisyon db: migrate - çeşitli veritabanlarına geçişleri çalıştırmalı
  • tırmık db: test - fikstürleri tutmalı ve bunları çeşitli veri tabanlarına ve test ünitesine / fonksiyonuna / vb.

Her veri tabanı için ayrı raylar projelendirmeyi ve bunları ActiveResource ile bağlamayı düşünüyoruz, ancak bunun çok verimli olmadığını düşünüyoruz. Daha önce benzer bir problemle uğraştınız mı?

Çok teşekkürler!!


76
2018-05-25 09:50


Menşei


Bir PHP uygulamasından bir raylı sisteme yükseltme yapmayı düşünüyoruz; Bununla ilgili herhangi bir şansın var mı? - Tommyixi
Merhaba @Tommyixi: Bu çok uzun zaman önceydi ve o zamandan beri çok şey değişti. Geriye dönüp bakıldığında, şimdi bunları bir veritabanına birden çok veritabanına ayırmaktan daha iyi bir çözüm olduğunu düşünüyorum. - Fer Martin


Cevaplar:


Wukerplank'ın cevabına göre, database.yml'deki bağlantı detaylarını da olduğu gibi bir adla da yapabilirsiniz:

log_database_production:
  adapter: mysql
  host: other_host
  username: logmein
  password: supersecret
  database: logs

Sonra özel modelinizde:

class AccessLog < ActiveRecord::Base
  establish_connection "log_database_#{Rails.env}".to_sym
end

Bu rahatsız edici kimlik bilgilerinin uygulama kodunuzda kalmasını engellemek için.

Düzenle: Bu bağlantıyı birden çok modelde yeniden kullanmak isterseniz, yeni bir soyut sınıf oluşturmalı ve onlardan miras almalısınız, çünkü bağlantılar sıkıca sınıflara bağlanır (açıklandığı gibi). İşte, İşte, ve İşte) ve her sınıf için yeni bağlantılar oluşturulacaktır.

Eğer durum buysa, şu şekilde ayarlayın:

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

141
2018-05-25 15:11



Çevreyi nasıl değiştirebilirim? Yani örneğin kalkınmak istiyorum establish_connection ile log_dev veritabanı ama üretimde istiyorum establish_connection ile log veri tabanı. Sadece telefon edebilir miyim Rails.env ? - Robert Audi
@AzizLight establish_connection "log_database_#{Rails.env}" - Unixmonkey
Korunmuş olun. Bu yöntemin kullanılması, ek veritabanlarındaki bağlantıları yeniden kullanmadan açık bırakmaktadır. Bu, ağır yük altında uygulamanızı durduracaktır. - Altonymous
@Altonymous İyi bir nokta. Bence bu davranışa atıfta bulunuyorsunuz: github.com/rails/rails/issues/7019 Bağlantı, sınıfa bağlı hale gelir; Bu nedenle, bağlantıyı yeniden kullanmanız gerekiyorsa, bunu soyut bir sınıfta oluşturmalı ve AR :: Base yerine ondan miras almalısınız. Cevabımı bunu yansıtmak için güncelledim. - Unixmonkey
Yeni bir şey yok, kontrol etmene gerek yok - mrbrdo


Farklı veritabanlarına bağlanmak oldukça kolaydır:

# 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

Denetleyicileriniz için veri alımına fazladan bir yük ekleyeceğinizden, birden fazla Rails projesi kurmaya karşı tedbirli olurdum, bu da işleri yavaşlatabilirdi.

Göçler, fikstürler, modeller vb. İle ilgili sorularınız için: Kolay bir yol olacağını düşünmüyorum, lütfen ayrı sorular gönderin ve mümkün olduğunca spesifik olun.

DB'leri tek haline getirmek bir seçenek değil midir? Hayatınızı çok daha kolaylaştıracak!


18
2018-05-25 10:06



Sorun şu ki, havuzlama yukarıdaki örneklem ile uygun şekilde kullanılmayacaktır - Sam Saffron


Bu check-out işlemini gerçekleştirmenin doğru yolunu başkalarına gösterecek harika bir yayın buldu http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html

Bunun gibi bir şey ayarlayın:

database.yml (db yapılandırma dosyası)

support_development:
    adapter: blah
    database: blah
    username: blah
    password: blah

support_base.rb (bir model dosyası)

class SupportBase < ActiveRecord::Base
    self.abstract_class = true #important!
    establish_connection("support_development")
end

tst_test.rb (bir model dosyası)

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, bu gerçekten geçişleri kapsamaz, ben bir komisyon ile birden fazla DB üzerinde göçler yapabileceğinizi sanmıyorum (her ne kadar zor bir 'yapamaz' emin değilim, mümkün olabilir). Bu, kontrol etmediğiniz diğer DB'leri bağlamak ve sorgulamak için harika bir yoldu.


11
2017-07-13 23:59





Rails ortamını da eklemek isteyebilirsiniz, bu yüzden geliştirme ve test veritabanlarınız aynı değildir.

establish_connection "legacy_#{Rails.env}"

4
2018-05-16 13:18





sonraki makale çoklu veritabanlarına karşı geçişleri gerçekleştirmek için yeni Rake görevlerinin tanımlanmasını önerir. Her görev kendi bağlantısını kurar ve ardından bu bağlantı ve belirli veritabanı klasörü ile geçişi yürütür.

Aynı zamanda tanıdık olanı tanımlar db:migrate Bu iki diğer görevi çağırır.

Buraya dahil olmak üzere bağlantı mevcut olmaz:

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

Kaynak:  Ruby on Rails Çoklu Veritabanlarına ve Göçlerine Bağlanma


3
2018-06-17 14:30





Hey bu yazı eski ama Rails 3.2 üzerinde çalışan ve başkalarına yardımcı olabilecek bir çözüm buldum. https://stackoverflow.com/a/16542724/1447654


1
2018-05-14 13:35