3.0 KiB
3.0 KiB
TaylorDB Attachments
Attachments are treated as standard columns and can be selected and written like other fields, using helper utilities for uploads.
This document covers:
- Selecting attachment fields
- Creating records with attachments
- Updating attachments
Select Attachments
// New Standard: Use regular .select() like any other field.
const expenses = await qb
.selectFrom("expenses")
.select(["id", "amount", "receipt"])
.execute();
Create with Attachments
Use qb.uploadAttachments to upload files before inserting.
await qb
.insertInto("customers")
.values({
firstName: "Jane",
lastName: "Doe",
avatar: await qb.uploadAttachments([
{ file: new Blob([""]), name: "test.png" },
]),
})
.execute();
Update with Attachments
await qb
.update("customers")
.set({
lastName: "Smith",
avatar: await qb.uploadAttachments([
{ file: new Blob([""]), name: "test.png" },
]),
})
.where("id", "=", 1)
.execute();
Receiving Files via tRPC 11 Multipart FormData
tRPC 11 supports multipart/form-data natively using z.instanceof(FormData) as the procedure input. File objects arrive directly in the mutation — no separate upload endpoint needed.
Server (tRPC router):
import { z } from "zod";
import { router, publicProcedure } from "../trpc";
export const myRouter = router({
submit: publicProcedure
.input(z.instanceof(FormData))
.mutation(async ({ input, ctx }) => {
const name = input.get("name") as string | null;
const files = input.getAll("files") as File[];
// Upload files directly to TaylorDB
const attachments = await ctx.queryBuilder.uploadAttachments(
files.map((file) => ({ file, name: file.name }))
);
await ctx.queryBuilder
.insertInto("submissions")
.values({ name, documents: attachments })
.execute();
}),
});
Client (tRPC React Query):
FormData mutations must bypass request batching. Use splitLink in your tRPC client setup:
import { splitLink, httpLink, httpBatchLink } from "@trpc/client";
trpc.createClient({
links: [
splitLink({
condition: (op) => op.input instanceof FormData,
true: httpLink({ url: trpcUrl }),
false: httpBatchLink({ url: trpcUrl }),
}),
],
});
Then call the mutation with a FormData object:
const formData = new FormData();
formData.append("name", name);
files.forEach((file) => formData.append("files", file));
await submitMutation.mutateAsync(formData);
For more topics, see:
TAYLORDB_BASIC_QUERIES.mdfor basic reads and filteringTAYLORDB_WRITE_OPERATIONS.mdfor inserts, updates, and deletesTAYLORDB_ADVANCED_PATTERNS.mdfor aggregations, pagination, and conditional queriesTAYLORDB_FIELD_TYPES.mdfor field type handling and enumsTAYLORDB_PITFALLS_BEST_PRACTICES.mdfor pitfalls and best practices