https://github.com/robinellgren/kysely-replica-dialect
Kysely dialect for MySQL and Postgres with support for replicas
https://github.com/robinellgren/kysely-replica-dialect
dialect kysely mysql pg postgres postgresql replication typescript
Last synced: about 1 year ago
JSON representation
Kysely dialect for MySQL and Postgres with support for replicas
- Host: GitHub
- URL: https://github.com/robinellgren/kysely-replica-dialect
- Owner: robinellgren
- License: mit
- Created: 2025-02-16T11:04:52.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-17T10:46:18.000Z (over 1 year ago)
- Last Synced: 2025-03-25T08:39:12.205Z (about 1 year ago)
- Topics: dialect, kysely, mysql, pg, postgres, postgresql, replication, typescript
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/kysely-replica-dialect
- Size: 26.6 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
A [Kysely](https://github.com/koskimas/kysely) dialect for `MySQL` and `Postgres` that supports using **read replication**. The dialect uses the respective core `kysely` dialects under the hood.
## Features
- ⚡️ Well-tested and production ready
- 💯 100% test coverage
- 🍃 Light - The library has zero dependencies (other than `kysely` itself)
- 🐘🐬 Works with both `MySQL` and `Postgres`
- ✅ Easy to add to your existing project
## Read replication
Read replication allows distributing `SELECT` queries across multiple read replicas while directing all writes and updates to a primary database instance. This can improve read performance and scalability.
`kysely-replica-dialect` adds support for `MySQL` and `Postgres` read replication in Kysely, which [is not available in the main library](https://github.com/kysely-org/kysely/issues/450). You define a primary database for writes and one or more read replicas for queries. Note that `kysely-replica-dialect` does not handle the actual replication setup. That is managed by the database itself.
## Installation
Available in [NPM](https://www.npmjs.com/package/kysely-replica-dialect).
The only required peer-dependency is `kysely`.
You can install the library with your favorite package manager:
```bash
# with pnpm
pnpm add kysely-replica-dialect
# with yarn
yarn add kysely-replica-dialect
# with npm
npm install kysely-replica-dialect
```
## Usage
> Each `write` or `transaction` query will use the `write` pool. For `SELECT`, the `read` pool will be used. Read and write replicas within the pool are switched using the underlying driver (`mysql2` or `pg`).
Since this library uses `kysely` core drivers under the hood, the extra dialect config is passed to there. This means that functionality for use `onCreateConnection` and `onReserveConnection` stays the same.
### MySQL
You can pass a new instance of `MysqlReplicaDialect` as the `dialect` option when creating a new `Kysely` instance:
```typescript
import { Kysely } from "kysely";
import { createPool } from "mysql2";
import { MysqlReplicaDialect } from "kysely-replica-dialect";
const writePool = createPool({
database: "some_db",
host: "localhost:3306",
});
const readPool = createPool({
database: "some_db",
host: "localhost:3307",
});
const db = new Kysely({
dialect: new MysqlReplicaDialect({
pools: {
read: readPool,
write: writePool,
},
...yourOtherDialectConfig,
}),
});
```
### Postgres
Similarily to Mysql, you can pass a new instance of `PostgresReplicaDialect` as the `dialect` option when creating a new `Kysely` instance:
```typescript
import { Kysely } from "kysely";
import { Pool } from "pg";
import { PostgresReplicaDialect } from "kysely-replica-dialect";
const writePool = new Pool({
database: "some_db",
host: "localhost:3306",
});
const readPool = new Pool({
database: "some_db",
host: "localhost:3307",
});
const db = new Kysely({
dialect: new PostgresReplicaDialect({
pools: {
read: readPool,
write: writePool,
},
...yourOtherDialectConfig,
}),
});
```
### Pool as function
If you want the pool to only be created once it's first used, pool can be a function (just like in `kysely`):
```typescript
import { createPool } from "mysql2";
import { Pool } from "pg";
new MysqlReplicaDialect({
pools: {
read: async () => createPool({ database: "some_db", host: "localhost:3307" }),
write: async () => createPool({ database: "some_db", host: "localhost:3306" }),
},
});
new PostgresReplicaDialect({
pools: {
read: async () => new Pool({ database: "some_db", host: "localhost:3307" }),
write: async () => new Pool({ database: "some_db", host: "localhost:3306" }),
},
});
```
## Transactions
When using the dialect within a transaction, the `write` pool will **always** be used. This is because there is no way to know beforehand what queries will be executed within the transaction so we cannot decide if read or write pool should be used.