sql >> データベース >  >> RDS >> PostgreSQL

RailsでのPostgreSQLの大きなオブジェクトのモデリング

    アダプターの1つとともにRailsに付属するActiveRecordを使用する場合、発生するデータベースタイプからRailsまたはRubyタイプへの唯一の正式なマッピングは、通常、NATIVE_DATABASE_TYPESで定義されます。 native_database_typesを介して返されるアダプター内の定数 方法。 Rails 3.2.xのPostgreSQLの場合、それはActiveRecord::ConnectionAdapters::PostgreSQLAdapterにあります これはこちらです 。したがって、そのアダプターの場合、Railsの「binary」タイプはPGの「bytea」タイプにマップされます。一部のタイプでは、 activerecord-native_db_types_override 。しかし、大きなオブジェクトを使用したいので...

    移行

    Jim Devilleがコメントで述べたように、次のようにテーブルにカスタム型付き列を指定できます。

    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

    更新PGドキュメント 「トランザクションの終了時に開いたままの大きなオブジェクト記述子は、自動的に閉じられます。」 (その情報を提供してくれたDiogoに感謝します)

        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 は、渡す/設定するか、connection.lo_creatを実行するだけで取得する必要があるOIDです。 。

    その他の例/情報:

    後者といくつかの回答ここ DBとは別に大きなファイルの保存を検討することをお勧めします。クラウドストレージを使用できるようにします。ただし、ではない外部ファイルへのパス/IDのみを保存する場合 DBによって管理されると、ACIDの整合性が失われます(1つ以上のDBレコードが、存在しない1つ以上のファイルを指しているか、データベースに1つ以上の関連レコードがない1つ以上のファイルが存在する可能性があります)。ファイルシステムにファイルを保存するためのもう1つの議論は、ファイルをストリーミングできるということですが、PGラージオブジェクトはpostgresによって管理される方法でファイルをファイルシステムに保存し、ACIDの一貫性を確保し、ストリーミングを許可します(通常のBLOBでは実行できません)。 / Railsバイナリタイプ)。だから、それはただ依存します。パス参照を使用して別のストレージに保存する方がよいオプションを見つける人もいれば、ラージオブジェクトを介したACIDの一貫性を好む人もいます。

    簡単な方法

    CarrierWave を使用するだけです およびcarrierwave-postgresql 。




    1. 誰でもこのクエリを説明できますか?

    2. Eloquentの2つのレコード間の値の差を計算する

    3. xマイル半径内の他の行のmySQL経度および緯度クエリ

    4. #1054on句エラーの不明な列