Aufgabe 17 - ORM und Migrationen mit Prisma
Aufgabe 17 - ORM und Migrationen mit Prisma
Abschnitt betitelt „Aufgabe 17 - ORM und Migrationen mit Prisma“Worum geht es?
Abschnitt betitelt „Worum geht es?“In dieser Übung wird ein Next.js-Projekt über das ORM Prisma mit einer laufenden PostgreSQL-Datenbank verbunden (siehe Kapitel 9 - Integration in Webanwendungen). Der Fokus liegt auf den Datenbankkonzepten dahinter: ein Schema im Code, was bei Migrationen in der Datenbank passiert und wie man das N+1-Problem vermeidet.
Was Sie dafür brauchen
Abschnitt betitelt „Was Sie dafür brauchen“- Kapitel 9 - Integration in Webanwendungen.
- Eine laufende Docker-PostgreSQL-Umgebung; Node.js (≥ 18) und npm;
psqloder pgAdmin.
Welche Kompetenzen Sie erwerben und zeigen
Abschnitt betitelt „Welche Kompetenzen Sie erwerben und zeigen“- Sie verbinden ein ORM mit einer Datenbank über einen Connection String.
- Sie definieren ein Schema im Code und beschreiben Beziehungen.
- Sie erzeugen und verstehen versionierte Migrationen.
- Sie erkennen und lösen das N+1-Problem mit Eager Loading.
Pädagogische Einordnung
Abschnitt betitelt „Pädagogische Einordnung“- Reproduktion: Projekt und Prisma einrichten (Teil A).
- Reorganisation und Transfer: Schema definieren und migrieren (Teile B und C).
- Reflexion, Problemlösung und Urteilsbildung: das N+1-Problem beobachten, lösen und beurteilen (Teil D).
Arbeitsaufträge
Abschnitt betitelt „Arbeitsaufträge“Die Übung ist auf etwa zwei Stunden ausgelegt. Teil D ist der Expertenteil.
Teil A - Projekt einrichten und Prisma verbinden
Abschnitt betitelt „Teil A - Projekt einrichten und Prisma verbinden“Zuerst schriftlich: Unterschied ORM gegen nativen Treiber (pg); was steckt in einem Connection String (DATABASE_URL); warum gehört er in eine .env-Datei und nicht in den Code?
-
Ein Next.js-Projekt anlegen:
Terminal-Fenster npx create-next-app@latest schoolblog --typescript --app --no-tailwind --no-eslint --src-dircd schoolblog -
Die Datenbank
schoolblogmanuell anlegen (CREATE DATABASE schoolblog;), da Prisma nur Tabellen, aber keine Datenbank erstellt. -
Prisma installieren und initialisieren, dann die
DATABASE_URLin.envanpassen:Terminal-Fenster npm install prisma @prisma/clientnpx prisma initDATABASE_URL="postgresql://pgadmin:postgres-root-password@localhost:5432/schoolblog"
Teil B - Schema definieren und erste Migration
Abschnitt betitelt „Teil B - Schema definieren und erste Migration“Zuerst schriftlich: Was ist eine Migration und warum als Datei in der Versionsverwaltung? Unterschied prisma migrate dev gegen prisma migrate deploy? Was passiert in der Datenbank beim Hinzufügen einer Spalte?
-
In
prisma/schema.prismadas Schema definieren:model User {id Int @id @default(autoincrement())email String @uniquename Stringposts Post[]createdAt DateTime @default(now())}model Category {id Int @id @default(autoincrement())name String @uniqueposts Post[]}model Post {id Int @id @default(autoincrement())title Stringcontent String?published Boolean @default(false)author User @relation(fields: [authorId], references: [id])authorId Intcategory Category @relation(fields: [categoryId], references: [id])categoryId IntcreatedAt DateTime @default(now())}Festhalten: Welche Beziehungstypen bestehen? Was bedeutet
@relation(...)(welche SQL-Konstruktion), und was@unique? -
Die erste Migration ausführen und auf zwei Wegen kontrollieren:
Terminal-Fenster npx prisma migrate dev --name initIn
prisma/migrations/*/migration.sqlden generierten SQL-Code prüfen und in der Datenbank mit\dtund\d "Post"nachsehen, ob die Fremdschlüssel angelegt wurden.
Teil C - Schema erweitern: zweite Migration
Abschnitt betitelt „Teil C - Schema erweitern: zweite Migration“-
Dem Modell
Postein FeldupdatedAt DateTime? @updatedAthinzufügen und migrieren:Terminal-Fenster npx prisma migrate dev --name add_updated_at_to_postIn der neuen
migration.sqldenALTER TABLEprüfen und begründen, warum das Feld nullable ist (was beiNOT NULLohne Default an einer befüllten Tabelle passieren würde). -
Den Migrationsverlauf prüfen:
SELECT migration_name, finished_at FROM "_prisma_migrations" ORDER BY finished_at;Reflexion: Was meldet Prisma, wenn man eine bereits angewandte Migrationsdatei nachträglich editiert? Wann ist
prisma migrate resetsinnvoll, und warum ist es in der Produktion gefährlich?
Teil D - Expertenteil: Das N+1-Problem beobachten und lösen
Abschnitt betitelt „Teil D - Expertenteil: Das N+1-Problem beobachten und lösen“Zuerst schriftlich: Was ist das N+1-Problem (am Beispiel Posts/Autoren)? Unterschied include gegen select? Warum ein globaler Prisma-Client-Singleton?
-
Einen Prisma-Client-Singleton
src/lib/prisma.tsanlegen (mitlog: ['query'], damit jede SQL-Abfrage im Terminal sichtbar ist). -
Testdaten über
prisma/seed.tseinfügen (zwei User, zwei Kategorien, vier Posts) und mitnpx prisma db seedladen. -
N+1 beobachten: Eine
src/app/blog/page.tsxmit absichtlich fehlerhafter Logik schreiben, die zuerst alle Posts lädt und dann pro Post den Autor einzeln nachlädt:const posts = await prisma.post.findMany({ where: { published: true } });// one separate query per post:const author = await prisma.user.findUnique({ where: { id: post.authorId } });Den Dev-Server starten (
npm run dev),/blogaufrufen und im Terminal zählen, wie viele SQL-Abfragen laufen und welche sich wiederholen. Was ändert sich mit einem fünften Post? -
N+1 lösen: Die Abfrage durch eine einzige mit Eager Loading ersetzen:
const posts = await prisma.post.findMany({where: { published: true },include: {author: { select: { name: true } },category: { select: { name: true } },},orderBy: { createdAt: 'desc' },});Erneut laden und im Terminal prüfen, dass nur noch eine Abfrage läuft; den
JOINin der generierten SQL finden. -
Selektiv laden: Eine Abfrage schreiben, die nur
titleund dennamedes Autors lädt (selectstattinclude), und die generierte SQL mit der aus Schritt 4 vergleichen. -
Reflexion: Warum ist das N+1-Problem in Eloquent/Laravel (Lazy Loading) besonders tückisch? Wann wäre eine separate Abfrage sinnvoller als
include? Was passiert bei 10.000 Posts, wenn das Problem unbemerkt bleibt?
Wissenscheck
Abschnitt betitelt „Wissenscheck“-
Sie finden einen Tippfehler in einer bereits eingecheckten und angewandten Migration. Dürfen Sie die Datei direkt editieren? Beschreiben Sie das korrekte Vorgehen.
-
Erklären und korrigieren Sie:
const categories = await prisma.category.findMany();for (const cat of categories) {const posts = await prisma.post.findMany({ where: { categoryId: cat.id } });console.log(`${cat.name}: ${posts.length} Posts`);} -
Nennen Sie zwei Situationen, in denen man trotz ORM auf direktes SQL (
prisma.$queryRaw) zurückgreifen sollte.
- Ein Word- oder PDF-Dokument mit den Antworten auf alle Theorie- und Reflexionsfragen, Screenshots der beiden
migration.sql, der Tabellenstruktur, der_prisma_migrations-Tabelle sowie der Terminal-Ausgabe mit dem N+1-Problem (Schritt 3) und nach der Lösung (Schritt 4), dazu der fertige Code vonpage.tsx.
HTL Villach, Schuljahr 2025-2026,
https://www.htl-villach.at