Migrate database to Vercel postgres

This commit is contained in:
Aaron William Po
2023-05-02 20:01:12 -04:00
parent 150e847df7
commit 85ecc9f062
10 changed files with 235 additions and 152 deletions

View File

@@ -18,11 +18,19 @@ const envSchema = z.object({
SESSION_SECRET: z.string(),
SESSION_TOKEN_NAME: z.string(),
SESSION_MAX_AGE: z.coerce.number().positive(),
DATABASE_URL: z.string().url(),
POSTGRES_URL: z.string().url(),
POSTGRES_PRISMA_URL: z.string().url(),
POSTGRES_URL_NON_POOLING: z.string().url(),
POSTGRES_USER: z.string(),
POSTGRES_PASSWORD: z.string(),
POSTGRES_DATABASE: z.string(),
POSTGRES_HOST: z.string(),
NODE_ENV: z.enum(['development', 'production', 'test']),
SPARKPOST_API_KEY: z.string(),
SPARKPOST_SENDER_ADDRESS: z.string().email(),
MAPBOX_ACCESS_TOKEN: z.string()
MAPBOX_ACCESS_TOKEN: z.string(),
});
const parsed = envSchema.safeParse(env);
@@ -110,12 +118,74 @@ export const SESSION_TOKEN_NAME = parsed.data.SESSION_TOKEN_NAME;
export const SESSION_MAX_AGE = parsed.data.SESSION_MAX_AGE;
/**
* URL of the CockroachDB database. CockroachDB uses the PostgreSQL wire protocol.
* PostgreSQL connection URL taken from Vercel.
*
* @example
* 'postgres://username:password@localhost/my-database';
* 'postgresql://user:password@host:5432/database';
*
* @see https://vercel.com/dashboard/stores
*/
export const DATABASE_URL = parsed.data.DATABASE_URL;
export const POSTGRES_URL = parsed.data.POSTGRES_URL;
/**
* PostgreSQL connection URL for Prisma taken from Vercel.
*
* @example
* 'postgresql://user:password@host:5432/database';
*
* @see https://vercel.com/dashboard/stores
*/
export const POSTGRES_PRISMA_URL = parsed.data.POSTGRES_PRISMA_URL;
/**
* Non-pooling PostgreSQL connection URL taken from Vercel.
*
* @example
* 'postgresql://user:password@host:5432/database';
*
* @see https://vercel.com/dashboard/stores
*/
export const POSTGRES_URL_NON_POOLING = parsed.data.POSTGRES_URL_NON_POOLING;
/**
* The PostgreSQL user from Vercel.
*
* @example
* 'user';
*
* @see https://vercel.com/dashboard/stores
*/
export const POSTGRES_USER = parsed.data.POSTGRES_USER;
/**
* The PostgreSQL password from Vercel.
*
* @example
* 'password';
*
* @see https://vercel.com/dashboard/stores
*/
export const POSTGRES_PASSWORD = parsed.data.POSTGRES_PASSWORD;
/**
* The PostgreSQL database from Vercel.
*
* @example
* 'database';
*
* @see https://vercel.com/dashboard/stores
*/
export const POSTGRES_DATABASE = parsed.data.POSTGRES_DATABASE;
/**
* The PostgreSQL host from Vercel.
*
* @example
* 'ep-sweet-pineapple.us-east-1.postgres.vercel-storage.com';
*
* @see https://vercel.com/dashboard/stores
*/
export const POSTGRES_HOST = parsed.data.POSTGRES_HOST;
/**
* Node environment.
@@ -149,11 +219,10 @@ export const SPARKPOST_SENDER_ADDRESS = parsed.data.SPARKPOST_SENDER_ADDRESS;
/**
* Your Mapbox access token.
*
*
* @example
* 'pk.abcdefghijklmnopqrstuvwxyz123456';
*
* 'pk.abcdefghijklmnopqrstuvwxyz123456';
*
* @see https://docs.mapbox.com/help/how-mapbox-works/access-tokens/
*/
export const MAPBOX_ACCESS_TOKEN = parsed.data.MAPBOX_ACCESS_TOKEN;
export const MAPBOX_ACCESS_TOKEN = parsed.data.MAPBOX_ACCESS_TOKEN;

View File

