You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nitrogen框架:能否将上传文件直接存入数据库(以RIAK-KV为例)

Directly Upload Files to Riak-KV in Nitrogen

Great question! Yes, you absolutely can skip Nitrogen's default ./scratch/ directory and upload files straight to Riak-KV without writing to local disk first. The key is to create a custom upload handler that captures the file data in memory and sends it directly to Riak during the upload process. Here's how to do it:

1. Build a Custom Upload Handler

Create an Erlang module (we'll call it my_riak_upload_handler.erl) that implements Nitrogen's nitro_upload_handler behavior. This handler will manage the upload stream, accumulate file data, and push it to Riak once the upload finishes.

-module(my_riak_upload_handler).
-behaviour(nitro_upload_handler).

-export([init/2, handle_upload/2, finish_upload/1]).

init(_UploadDetails, _Context) ->
    % Initialize state: start a Riak connection (adjust host/port to your setup)
    {ok, RiakPid} = riakc_pb:start_link("127.0.0.1", 8087),
    {ok, #{riak_pid => RiakPid, accumulated_data => <<>>}}.

handle_upload({file, FileName, _ContentType, DataChunk}, State) ->
    % Accumulate the incoming file chunks in state
    CurrentData = maps:get(accumulated_data, State),
    UpdatedData = <<CurrentData/binary, DataChunk/binary>>,
    % Store filename and updated data in state
    NewState = State#{accumulated_data => UpdatedData, filename => FileName},
    {ok, NewState}.

finish_upload(State) ->
    #{
        riak_pid := RiakPid,
        accumulated_data := FullFileBinary,
        filename := FileName
    } = State,

    % Prepare the Riak object: use a bucket of your choice, filename as key (or generate a unique one)
    RiakBucket = <<"user_uploads">>,
    RiakKey = list_to_binary(FileName),
    % Create the object with the full file binary and its content type
    RiakObject = riakc_obj:new(RiakBucket, RiakKey, FullFileBinary, "application/octet-stream"),

    % Save the object to Riak
    Result = case riakc_pb:put(RiakPid, RiakObject) of
        ok ->
            {success, #{riak_key => RiakKey}};
        {error, Reason} ->
            {failure, #{reason => Reason}}
    end,

    % Clean up the Riak connection (or reuse it with a pool for better performance)
    riakc_pb:stop(RiakPid),
    Result.

2. Configure Your Upload Element to Use the Handler

In your Nitrogen page code, specify your custom handler when rendering the #upload{} component:

render() ->
    #panel{children=[
        #upload{
            id = file_uploader,
            handler = my_riak_upload_handler,
            postback = upload_finished
        },
        #span{id = upload_status, text = "Ready to upload"}
    ]}.

3. Handle the Upload Completion Postback

Add an event handler in your page module to respond when the upload finishes, and update the UI with the result:

event(upload_finished) ->
    case wf:upload_result(file_uploader) of
        {success, #{riak_key := Key}} ->
            SuccessMsg = io_lib:format("Upload successful! Riak key: ~s", [binary_to_list(Key)]),
            wf:update(upload_status, #span{text = SuccessMsg, class = "success"});
        {failure, #{reason := Reason}} ->
            ErrorMsg = io_lib:format("Upload failed: ~p", [Reason]),
            wf:update(upload_status, #span{text = ErrorMsg, class = "error"})
    end.

Key Considerations for Production

  • Large Files: For big files, accumulating the entire binary in memory isn't ideal. Instead, use Riak's multipart upload API (via riakc_pb:put_chunk/4) to send chunks as they're received in handle_upload/2.
  • Connection Pools: Instead of opening/closing a Riak connection per upload, use a connection pool (like poolboy) to reuse connections and improve performance.
  • Metadata: To store extra info (like upload timestamp, user ID), add it to the Riak object's metadata using riakc_obj:update_metadata/2.
  • Error Handling: Expand the handler with retries for Riak connection failures, and validate file sizes/types before uploading.

内容的提问来源于stack exchange,提问作者Vianney Sserwanga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:43:11