PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Memodelkan objek besar PostgreSQL di Rails

Jika menggunakan ActiveRecord yang disertakan dengan Rails dengan salah satu adaptornya, satu-satunya pemetaan formal tipe database ke tipe Rails atau Ruby yang terjadi biasanya ditentukan dalam NATIVE_DATABASE_TYPES konstanta di adaptor yang dikembalikan melalui native_database_types metode. Untuk PostgreSQL di Rails 3.2.x, yaitu di ActiveRecord::ConnectionAdapters::PostgreSQLAdapter yang di sini . Jadi, untuk adaptor itu, tipe "biner" di Rails dipetakan ke tipe "bytea" di PG. Untuk beberapa jenis, Anda dapat mengganti jenis basis data yang dipetakannya menggunakan permata bernama activerecord-native_db_types_override . Tapi, kami ingin menggunakan objek besar, jadi...

Migrasi

Seperti yang dicatat Jim Deville di komentar, Anda dapat menentukan kolom yang diketik khusus di tabel seperti:

t.column :some_oid, 'blob_oid', :null => false

Jika Anda perlu melakukan lebih banyak lagi yang non-standar, Anda juga dapat menggunakan execute("SQL GOES HERE;") untuk membuat tabel menggunakan SQL langsung. Dan, jika Anda memiliki skema lama atau perubahan SQL yang telah dibuat di luar migrasi, pertimbangkan untuk menggunakan structure.sql (config.active_record.schema_format = :sql pilihan di config/application.rb dan kemudian lakukan:rake db:structure:dump ).

Objek Besar Baca/Tulis/Periksa Panjang/Hapus

Disalin dengan beberapa modifikasi untuk memperjelas, dll. dari:https://github.com/diogob/carrierwave-postgresql/blob/v0.1.0/lib/carrierwave/storage/postgresql_lo.rb :

Diperbarui :kita dapat tetapi tidak perlu memulai sebelum lo_read/lo_write/lo_lseek dan melakukan lo_close di blok sure karena per Dokumentasi PG "Setiap deskriptor objek besar yang tetap terbuka pada akhir transaksi akan ditutup secara otomatis." (terima kasih kepada Diogo atas infonya)

    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

Alih-alih connection , gunakan koneksi mentah dari model atau basis, mis. ActiveRecord::Base.connection.raw_connection (lihat ini ).

(...).transaction memanggil transaksi pada model atau basis, mis. ActiveRecord::Base.transaction (lihat ini ).

identifier adalah oid yang harus Anda lewati/set atau dapatkan hanya dengan melakukan connection.lo_creat .

Contoh/info lain:

Yang terakhir dan beberapa jawaban di sini menyarankan bahwa Anda mungkin ingin mempertimbangkan penyimpanan file besar yang terpisah dari DB, mis. sehingga Anda dapat menggunakan penyimpanan cloud. Tapi, jika hanya menyimpan path/ID ke file eksternal yang bukan dikelola oleh DB, Anda kehilangan konsistensi ACID (satu atau lebih catatan DB dapat menunjuk ke satu atau lebih file yang tidak ada atau satu atau lebih file bisa ada yang tidak memiliki satu atau lebih catatan terkait dalam database). Argumen lain untuk menyimpan file pada sistem file adalah Anda dapat melakukan streaming file, tetapi objek besar PG menyimpan file pada sistem file dengan cara yang dikelola oleh postgres untuk memastikan konsistensi ACID dan memungkinkan streaming (yang tidak dapat Anda lakukan dengan BLOB normal /Rails tipe biner). Jadi, itu hanya tergantung; beberapa menemukan penyimpanan di penyimpanan terpisah menggunakan referensi jalur sebagai opsi yang lebih baik, dan beberapa lebih memilih konsistensi ACID melalui Objek Besar.

Cara Mudah

Cukup gunakan CarrierWave dan carrierwave-postgresql .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Status HTTP 500 - java.lang.NoClassDefFoundError:java/time/temporal/TemporalField saat menjalankan aplikasi di OpenShift

  2. Gagal menghubungkan server AWS-Postgres dengan aplikasi boot musim semi dengan hosting heroku

  3. Memilih kolom dengan DISTINCT di PostgreSQL

  4. konversi tipe data MySQL SET ke Postgres

  5. Mendapatkan NoSuchMethodError:javax.persistence.Table.indexes() saat melakukan kueri JPA