kysely-org / kysely

A type-safe typescript SQL query builder
https://kysely.dev
MIT License
10.22k stars 260 forks source link

Using `kysely` and `pg` requires me to install `pg-native`, and Vercel preview deployment errors on `pg-native` #368

Closed magnusrodseth closed 1 year ago

magnusrodseth commented 1 year ago

I'm struggling with pg and pg-native. My package.json looks like this:

{
  "name": "@acme/timeseries",
  "version": "0.1.0",
  "main": "./index.ts",
  "types": "./index.ts",
  "license": "MIT",
  "scripts": {
    "clean": "rm -rf .turbo node_modules",
    "with-env": "dotenv -e ../../.env --",
    "update": "pnpm update",
    "gen:types:kanel": "pnpm with-env kanel",
    "gen:types:kysely": "pnpm with-env kysely-codegen --url 'env(TIMESERIES_DB_CONNECTION_STRING)'"
  },
  "devDependencies": {
    "@types/pg": "^8.6.6",
    "dotenv-cli": "^6.0.0",
    "kanel": "^3.2.2",
    "kanel-zod": "^0.0.5",
    "typescript": "^4.9.5"
  },
  "dependencies": {
    "kysely": "^0.23.5",
    "kysely-codegen": "^0.9.0",
    "pg": "^8.10.0",
    "pg-native": "^3.0.1",
    "zod": "^3.20.6"
  }
}

Note that this package is part of a monorepo, including a Next.js application that consumes this package to interface with the PostgreSQL database.

I need to have both pg and pg-native for my application to build and run. The same goes for my GitHub Actions workflow and Vercel preview deployment - they won't attempt to run without the pg-native dependency installed.

Locally, everything now runs, and I get to extract sensible data from my TimescaleDB PostgreSQL database. I get data console.log-ed in my browser that actually stems from the database.

My GitHub CI workflow build correctly, so there's no problem with the pg-native dependency there. However, my Vercel preview deployment gets the following error with pg-native installed:

.../libpq@1.8.12/node_modules/libpq install: gyp ERR! configure error
--
09:54:08.019 | .../libpq@1.8.12/node_modules/libpq install: gyp ERR! stack Error: `gyp` failed with exit code: 1
09:54:08.019 | .../libpq@1.8.12/node_modules/libpq install: gyp ERR! stack     at ChildProcess.onCpExit (/pnpm7/node_modules/pnpm/dist/node_modules/node-gyp/lib/configure.js:325:16)
09:54:08.020 | .../libpq@1.8.12/node_modules/libpq install: gyp ERR! stack     at ChildProcess.emit (node:events:513:28)
09:54:08.020 | .../libpq@1.8.12/node_modules/libpq install: gyp ERR! stack     at ChildProcess._handle.onexit (node:internal/child_process:291:12)

Googling this error, I read this thread and they immediately started talking about pg-native.

I don't understand why I should even need pg-native when using kysely with the pg package. Is there some reason this won't run serverless - is that it?

koskimas commented 1 year ago

Kysely doesn't require you to install any drivers. There are zero internal dependencies to external libraries. The dialects take all their dependencies as arguments when you instantiate them.

The PostgresDialect doesn't use the native module in any way. It uses the Pool you give it and nothing else.

The dependency requirements might come from kysely-codegen or some third party dialect you might be using, but definitely not from kysely.

Another guess is that when you install pg some bundler you use incorrectly thinks you also need to install pg-native. In this case I'd search this from pg repo's issues.

If you create your Kysely instance without pg for example like this:

import { 
  DummyDriver,
  Kysely,
  PostgresDialect,
  PostgresAdapter,
  PostgresCompiler,
  PostgresIntrospector,
  PostgresQueryCompiler,
} from 'kysely'

const db = new Kysely<DB>({
  dialect: {
    createAdapter: () => new PostgresAdapter(),
    createDriver: () => new DummyDriver(),
    createIntrospector: (db) => new PostgresIntrospector(db),
    createQueryCompiler: () => new PostgresQueryCompiler(),
  },
})

and remove all references to the pg module, you should see the error go away. Not that this is a solution, but it should assure you that Kysely is not the culprit here.

magnusrodseth commented 1 year ago

I use a Turborepo, where I have an apps/web which is my Next app and a packages/timeseries package, which is my connection and library for interacting with the timeseries Postgres database. I fixed this by deleting the timeseries package, and using kysely in apps/web in getServerSideProps.

Suboptimal and a bit messy, but it works.