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

如何使用Prisma ORM将数据缓冲区存入PostgreSQL的Oid字段

问题分析

报错的核心原因是:PostgreSQL的Oid类型并非直接存储二进制数据,而是一个整数型标识符,指向PostgreSQL系统表pg_largeobject中的大对象(Large Object)。而你直接传入Buffer(二进制数据),和Prisma生成的Int类型(对应Oid)不匹配,导致类型错误。

两种解决方案

方案一:继续使用Oid存储大对象

需要先将Buffer写入PostgreSQL大对象,获取对应的Oid值,再存入data字段。步骤如下:

  1. 安装PostgreSQL客户端库
npm install pg
  1. 修改服务端代码,结合pg库操作大对象
import { Pool } from 'pg';
import { PrismaClient } from '@prisma/client';
import { Request, Response } from 'express';

const prisma = new PrismaClient();
// 复用Prisma的数据库连接配置
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

app.post("/img", async (req: Request | any, res: Response) => {
  const file = req.files.data;
  const pgClient = await pool.connect();

  try {
    await pgClient.query('BEGIN');
    
    // 1. 创建空的大对象,获取Oid
    const createRes = await pgClient.query('SELECT lo_create(0) AS oid');
    const oid = createRes.rows[0].oid;
    
    // 2. 打开大对象并写入Buffer数据
    const openRes = await pgClient.query('SELECT lo_open($1, $2) AS fd', [oid, 2032]); // 2032代表WRITE模式
    const fd = openRes.rows[0].fd;
    await pgClient.query('SELECT lo_write($1, $2, $3)', [fd, file.data, file.data.length]);
    
    // 3. 关闭大对象并提交事务
    await pgClient.query('SELECT lo_close($1)', [fd]);
    await pgClient.query('COMMIT');

    // 4. 用Prisma写入Oid到数据库
    const img = await prisma.image.create({
      data: {
        name: file.name,
        image_type: file.mimetype,
        image_size: file.size,
        data: oid, // 传入整数型Oid
      },
    });

    res.send({
      status: "success",
      data: img,
    });
  } catch (error) {
    await pgClient.query('ROLLBACK');
    console.error(error);
    res.status(500).send({ status: "error", message: "图片上传失败" });
  } finally {
    pgClient.release();
  }
});
  1. 注意事项
  • 删除image记录时,需要手动调用lo_unlink(oid)删除对应的大对象,避免垃圾数据残留;
  • 大对象适合存储GB级别的超大文件,日常小文件推荐用方案二。

方案二:改用Bytea直接存储二进制数据

如果你的图片文件不大(通常<1GB),直接用PostgreSQL的bytea类型存储更简单:

  1. 修改数据库表字段类型
ALTER TABLE image ALTER COLUMN data TYPE bytea;
  1. 更新Prisma Model
model image {
  id         String   @id @db.Uuid @default(uuid())
  data       Bytes    @db.Bytea // 替换原有的Int @db.Oid
  image_size BigInt
  image_type String?  @db.VarChar(25)
  name       String?  @db.VarChar(30)
  client     client[]
}
  1. 同步Schema到数据库
npx prisma db push
# 或使用迁移:npx prisma migrate dev
  1. 原服务端代码无需修改,直接运行即可(Prisma的Bytes类型支持直接传入Buffer)

内容的提问来源于stack exchange,提问作者Vasu Subbannavar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:20:32