Prisma ile Seeding oluşturma

Melih ŞAHİN
Kodcular
Published in
4 min readFeb 5, 2024

Merhabalar,

Bu yazımda Next js ile fullstack bir uygulama geliştirirken Prisma ORM kullanarak nasıl temel veriler oluşturulur onu anlatmaya çalışacağım.

Prisma nedir ne işe yarar?

Prisma”, geliştiricilere veritabanı işlemlerini yönetme ve sorgulama konusunda kolaylık sağlayan modern ve güçlü bir ORM aracıdır. Kısaca özellikleri:

  • Veritabanı Modelleri
  • İlişki oluşturma(Relations)
  • Sorgu Oluşturma
  • Veritabanı Bağlantısı
  • TypeScript Desteği
  • Migration Yönetimi

Seeding nedir ne işe yarar?

Seeding”, veritabanına başlangıç verilerini eklemek veya veritabanını örnek verilerle doldurmak anlamına gelir. Bu işlem, uygulamanın geliştirme, test veya başlangıç aşamasında kullanılabilecek veritabanı tablolarına varsayılan veya örnek verileri eklemeyi içerir. Seeding işlemi, bir uygulamanın doğru çalışabilmesi ve test edilebilmesi için gerekli veritabanı içeriğini sağlar.

Örnek projede Kullanılanlar:

Proje kurulum

Konumuz seeding olduğu için uygulama kurulumu ve veritabanı bağlantı işlemlerini çok fazla değinmeyeceğim.

  1. Next js kurulumu:
npx create-next-app@latest

2. Prisma ve diğer paketlerin kurulumu

// paket kurulumu
npm i prisma --save-dev
npm i @prisma/client

npx prisma // bu komutla prisma cli' yı kullanabilirsiniz.

npm i lodash
npm i @faker-js/faker --save-dev
npm i bcrypt

3. Veritabanı oluşturma ve kurulumu

a. Bilgisayarımıza PostgreSQL veritabanı kurulduğunu varsayıp example_db adında bir veritabanı oluşturalım. Ardından projemizde .env dosyası oluşturup burada veritabanı bağlantı url’ ini ekleyelim.

DATABASE_URL="postgresql://postgres:@localhost:5432/example_db?schema=public"

b. proje ana dizininde `prisma` adında bir klasör oluşturup içinde de `schema.prisma` adında model dosyasını oluşturalım. Bu dosya veritabanı tablolarımızı tanımladığımız kısım.

schema.prisma

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @db.VarChar(255)
content String @db.VarChar(255)
User User @relation(fields: [userId], references: [id])
userId Int
}

model User {
id Int @id @default(autoincrement())
email String @unique
createdAt DateTime @default(now())
name String @db.VarChar(255)
password String? @db.VarChar(255)
posts Post[]
}

c. ardından bu tabloları oluşturmak için şu komutu kullanıyoruz:

npx prisma db push

Veritabanını kontrol edersek tabloların oluştuğunu görmüş oluruz.

4. Seed Dosyası Oluşturma

prisma klasörünün içinde seed.ts dosyası oluşturalım ve temel yapıyı oluşturalım.

seed.ts

export default PostSeed;


import {PrismaClient} from "@prisma/client";

const prisma = new PrismaClient();

const main = async () => {
...
}

main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});

Şimdi main() fonksiyonu içinde tanımlayacağımız seeder yapısını oluşturalım. Burada Typescript’in gücünden faydalanacağız. Öncelikle birden fazla seeder dosyası olacağını varsayarak abstract bir class oluşturalım.

Seeder.ts

abstract class Seeder {
protected count: number; // ne kadar veri oluşturacağına karar verir
protected _data: any = []; // seed verisi

constructor(count: number) {
this.count = count;
}

protected abstract createData(): void; // veriyi oluşturacak fonksiyon

get data(): [] {
return this._data;
}
}

export default Seeder;

Şimdi de ilgili tablolar için seed dosyalarımızı oluşturalım.

userSeed.ts

import bcrypt from "bcrypt";
import range from "lodash/range";
import { faker } from "@faker-js/faker";

import Seeder from "./Seeder";

class UserSeed extends Seeder {
constructor(count: number = 10) {
super(count);
this.count = count;
this.createData();
}

createData() {
range(this.count).forEach(() => {
this._data.push({
name: faker.person.firstName(),
createdAt: faker.date.anytime(),
email: faker.internet.email(),
password: bcrypt.hashSync("12345678", 10),
});
});
}
}

export default UserSeed;

postSeed.ts

import range from "lodash/range";
import { faker } from "@faker-js/faker";

import Seeder from "./Seeder";

class PostSeed extends Seeder {
constructor(count: number = 10) {
super(count);
this.count = count;
this.createData();
}

createData() {
range(this.count).forEach(() => {
this._data.push({
title: faker.lorem.sentence(),
createdAt: faker.date.anytime(),
updatedAt: faker.date.anytime(),
content: faker.lorem.sentence(),
});
});
}
}

export default PostSeed;

seed.ts dosyasına geri dönüp oluşturduğumuz seeder’ ları ekleyelim.

seed.ts

import { Simulate } from "react-dom/test-utils";
import error = Simulate.error;
import { PrismaClient } from "@prisma/client";
import UserSeed from "./data/userSeed";
import PostSeed from "./data/postSeeder";

const prisma = new PrismaClient();

const main = async () => {
try {
await prisma.post.deleteMany();
await prisma.user.deleteMany();

const posts = new PostSeed();
const users = new UserSeed(3);

for (const user of users.data) {
await prisma.user.create({
data: {
...(user as any),
posts: {
create: posts.data,
},
},
});

}

console.log(`Database has been seeded. 🚀`);
} catch (e) {
throw error;
}
};

main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});

5. Seed komutu ekleme

oluşturduğumuz bu seeder’ları çalıştırmak için package.json dosyamıza bir komut eklememiz gerekiyor. Burada dikkat edilmesi gereken bazı hususlar var. Örneğin Next js projesiyle bu işlemi yaparken seed dosyasında modül ekleme hataları olabiliyor. Bunu engellemek için seed komutuna “compiler-options” flag’i eklemek gerek. Böylece işlem tetiklendiğinde modül hatası almayacağız.

package.json

"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"db-seed": "prisma db seed"
},
"prisma": {
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
},

Son olarak verilemizi oluşturacak komutu çalıştıralım.

npm run db-seed

Burada da görüldüğü gibi başarıyla test verilerimiz oluştu.😊

projenin kaynak kodlarına https://github.com/melihs/prisma-seeding-example bu linkten ulaşabilirsiniz

Bir sonraki yazıda görüşmek dileğiyle 👋🏻

--

--