PostgreSQL 加载图像到数据库

PostgreSQL load images to DB

我已经知道如何在数据库中存储图像,只需使用 bytea 输入我的 table

而且我已经可以通过我的项目 .net Core 中的代码将图像保存到数据库,我只是通过 url 获取图像并像那里一样保存:

using (HttpResponseMessage res = await client.GetAsync(photo_url))
  using (HttpContent content = res.Content) {
    byte[] imageByte = await content.ReadAsByteArrayAsync();
     using (NpgsqlConnection conn = new NpgsqlConnection("ConnectionString")) {
      conn.Open();
      using (NpgsqlTransaction tran = conn.BeginTransaction())
      using (NpgsqlCommand cmd = new NpgsqlCommand("Photo_Save", conn)) {           
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("photo", NpgsqlTypes.NpgsqlDbType.Bytea, imageByte);
        cmd.ExecuteScalar();           
        tran.Commit();
  }
}

效果不错

但我需要从我的电脑中保存到 table 个图像

有没有办法不用宿主机或者其他项目的代码,只用本地图片,连接Postges DB,就可以上传图片到数据库?

如果可以使用 psql,则可以使用 \lo_import 导入图像,并使用 lo_openloread 函数将内容读取为 bytea.

假设我想将文件 chuck.jpg 导入到 table blobs,并且文件不超过 1000000 字节,可以这样做:

test=> \lo_import chuck.jpg 
lo_import 152237

test=> INSERT INTO blobs VALUES (1, loread(lo_open(152237, 131072), 1000000));
INSERT 0 1

test=> \lo_unlink 152237
lo_unlink 152237

我用\lo_unlink删除了临时大对象。

假设图像采用以下方案:

CREATE TABLE images (
  owner_id uuid references users(user_id), 
  image_id uuid primary key,
  added_timestamp timestamp with time zone,
  img bytea
);

这个可以更顺利地做同样的事情而无需安装任何二进制文件(在我的例子中直接从 pgAdmin 和 Postgresql 11 工作)

create or replace function img_import(filename text)
  returns void
  volatile
  as $$
    declare
        content_ bytea;
        loid oid;
        lfd integer;
        lsize integer;
    begin
        loid := lo_import(filename);
        lfd := lo_open(loid,131072);
        lsize := lo_lseek(lfd,0,2);
        perform lo_lseek(lfd,0,0);
        content_ := loread(lfd,lsize);
        perform lo_close(lfd);
        perform lo_unlink(loid);

    insert into images values
    (uuid('66032153-0afc-4124-a50a-c4ea386f4684'), 
    uuid_generate_v4(),
    now(),
    content_);
    end;
$$ language plpgsql

感谢 this 来源的作者(用于导入 XML 的函数)。

也如其他答案中所指出的那样,如果需要,可以调整 lo_open(loid,131072); 以适应某些最大尺寸。