Oops!!

プログラミングとかのラフなブログ

PlanetScaleのカラムを変更する手順

PlanetScaleのカラムを変更する手順

PlanetScaleですでに運用されているものの型やカラム名を変更したいことがあります。

Prismaを利用しているとマイグレーションファイルを作って、それをDBに反映していくのですが、PlanetScaleではprisma db pushで変更することが推奨されます。

その手順は以下です。

今回はSiteモデルのurlをvarchar(191)(prismaのStringのデフォルト)からvarchar(8190)(Apacheが受け付けられるURLの長さのデフォルト)へ変更したいと思います。

model Site {
  id      Int     @id @default(autoincrement())
  name    String  
  url     String
}

1. データを一時退避させるカラムを作成してpushする

model Site {
  id      Int     @id @default(autoincrement())
  name    String  
  url     String  
  tempUrl String? @db.VarChar(1048)
}

これをnpx prisma db pushで適用します。

2. データをコピーしてsiteのurlをnullにする

const records = await prisma.site.findMany({
  where: {
    tempUrl: null,
  },
  select: {
    id: true,
    url: true,
  },
});

const updatePromises = records.map(record => {
  return prisma.site.update({
    where: { id: record.id },
    data: { tempUrl: record.url, url: null},
  });
});

3. siteのurlカラムを削除する

model Site {
  id      Int     @id @default(autoincrement())
  name    String  
  tempUrl String? @db.VarChar(1048)
}

これをnpx prisma db pushします。

4. siteのurlカラムを再構築する

今度はurlを@db.VarChar(1048)で再構築します。

その際、urlは一旦String?で構築します。

model Site {
  id      Int     @id @default(autoincrement())
  name    String  
  url     String? @db.VarChar(1048)
  tempUrl String? @db.VarChar(1048)
}

これをnpx prisma db pushで適用します。

5. tempUrlの情報をurlに移行する

const records = await prisma.site.findMany({
  where: {
    url: null,
  },
  select: {
    id: true,
    tempUrl: true,
  },
});

const updatePromises = records.map(record => {
  return prisma.site.update({
    where: { id: record.id },
    data: { url: record.tempUrl, tempUrl: null},
  });
});

6. tempUrlを削除し、urlはNullを許容しないように設定

urlはStringに変更し、tempUrlは削除します。

データが全て入っていればNOT NULLへの変更は可能みたいです。

model Site {
  id      Int     @id @default(autoincrement())
  name    String  
  url     String  @db.VarChar(1048)
}

これをnpx prisma db pushで適用します。

手順が複雑でヒューマンエラーが起きそうですが、一応これが推奨みたいです。

プロフィール画像

すずき ゆうた

愛知県でフリーランスのフロントエンド・エンジニアをしています。Reactを用いた開発が得意です。 他にもプロジェクトマネジメントや組織マネジメントも行ってきました。エビデンスのない事でも自分の経験から書いていくので話半分くらいでお願いします。