Câu hỏi Kết nối Rails 3.1 với nhiều cơ sở dữ liệu


Tại ShowNearby, chúng tôi đã tiến hành chuyển đổi rất lớn sang RoR 3.1 từ PHP và chúng tôi đang đối mặt với một số vấn đề mà có thể một số bạn đã giải quyết trước đó.

Chúng tôi có một lượng lớn dữ liệu và chúng tôi quyết định tách riêng DB của mình thành một số DB mà chúng tôi có thể xử lý riêng. Ví dụ: tài khoản, địa điểm, nhật ký và các tài khoản khác của chúng tôi được chia thành một số cơ sở dữ liệu

Chúng tôi cần phải có được di chuyển, đồ đạc, mô hình, để chơi độc đáo, và cho đến nay nó đã được khá lộn xộn. Một số yêu cầu của chúng tôi về giải pháp có thể chấp nhận được:

  • một mô hình nên liên quan đến một bảng trong một trong các cơ sở dữ liệu.
  • rake db: drop - nên thả tất cả các cơ sở dữ liệu env chúng tôi chỉ định trong database.yml
  • rake db: create - nên tạo tất cả các cơ sở dữ liệu env mà chúng tôi chỉ định trong database.yml
  • rake db: di chuyển - nên chạy di chuyển đến các cơ sở dữ liệu khác nhau
  • rake db: test - nên lấy đồ đạc và thả chúng vào các cơ sở dữ liệu khác nhau và kiểm tra đơn vị / chức năng / etc

Chúng tôi đang xem xét thiết lập các dự án đường ray riêng biệt cho mỗi cơ sở dữ liệu và kết nối chúng với ActiveResource, nhưng chúng tôi cảm thấy điều này không hiệu quả lắm. Có ai trong số các bạn đối phó với một vấn đề tương tự trước đây không?

Cám ơn rất nhiều!!


76
2018-05-25 09:50


gốc


Chúng tôi đang cân nhắc việc nâng cấp từ một ứng dụng PHP lên một đường ray; bạn có may mắn với điều này không? - Tommyixi
Hi @Tommyixi: đây là thời gian rất dài trước đây và rất nhiều đã thay đổi kể từ đó. Nhìn lại, tôi nghĩ rằng đó là một giải pháp tốt hơn để tổng hợp chúng thành một cơ sở dữ liệu hơn là tách nó thành nhiều cơ sở dữ liệu - Fer Martin


Các câu trả lời:


Với câu trả lời của Wukerplank, bạn cũng có thể đặt các chi tiết kết nối trong database.yml như thường lệ với một cái tên như sau:

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

Sau đó, trong mô hình đặc biệt của bạn:

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

Để giữ cho những thông tin đăng nhập pesky từ trong mã ứng dụng của bạn.

Chỉnh sửa: Nếu bạn muốn sử dụng lại kết nối này trong nhiều mô hình, bạn nên tạo một lớp trừu tượng mới và kế thừa từ nó, bởi vì các kết nối được kết nối chặt chẽ với các lớp (như được giải thích đây, đâyđây) và các kết nối mới sẽ được tạo cho mỗi lớp.

Nếu đúng như vậy, hãy thiết lập mọi thứ như sau:

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



Làm thế nào để giải thích cho sự thay đổi môi trường? Vì vậy, ví dụ trong phát triển tôi muốn establish_connection với log_dev cơ sở dữ liệu nhưng trong sản xuất tôi muốn establish_connection với log cơ sở dữ liệu. Tôi có thể gọi điện tới Rails.env ? - Robert Audi
@AzizLight establish_connection "log_database_#{Rails.env}" - Unixmonkey
Được cảnh báo trước. Có vẻ như sử dụng phương pháp này để lại các kết nối trên cơ sở dữ liệu bổ sung mở mà không cần sử dụng lại chúng. Điều này sẽ nghiền ứng dụng của bạn để dừng lại dưới tải nặng. - Altonymous
@Altonymous Tốt điểm. Tôi nghĩ rằng bạn đang đề cập đến hành vi này: github.com/rails/rails/issues/7019 Kết nối trở nên kết hợp với lớp; vì vậy nếu bạn cần tái sử dụng kết nối, bạn nên thiết lập nó trên một lớp trừu tượng và kế thừa từ nó thay vì AR :: Base. Tôi đã cập nhật câu trả lời của mình để phản ánh điều này. - Unixmonkey
không có gì mới ở đó, không cần phải kiểm tra - mrbrdo


Kết nối với các cơ sở dữ liệu khác nhau khá dễ dàng:

# 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

Tôi sẽ cảnh giác với việc thiết lập nhiều dự án Rails vì bạn sẽ bổ sung thêm rất nhiều chi phí để truy xuất dữ liệu cho các bộ điều khiển của mình, điều này có thể làm cho mọi thứ chậm đi.

Đối với câu hỏi của bạn về di chuyển, đồ đạc, mô hình, vv .. Tôi không nghĩ rằng sẽ có một cách dễ dàng, vì vậy xin vui lòng gửi câu hỏi riêng biệt và được cụ thể như bạn có thể.

Hợp nhất các DB thành một không phải là một lựa chọn? Nó sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều!


18
2018-05-25 10:06



rắc rối là kết nối tổng hợp sẽ không được sử dụng đúng cách với mẫu trên - Sam Saffron


Tìm thấy một bài đăng tuyệt vời sẽ chỉ cho người khác biết cách thực hiện việc thanh toán này đúng cách http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html

Thiết lập một cái gì đó như thế này:

database.yml (tệp cấu hình db)

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

support_base.rb (tệp mô hình)

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

tst_test.rb (tệp mô hình)

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, điều này thực sự không bao gồm di chuyển, tôi không nghĩ rằng bạn có thể làm di chuyển trên nhiều hơn một DB với rake (mặc dù tôi không chắc chắn đó là một khó 'không thể làm', nó có thể có thể). Đây chỉ là một cách tuyệt vời để kết nối và truy vấn các DB khác mà bạn không kiểm soát.


11
2017-07-13 23:59





Bạn cũng có thể muốn gắn thêm môi trường Rails, vì vậy cơ sở dữ liệu phát triển và kiểm thử của bạn không giống nhau.

establish_connection "legacy_#{Rails.env}"

4
2018-05-16 13:18





Các bài viết sau gợi ý xác định các nhiệm vụ Rake mới để đạt được sự di chuyển đối với nhiều cơ sở dữ liệu. Mỗi tác vụ thiết lập kết nối của riêng nó và sau đó thực hiện việc di chuyển với kết nối này và thư mục cơ sở dữ liệu cụ thể.

Nó cũng định nghĩa một người quen thuộc db:migrate gọi hai nhiệm vụ khác.

Bao gồm ở đây trong trường hợp liên kết không khả dụng:

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

Nguồn:  Ruby on Rails Kết nối với nhiều cơ sở dữ liệu và di chuyển


3
2018-06-17 14:30





Hey bài đăng này là cũ nhưng tôi đã tìm thấy một giải pháp làm việc trên Rails 3,2 có thể giúp đỡ người khác. https://stackoverflow.com/a/16542724/1447654


1
2018-05-14 13:35