Cloud SQL & Cloud Functions (2nd gen.) でPrismaを使ってみる
前提
- 筆者はPrisma初挑戦
- ORMの経験はRailsのActive Recordくらい。
→ 記事の水準を担保できないので、スクラップにしました。
目標
Prismaを使い、
- CloudSQLへの接続
- ローカル
- Cloud Functions上
- CloudSQLのmigration
- CloudSQLへの書き込み
- ローカル
- Cloud Functions上
を行う。
環境
- 2023年10月
- MacBook Air (M1, 2020)
- Node.js v. 18.18.1
- Prisma 5.4.2
参考資料
CloudSQLの作成
dev-prisma
の名前で作成。スペックは最小構成。
試用なので、以後、rootユーザーを使う。
Cloud Functions作成
firebase init functions
でTypeScriptプロジェクトを作成
Prisma導入
npm install prisma
npx prisma init
.env
とschema.prisma
が作成される。
schema.prismaの作成
寄付フォームからのデータを想定して、下記のようにした。[1]
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model FormValue {
id Int @id @default(autoincrement())
first_name String
first_name_kana String
last_name String
last_name_kana String
email String
amount Int
anonymous Boolean? @default(false)
receipt Boolean? @default(false)
project String
}
.envの設定
DATABASE_URL
を設定する。
mysql://<username>:<password>@localhost/<db_name>?socket=/cloudsql/<接続名>
接続名はCloudSQLの管理画面にある。
-
GPT-4は2022年までの学習データを持っており、Prismaをカバーしているので、TypeScriptの型情報を渡せば作ってもらえる。 ↩︎
Cloud SQL Auth Proxyでローカル接続
Cloud SQL Auth Proxy導入
公式ドキュメントをもとに下記を実行(環境によって異なります。)
curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.6.1/cloud-sql-proxy.darwin.amd64
chmod +x cloud-sql-proxy
Cloud SQL Admin APIも有効化
Cloud SQL Auth Proxy実行
portは1234に指定しています。
./cloud-sql-proxy --port 1234 <接続名>
エラー
下記の認証エラーに遭遇。
The proxy has encountered a terminal error: unable to start: error initializing dialer: failed to create token source: google: could not find default credentials. See https://cloud.google.com/docs/authentication/external/set-up-adc for more information
以下でCloudSQLのプロジェクトのアカウントで認証しなおして解消。
gcloud auth login
gcloud config set project <your project id>
gcloud auth application-default login
Migration
portを書き換えたので、下記のように変更。
DATABASE_URL="mysql://<username>:<password>@localhost:1234/<db_name>"
ターミナルで下記を実行
npx prisma migrate dev --name init
すると、migrations
フォルダが作成される。
DBeaverで確認してみる。
接続方法は下記。localhostのDBとして接続できる。
Prismaのコマンド
npx prisma migrate dev
は開発環境用。本番環境では
npx prisma migrate deploy
を CI/CDで実行するべし、とのこと。
GitHub Actionsの例が載っている。
CloudSQLへの書き込み 〜ローカル編〜
Prisma Clientのインストール
書き込みなどのクエリを実行する際にはPrisma Client
を用いる。
npm install @prisma/client
ローカルでレコード追加
Cloud Functionsのプロジェクトで下記のテストコードを作成、実行。[1]
import { PrismaClient } from '@prisma/client'
async function test() {
const prisma = new PrismaClient()
const entry = await prisma.formValue.create({ // 型情報から補完が効く
data: {
"first_name": "太郎",
"first_name_kana": "タロウ",
"last_name": "山田",
"last_name_kana": "ヤマダ",
"email": "hoge@example.or.jp",
"amount": 1000,
"anonymous": false,
"receipt": false,
"project": "test_project",
},
})
return entry
}
test().then((entry) => console.log(entry))
DBeaver等で追加を確認。
-
ts-nodeを使用。 ↩︎
CloudSQLへの書き込み 〜Cloud Functions編〜
Cloud Functions作成
簡単なCloud Functionsを作成する。
.env
mysql://<username>:<password>@localhost/<db_name>?socket=/cloudsql/<接続名>
データベース処理
import { PrismaClient } from "@prisma/client"
import { FormData } from "./type"
export async function insertEntry(formData: FormData) {
const prisma = new PrismaClient()
try {
await prisma.formValue.create({
data: {
first_name: formData.first_name, // オブジェクトは敢えて開いて書いている。
first_name_kana: formData.first_name_kana,
last_name: formData.last_name,
last_name_kana: formData.last_name_kana,
email: formData.email,
amount: Number(formData.amount),
anonymous: formData.anonymous,
receipt: formData.receipt,
project: formData.project,
},
}),
console.log("successfully inserted")
} catch (e) {
console.error("DB Error: ", e)
}
}
型定義
export type FormData = {
first_name: string;
first_name_kana: string;
last_name: string;
last_name_kana: string;
email: string;
amount: number;
anonymous?: boolean;
receipt?: boolean;
project: string;
};
エントリーポイント
import * as functions from "firebase-functions/v2";
import { FormData } from "./type";
import { insertEntry } from "./database";
export const prismaTest = functions.https.onRequest(
{
region: "asia-northeast1",
},
async (req, res) => {
const formData = req.body as FormData;
await insertEntry(formData)
res.send("ok");
}
)
Cloud Functionsのデプロイ
firebase deploy --only functions
下記の通り、v2をimportしているのでCloud Functionsは第二世代としてdeployされる。
import * as functions from "firebase-functions/v2";
Cloud Functionsの管理画面から「未認証の呼び出しを許可する」を有効化
CloudRunでCloudSQL接続設定
CloudRunを開き、CloudSQLへAuth Proxyで接続できるように設定。
*設定後、Cloud Functionsの再デプロイが必要。デプロイオプションなどありそうだが、わからなかった。
実行
postmanやThunder Clientからリクエストを送ってテスト。