PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Моделиране на големи обекти на PostgreSQL в Rails

Ако използвате ActiveRecord, който идва с Rails с един от неговите адаптери, единственото формално съпоставяне на тип база данни с тип Rails или Ruby, което се случва, обикновено се дефинира в NATIVE_DATABASE_TYPES константа в адаптера, която се връща чрез неговите native_database_types метод. За PostgreSQL в Rails 3.2.x, това е в ActiveRecord::ConnectionAdapters::PostgreSQLAdapter което е тук . И така, за този адаптер типът "двоичен" в Rails се преобразува в типа "bytea" в PG. За някои типове можете да замените този тип база данни, към който той се присвоява, като използвате gem, наречен activerecord-native_db_types_override . Но искаме да използваме големи обекти, така че...

Миграции

Както Джим Девил отбеляза в коментарите, можете да посочите персонализираната колона в таблицата като:

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

Ако трябва да направите дори повече, което е нестандартно, можете също да използвате execute("SQL GOES HERE;") за създаване на таблицата с помощта на прав SQL. И ако имате съществуваща наследена схема или промени в SQL, които са направени извън миграциите, обмислете използването на structure.sql (config.active_record.schema_format = :sql опция в config/application.rb и след това направете:rake db:structure:dump ).

Големи обекти Четене/Запис/Проверка на дължина/Изтриване

Копирано с някои модификации за изясняване и т.н. от:https://github.com/diogob/carrierwave-postgresql/blob/v0.1.0/lib/carrierwave/storage/postgresql_lo.rb :

Актуализирано :можем, но не е необходимо да поставяме начало преди lo_read/lo_write/lo_lseek и да правим lo_close в блока за осигуряване, защото според PG документация „Всички големи обектни дескриптори, които остават отворени в края на транзакцията, ще бъдат затворени автоматично.“ (благодарение на Диого за тази информация)

    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

Вместо connection , използвайте необработената връзка от модела или основата, напр. ActiveRecord::Base.connection.raw_connection (вижте това ).

(...).transaction извиква транзакция на модел или база, напр. ActiveRecord::Base.transaction (вижте това ).

identifier е oid, който или трябва да подадете/настроите, или да получите от просто извършване на connection.lo_creat .

Други примери/информация:

Последното и някои отговори тук предлагаме да помислите за съхранение на големи файлове отделно от DB, напр. така че да можете да използвате облачно хранилище. Но ако съхранявате само пътищата/идентификаторите към външни файлове, които не са управлявани от DB, вие губите ACID последователност (един или повече DB записи може да сочат към един или повече файлове, които не са там, или един или повече файлове може да съществуват, които нямат един или повече свързани записи в базата данни). Друг аргумент за съхраняване на файлове във файловата система е, че можете да предавате файлове поточно, но големият обект на PG съхранява файлове във файловата система по начин, управляван от postgres, за да осигури съвместимост на ACID и да позволи поточно предаване (което не можете да направите с нормален BLOB /Rails двоичен тип). Така че просто зависи; някои смятат, че съхраняването в отделно хранилище, използвайки препратки към пътя, е по-добър вариант, а някои предпочитат ACID последователност чрез големи обекти.

Лесният начин

Просто използвайте CarrierWave и 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. ГРЕШКА:липсва памет на машина с 32 GB RAM и без суап файл

  2. Стойността на първичния ключ не се увеличава правилно

  3. Postgres SQL за запитване на масив text[] в конкретен елемент

  4. Споделяне на вашите данни с PostgreSQL 11

  5. Клаузата UPDATE-FROM в jOOQ хвърля очакване за CTE поле