@@ -1,16 +0,0 @@
-- CreateTable
CREATE TABLE "BreweryPostLike" (
"id" STRING NOT NULL,
"breweryPostId" STRING NOT NULL,
"likedById" STRING NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
CONSTRAINT "BreweryPostLike_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_breweryPostId_fkey" FOREIGN KEY ("breweryPostId") REFERENCES "BreweryPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_likedById_fkey" FOREIGN KEY ("likedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -1,2 +0,0 @@
-- AlterTable
ALTER TABLE "BreweryPost" ADD COLUMN "dateEstablished" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

View File

@@ -1,15 +0,0 @@
/*
Warnings:
- You are about to drop the column `location` on the `BreweryPost` table. All the data in the column will be lost.
- Added the required column `address` to the `BreweryPost` table without a default value. This is not possible if the table is not empty.
- Added the required column `city` to the `BreweryPost` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "BreweryPost" DROP COLUMN "location";
ALTER TABLE "BreweryPost" ADD COLUMN "address" STRING NOT NULL;
ALTER TABLE "BreweryPost" ADD COLUMN "city" STRING NOT NULL;
ALTER TABLE "BreweryPost" ADD COLUMN "coordinates" FLOAT8[];
ALTER TABLE "BreweryPost" ADD COLUMN "country" STRING;
ALTER TABLE "BreweryPost" ADD COLUMN "stateOrProvince" STRING;

View File

@@ -1,41 +0,0 @@
/*
Warnings:
- You are about to drop the column `address` on the `BreweryPost` table. All the data in the column will be lost.
- You are about to drop the column `city` on the `BreweryPost` table. All the data in the column will be lost.
- You are about to drop the column `coordinates` on the `BreweryPost` table. All the data in the column will be lost.
- You are about to drop the column `country` on the `BreweryPost` table. All the data in the column will be lost.
- You are about to drop the column `stateOrProvince` on the `BreweryPost` table. All the data in the column will be lost.
- A unique constraint covering the columns `[locationId]` on the table `BreweryPost` will be added. If there are existing duplicate values, this will fail.
- Added the required column `locationId` to the `BreweryPost` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "BreweryPost" DROP COLUMN "address";
ALTER TABLE "BreweryPost" DROP COLUMN "city";
ALTER TABLE "BreweryPost" DROP COLUMN "coordinates";
ALTER TABLE "BreweryPost" DROP COLUMN "country";
ALTER TABLE "BreweryPost" DROP COLUMN "stateOrProvince";
ALTER TABLE "BreweryPost" ADD COLUMN "locationId" STRING NOT NULL;
-- CreateTable
CREATE TABLE "Location" (
"id" STRING NOT NULL,
"city" STRING NOT NULL,
"stateOrProvince" STRING,
"country" STRING,
"coordinates" FLOAT8[],
"address" STRING NOT NULL,
"postedById" STRING NOT NULL,
CONSTRAINT "Location_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "BreweryPost_locationId_key" ON "BreweryPost"("locationId");
-- AddForeignKey
ALTER TABLE "Location" ADD CONSTRAINT "Location_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "Location"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -1,14 +1,14 @@
-- CreateTable
CREATE TABLE "User" (
"id" STRING NOT NULL,
"username" STRING NOT NULL,
"firstName" STRING NOT NULL,
"lastName" STRING NOT NULL,
"hash" STRING NOT NULL,
"email" STRING NOT NULL,
"id" TEXT NOT NULL,
"username" TEXT NOT NULL,
"firstName" TEXT NOT NULL,
"lastName" TEXT NOT NULL,
"hash" TEXT NOT NULL,
"email" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
"isAccountVerified" BOOL NOT NULL DEFAULT false,
"isAccountVerified" BOOLEAN NOT NULL DEFAULT false,
"dateOfBirth" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
@@ -16,14 +16,14 @@ CREATE TABLE "User" (
-- CreateTable
CREATE TABLE "BeerPost" (
"id" STRING NOT NULL,
"name" STRING NOT NULL,
"ibu" FLOAT8 NOT NULL,
"abv" FLOAT8 NOT NULL,
"description" STRING NOT NULL,
"postedById" STRING NOT NULL,
"breweryId" STRING NOT NULL,
"typeId" STRING NOT NULL,
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"ibu" DOUBLE PRECISION NOT NULL,
"abv" DOUBLE PRECISION NOT NULL,
"description" TEXT NOT NULL,
"postedById" TEXT NOT NULL,
"breweryId" TEXT NOT NULL,
"typeId" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
@@ -32,22 +32,33 @@ CREATE TABLE "BeerPost" (
-- CreateTable
CREATE TABLE "BeerPostLike" (
"id" STRING NOT NULL,
"beerPostId" STRING NOT NULL,
"likedById" STRING NOT NULL,
"id" TEXT NOT NULL,
"beerPostId" TEXT NOT NULL,
"likedById" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
CONSTRAINT "BeerPostLike_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BreweryPostLike" (
"id" TEXT NOT NULL,
"breweryPostId" TEXT NOT NULL,
"likedById" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
CONSTRAINT "BreweryPostLike_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BeerComment" (
"id" STRING NOT NULL,
"rating" INT4 NOT NULL,
"beerPostId" STRING NOT NULL,
"postedById" STRING NOT NULL,
"content" STRING NOT NULL,
"id" TEXT NOT NULL,
"rating" INTEGER NOT NULL,
"beerPostId" TEXT NOT NULL,
"postedById" TEXT NOT NULL,
"content" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
@@ -56,35 +67,49 @@ CREATE TABLE "BeerComment" (
-- CreateTable
CREATE TABLE "BeerType" (
"id" STRING NOT NULL,
"name" STRING NOT NULL,
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
"postedById" STRING NOT NULL,
"postedById" TEXT NOT NULL,
CONSTRAINT "BeerType_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Location" (
"id" TEXT NOT NULL,
"city" TEXT NOT NULL,
"stateOrProvince" TEXT,
"country" TEXT,
"coordinates" DOUBLE PRECISION[],
"address" TEXT NOT NULL,
"postedById" TEXT NOT NULL,
CONSTRAINT "Location_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BreweryPost" (
"id" STRING NOT NULL,
"name" STRING NOT NULL,
"location" STRING NOT NULL,
"description" STRING NOT NULL,
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"locationId" TEXT NOT NULL,
"description" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
"postedById" STRING NOT NULL,
"postedById" TEXT NOT NULL,
"dateEstablished" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "BreweryPost_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BreweryComment" (
"id" STRING NOT NULL,
"rating" INT4 NOT NULL,
"breweryPostId" STRING NOT NULL,
"postedById" STRING NOT NULL,
"content" STRING NOT NULL,
"id" TEXT NOT NULL,
"rating" INTEGER NOT NULL,
"breweryPostId" TEXT NOT NULL,
"postedById" TEXT NOT NULL,
"content" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
@@ -93,28 +118,28 @@ CREATE TABLE "BreweryComment" (
-- CreateTable
CREATE TABLE "BeerImage" (
"id" STRING NOT NULL,
"beerPostId" STRING NOT NULL,
"path" STRING NOT NULL,
"alt" STRING NOT NULL,
"caption" STRING NOT NULL,
"id" TEXT NOT NULL,
"beerPostId" TEXT NOT NULL,
"path" TEXT NOT NULL,
"alt" TEXT NOT NULL,
"caption" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
"postedById" STRING NOT NULL,
"postedById" TEXT NOT NULL,
CONSTRAINT "BeerImage_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BreweryImage" (
"id" STRING NOT NULL,
"breweryPostId" STRING NOT NULL,
"path" STRING NOT NULL,
"id" TEXT NOT NULL,
"breweryPostId" TEXT NOT NULL,
"path" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3),
"caption" STRING NOT NULL,
"alt" STRING NOT NULL,
"postedById" STRING NOT NULL,
"caption" TEXT NOT NULL,
"alt" TEXT NOT NULL,
"postedById" TEXT NOT NULL,
CONSTRAINT "BreweryImage_pkey" PRIMARY KEY ("id")
);
@@ -125,6 +150,9 @@ CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "BreweryPost_locationId_key" ON "BreweryPost"("locationId");
-- AddForeignKey
ALTER TABLE "BeerPost" ADD CONSTRAINT "BeerPost_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -140,6 +168,12 @@ ALTER TABLE "BeerPostLike" ADD CONSTRAINT "BeerPostLike_beerPostId_fkey" FOREIGN
-- AddForeignKey
ALTER TABLE "BeerPostLike" ADD CONSTRAINT "BeerPostLike_likedById_fkey" FOREIGN KEY ("likedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_breweryPostId_fkey" FOREIGN KEY ("breweryPostId") REFERENCES "BreweryPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_likedById_fkey" FOREIGN KEY ("likedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BeerComment" ADD CONSTRAINT "BeerComment_beerPostId_fkey" FOREIGN KEY ("beerPostId") REFERENCES "BeerPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -149,6 +183,12 @@ ALTER TABLE "BeerComment" ADD CONSTRAINT "BeerComment_postedById_fkey" FOREIGN K
-- AddForeignKey
ALTER TABLE "BeerType" ADD CONSTRAINT "BeerType_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Location" ADD CONSTRAINT "Location_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "Location"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -1,3 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "cockroachdb"
provider = "postgresql"

View File

@@ -6,8 +6,10 @@ generator client {
}
datasource db {
provider = "cockroachdb"
url = env("DATABASE_URL")
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL") // uses connection pooling
directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
shadowDatabaseUrl = env("POSTGRES_URL_NON_POOLING") // used for migrations
}
model User {

View File

@@ -53,7 +53,7 @@ import logger from '../../config/pino/logger';
joinData: { beerPosts, users },
}),
createNewBreweryPostComments({
numberOfComments: 100000,
numberOfComments: 50000,
joinData: { breweryPosts, users },
}),
]);
@@ -61,7 +61,7 @@ import logger from '../../config/pino/logger';
const [beerPostLikes, breweryPostLikes] = await Promise.all([
createNewBeerPostLikes({
numberOfLikes: 100000,
numberOfLikes: 500000,
joinData: { beerPosts, users },
}),
createNewBreweryPostLikes({
@@ -77,7 +77,7 @@ import logger from '../../config/pino/logger';
joinData: { beerPosts, users },
}),
createNewBreweryImages({
numberOfImages: 20000,
numberOfImages: 5000,
joinData: { breweryPosts, users },
}),
]);