Nếu sử dụng ActiveRecord đi kèm với Rails với một trong các bộ điều hợp của nó, ánh xạ chính thức duy nhất của loại cơ sở dữ liệu sang loại Rails hoặc Ruby xảy ra thường được xác định trong NATIVE_DATABASE_TYPES
hằng số trong bộ điều hợp được trả về qua native_database_types
của nó phương pháp. Đối với PostgreSQL trong Rails 3.2.x, có trong ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
là đây
. Vì vậy, đối với bộ điều hợp đó, kiểu "nhị phân" trong Rails ánh xạ với kiểu "bytea" trong PG. Đối với một số loại, bạn có thể ghi đè loại cơ sở dữ liệu mà nó ánh xạ tới bằng cách sử dụng đá quý có tên activerecord-native_db_types_override . Tuy nhiên, chúng tôi muốn sử dụng các đối tượng lớn, vì vậy ...
Di chuyển
Như Jim Deville đã lưu ý trong các nhận xét, bạn có thể chỉ định cột được nhập tùy chỉnh trong bảng như:
t.column :some_oid, 'blob_oid', :null => false
Nếu bạn cần làm nhiều hơn nữa mà không phải là tiêu chuẩn, bạn cũng có thể sử dụng execute("SQL GOES HERE;")
để tạo bảng bằng SQL thẳng. Và, nếu bạn có một lược đồ kế thừa hiện tại hoặc các thay đổi SQL đã được thực hiện bên ngoài quá trình di chuyển, hãy xem xét sử dụng cấu trúc.sql (config.active_record.schema_format = :sql
trong config/application.rb
và sau đó thực hiện:rake db:structure:dump
).
Đối tượng lớn Đọc / Ghi / Kiểm tra Độ dài / Xóa
Đã sao chép một số sửa đổi cần làm rõ, v.v. từ: https://github.com/diogob/carrierwave-postgresql/blob/v0.1.0/lib/carrierwave/storage/postgresql_lo.rb :
Đã cập nhật :chúng ta có thể nhưng không cần bắt đầu trước lo_read / lo_write / lo_lseek và đặt lo_close trong khối ensure vì per Tài liệuPG "Bất kỳ bộ mô tả đối tượng lớn nào vẫn mở khi kết thúc giao dịch sẽ tự động bị đóng." (cảm ơn Diogo về thông tin đó)
require 'pg'
...
def read
(...).transaction do
lo = connection.lo_open(identifier)
content = connection.lo_read(lo, file_length)
connection.lo_close(lo)
content
end
end
def write(file)
(...).transaction do
lo = connection.lo_open(identifier, ::PG::INV_WRITE)
size = connection.lo_write(lo, file.read)
connection.lo_close(lo)
size
end
end
def delete
connection.lo_unlink(identifier)
end
def file_length
(...).transaction do
lo = connection.lo_open(identifier)
size = connection.lo_lseek(lo, 0, 2)
connection.lo_close(lo)
size
end
end
Thay vì connection
, sử dụng kết nối thô từ mô hình hoặc cơ sở, ví dụ:ActiveRecord::Base.connection.raw_connection
(xem điều này
).
(...).transaction
đang gọi giao dịch trên mô hình hoặc cơ sở, ví dụ:ActiveRecord::Base.transaction
(xem cái này
).
identifier
là oid mà bạn cần phải nhập / đặt hoặc nhận được khi chỉ thực hiện connection.lo_creat
.
Các ví dụ / thông tin khác:
- http://rubydoc.info/github/nedforce/devcms-core/ DbFile
- https://github.com/nedforce/devcms-core
- http://my.safaribooksonline.com/ book / web-development / ruby / 9780596510329 / database / largebinary_objects
Câu trả lời sau và một số câu trả lời tại đây gợi ý rằng bạn có thể muốn xem xét việc lưu trữ các tệp lớn tách biệt với DB, ví dụ:để bạn có thể sử dụng lưu trữ đám mây. Tuy nhiên, nếu chỉ lưu trữ các đường dẫn / ID đến các tệp bên ngoài thì không được quản lý bởi DB, bạn sẽ mất tính nhất quán ACID (một hoặc nhiều bản ghi DB có thể trỏ đến một hoặc nhiều tệp không có ở đó hoặc một hoặc nhiều tệp có thể tồn tại không có một hoặc nhiều bản ghi được liên kết trong cơ sở dữ liệu). Một đối số khác để lưu trữ tệp trên hệ thống tệp là bạn có thể truyền tệp, nhưng đối tượng lớn PG lưu trữ tệp trên hệ thống tệp theo cách được quản lý bởi postgres để vừa đảm bảo tính nhất quán của ACID vừa cho phép truyền trực tuyến (điều mà bạn không thể làm với BLOB thông thường / Rails kiểu nhị phân). Vì vậy, nó chỉ phụ thuộc; một số thấy lưu trữ trong bộ nhớ riêng bằng cách sử dụng tham chiếu đường dẫn là một lựa chọn tốt hơn và một số thích tính nhất quán ACID thông qua Đối tượng lớn.
Cách dễ dàng
Chỉ cần sử dụng CarrierWave và carrierwave-postgresql .