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_open
和 loread
函数将内容读取为 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);
以适应某些最大尺寸。
我已经知道如何在数据库中存储图像,只需使用 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_open
和 loread
函数将内容读取为 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);
以适应某些最大尺寸。