PrismaP
Prisma2mo ago
5 replies
Hornster

sql-template-tag in raw queries inconsistently breaking

I am using prisma in a nextjs application, where I use raw queries in several places due to limited support from prisma (e.g. unsupported postgis types, or bulk upserts).

A bulk upsert might look like this:
const inserts: Prisma.Sql[] = [];

// bulk insert based on e.g. a parsed csv file
for (const row of rows) {
  inserts.push(
    Prisma.sql`(${row.ts}::timestamp, ${row.scenario_id}, ${row.entity_id}, ${row.measurements}::jsonb)`
  );
}

await prismaClient.$executeRaw`INSERT INTO entity_measurements (
    ts,
    scenario_id,
    entity_id,
    measurements
  )
  VALUES ${Prisma.join(inserts)}
  ON CONFLICT (ts, scenario_id, entity_id) DO UPDATE SET measurements = EXCLUDED.measurements
`;


Using prisma's query event I can log both the resulting query and the list of parameters. If the query works, it produces a query where the ${Prisma.join(inserts)} is replaced with the full list of parameters in the form of ($1::timestamp, $2, $3, $4::jsonb), ($5::timestamp, $6, $7, $8::jsonb) ..., and the param list simply contains all the actual data - just as expected

However, very often this query produces a syntax error, in which case the following can be observed: ${Prisma.join(inserts)} is replaced with just one parameter $1, and params contains an object, where the actual parameters are stored in
values
, accompanied with the filler strings in strings. example:
const query = "INSERT INTO entity_measurements (ts, scenario_id, entity_id, measurements) VALUES $1  ON CONFLICT (ts, scenario_id, entity_id) DO UPDATE SET measurements = EXCLUDED.measurements"
const params = [{
  "values":["2025-12-09 12:00:00.000 Z", 1, 1, "{\"field\":\"value\"}"],
  "strings":["(","::timestamp, ",", ",", ","::jsonb)"]
}]

This will then throw a syntax error:
Raw query failed. Code: '42601' . Message: ERROR: syntax error at or near "$1"

It seems like for some reason the sql-template-tag breaks, and I have not found an explanation for why. Using the example above, the exact same input csv will sometimes work, and other times it produces the mentioned error.

For context:
Im running prisma 6.17.1 in nextjs 15.5.7, the target database is a postgres 17 instance. Previously this usually only happened in the next dev build, and restarting the dev server fixed it, but now it also happens in a production build. For production and development turbopack is being used.
Due to a multi-tenant scheme, I have to create a dedicated prisma client for every tenant, so that I can inject the tenant's schema name in the connection string.

Has anyone encountered a similiar issue, or might have a clue why these raw queries break so inconsistently? Help would be greatly appreciated.
Was this page helpful?