如何在Prisma中批量复制数据库记录并为每条新记录生成唯一ID?
Alright, let's tackle your two related problems step by step. First, I'll cover the core logic behind copying records and assigning new unique IDs, then dive into the exact Prisma implementation for your specific dataset.
General Approach to Copying Records with New IDs
The key rule here is never duplicate the original ID (since IDs are unique constraints). The basic workflow looks like this:
- Fetch the original record(s) you want to copy, excluding the ID field (or just retain all other fields).
- Generate a new unique ID for each copy (the method depends on your database: UUIDs, auto-incrementing integers, etc.).
- Bulk insert the new records into the database, ensuring each has a unique ID to avoid constraint violations.
Prisma Implementation for Your Exact Dataset
Let's assume you have a Prisma model named TechStack matching your data structure (adjust the model name if yours is different):
model TechStack { id String @id @default(uuid()) // Uses UUIDs as the primary key, auto-generated by default title String }
Here's a complete, runnable script to copy each of your two base records 1000 times with unique IDs:
Option 1: Let Prisma/Database Auto-Generate IDs (Simplest)
This leverages Prisma's @default(uuid()) to let the database handle ID generation, so you don't have to generate UUIDs manually:
const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); async function bulkCopyRecords() { // Define your base records (we omit the original ID since we want new ones) const baseEntries = [ { title: "TailwindCSS" }, { title: "Apollo GraphQL" } ]; // Build the bulk insert array: 1000 copies per base entry const bulkRecords = []; for (const entry of baseEntries) { for (let i = 0; i < 1000; i++) { bulkRecords.push(entry); } } // Batch insert to avoid hitting database limits on single bulk inserts const batchSize = 1000; // Adjust based on your database's limits (most allow 1000+ per batch) for (let i = 0; i < bulkRecords.length; i += batchSize) { const batch = bulkRecords.slice(i, i + batchSize); await prisma.techStack.createMany({ data: batch, skipDuplicates: true // Optional: Skips any accidental duplicates (rare, but safe to include) }); } console.log(`Successfully inserted ${bulkRecords.length} new records!`); } // Run the function and clean up the Prisma client bulkCopyRecords() .catch((error) => console.error("Error inserting records:", error)) .finally(async () => await prisma.$disconnect());
Option 2: Manually Generate UUIDs (If You Need Control)
If you prefer to generate IDs yourself (e.g., for consistency with existing logic), use Node.js's built-in crypto module to generate UUIDs:
const { PrismaClient } = require('@prisma/client'); const crypto = require('crypto'); const prisma = new PrismaClient(); async function bulkCopyRecordsWithManualIDs() { const baseEntries = [ { title: "TailwindCSS" }, { title: "Apollo GraphQL" } ]; const bulkRecords = []; for (const entry of baseEntries) { for (let i = 0; i < 1000; i++) { bulkRecords.push({ id: crypto.randomUUID(), // Generate a unique UUID for each copy title: entry.title }); } } // Batch insert as before const batchSize = 1000; for (let i = 0; i < bulkRecords.length; i += batchSize) { const batch = bulkRecords.slice(i, i + batchSize); await prisma.techStack.createMany({ data: batch, skipDuplicates: true }); } console.log(`Successfully inserted ${bulkRecords.length} new records!`); } bulkCopyRecordsWithManualIDs() .catch((error) => console.error("Error inserting records:", error)) .finally(async () => await prisma.$disconnect());
Key Notes
- Batch Inserts: Most databases have limits on how many rows you can insert in a single query (e.g., MySQL's default is 1000). Splitting into batches prevents errors from exceeding these limits.
- Skip Duplicates: The
skipDuplicatesflag is optional but useful—it ensures that if a duplicate ID is accidentally generated (extremely unlikely with UUIDs), the entire batch won't fail. - Original IDs: We intentionally omit the original IDs from the base entries because inserting them would cause a unique constraint violation (those IDs already exist in your database).
内容的提问来源于stack exchange,提问作者robokonk

