Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example: add tidb database example #4822

Open
wants to merge 1 commit into
base: latest
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/test-tidb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: test-tidb
on:
push:
paths:
- databases/tidb/**
branches:
- latest
- dev
- patch-dev
pull_request:
paths:
- databases/tidb/**

env:
CI: 1
PRISMA_TELEMETRY_INFORMATION: 'prisma-examples test-tidb.yaml'

jobs:
test:
defaults:
run:
working-directory: databases/tidb
runs-on: ubuntu-latest

env:
DATABASE_URL: mysql://[email protected]:4000/prisma?sslmode=disable

steps:
- uses: actions/checkout@v3
- name: Start a single TiDB instance with Docker
env:
TIDB_DOCKER_TAG: 'pingcap/tidb:v7.1.0'
run: |
docker pull $TIDB_DOCKER_TAG
docker run -d --name tidb --hostname tidb -p 4000:4000 -p 8080:8080 -v "${{ github.workspace }}:/app" $TIDB_DOCKER_TAG
sudo apt update && sudo apt install wait-for-it -y
wait-for-it -h localhost -p 4000
- uses: actions/setup-node@v3
with:
node-version: '14'
- run: npm install
- run: npx prisma migrate dev --name "init"
- run: npm run test
10 changes: 10 additions & 0 deletions databases/tidb/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# If you connect with local TiDB cluster, setup the DATABASE_URL variable as the following format.
#
# DATABASE_URL="mysql://<user>:<password>@<host>:<port>/<database>"
#
# For example:
#
DATABASE_URL="mysql://root@localhost:4000/test"

# If you connect with TiDB Serverless cluster, you need to add `sslaccept=strict` to the end of the connection string.
# DATABASE_URL="mysql://<user>:<password>@<host>:<port>/<database>?sslaccept=strict
7 changes: 7 additions & 0 deletions databases/tidb/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
tidb-data/
dist/
*.env*
!.env.example
data/
logs/
143 changes: 143 additions & 0 deletions databases/tidb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# TiDB example

This example shows how to:

- Connect Prisma to a TiDB database
- Create the database schema with raw SQL
- Populate the Prisma schema using [`prisma db pull`](https://www.prisma.io/docs/reference/api-reference/command-reference#db-pull)
- Read and write data to the database using [Prisma Client](https://www.prisma.io/client)

The example consists of two parts:

- `tests/prisma.test.ts`: Jest test (in TypeScript) with a variety of Prisma Client queries and assertions to showcase access patterns
- `src/script.ts`: Node.js script with queries similar to the ones in the test.

## Prerequisites

- Node.js installed.
- [TiUP](https://docs.pingcap.com/tidb/dev/tiup-overview#install-tiup) installed. (Optional if you using TiDB Serverless)
- [Docker](https://www.docker.com/products/docker-desktop) installed. (Optional if you using TiDB Serverless)

> **Note:** You can also connect to a [free TiDB Serverless Cluster](https://docs.pingcap.com/tidbcloud/dev-guide-build-cluster-in-cloud).

## 1. Download this example & install dependencies

Download this example:

```
curl https://codeload.github.com/prisma/prisma-examples/tar.gz/latest | tar -xz --strip=2 prisma-examples-latest/databases/tidb
```

Install npm dependencies:

```
cd tidb
npm install
```

<details>
<summary><strong>Alternative:</strong>Clone this repository</summary>

Clone this repository:

```
git clone [email protected]:prisma/prisma-examples.git --depth=1
```

Install npm dependencies:

```
cd prisma-examples/databases/tidb
npm install
```

</details>

## 2. Start a TiDB database server

There are two approaches to setting up a TiDB database:

1. Using a free hosted [TiDB Serverless](https://tidbcloud.com/free-tail).
2. Using TiUP cli to start a local TiDB cluster.
3. Locally with Docker using the included [`docker-compose.yml`](./docker-compose.yml) file.

### (Option 1) Using TiDB Serverless (Recommended)

Follow the [guide](https://docs.pingcap.com/tidbcloud/dev-guide-build-cluster-in-cloud) to create a free TiDB Serverless cluster.

### (Option 2) Using TiDB Serverless

Execute the following command to start a local TiDB cluster:

```sh
tiup playground --without-monitor --tiflash 0
```

### (Option 3) Start TiDB with Docker

Run the following command from the `tidb` folder to start a TiDB Docker container:

```sh
docker compose up -d
```

## 3. Configure the database connection URL

Prisma uses the `DATABASE_URL` environment variable in `.env` in the `tidb` folder to connect to the database.

Create the file by copying the example file:

```sh
cp .env.example .env
```

Modify the `DATABASE_URL` in `.env` to point to your database server:


- If you're using a local TiDB cluster deployed by TiUP or Docker Compose, you can use the following connection string by default:

```sh
DATABASE_URL="mysql://root@localhost:4000/test"
```

- If you're using a TiDB Serverless cluster, you can find the database connection information in the console and fill in the following connection string:

**Note: You MUST to add `?sslaccept=strict` to the end of the connection string to connect to TiDB Serverless.**

```sh
DATABASE_URL="mysql://<username>:<password>@<host>:4000/test?sslaccept=strict"
```

## 4. Create the database schema in TiDB with Prisma Migrate

Now that you have defined the `DATABASE_URL` in `.env`, you will use Prisma Migrate to create a migration file with the SQL necessary to create the database schema.

Run the following command from the `tidb` folder:

```
npx prisma migrate dev --name init
```

You should see the following output:

```
Your database is now in sync with your schema.
```

> **Note:** The `prisma migrate dev` command will automatically generate Prisma Client for use in `script.ts`.

## 5. Run the tests and script

To run the test in `tests/prisma.test.ts`, run the following command:

```
npm run test
```

To run the script `src/script.ts`, run the following command:

```
npm run start
```

As a next step, explore the `script.ts` file to see how to use Prisma Client to read and write data in the database.
86 changes: 86 additions & 0 deletions databases/tidb/config/pd.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# PD Configuration.

name = "pd"
data-dir = "default.pd"

client-urls = "http://127.0.0.1:2379"
# if not set, use ${client-urls}
advertise-client-urls = ""

peer-urls = "http://127.0.0.1:2380"
# if not set, use ${peer-urls}
advertise-peer-urls = ""

initial-cluster = "pd=http://127.0.0.1:2380"
initial-cluster-state = "new"

lease = 3
tso-save-interval = "3s"

[security]
# Path of file that contains list of trusted SSL CAs. if set, following four settings shouldn't be empty
cacert-path = ""
# Path of file that contains X509 certificate in PEM format.
cert-path = ""
# Path of file that contains X509 key in PEM format.
key-path = ""

[log]
level = "error"

# log format, one of json, text, console
#format = "text"

# disable automatic timestamps in output
#disable-timestamp = false

# file logging
[log.file]
#filename = ""
# max log file size in MB
#max-size = 300
# max log file keep days
#max-days = 28
# maximum number of old log files to retain
#max-backups = 7
# rotate log by day
#log-rotate = true

[metric]
# prometheus client push interval, set "0s" to disable prometheus.
interval = "15s"
# prometheus pushgateway address, leaves it empty will disable prometheus.
address = "pushgateway:9091"

[schedule]
max-merge-region-size = 0
split-merge-interval = "1h"
max-snapshot-count = 3
max-pending-peer-count = 16
max-store-down-time = "30m"
leader-schedule-limit = 4
region-schedule-limit = 4
replica-schedule-limit = 8
merge-schedule-limit = 8
tolerant-size-ratio = 5.0

# customized schedulers, the format is as below
# if empty, it will use balance-leader, balance-region, hot-region as default
# [[schedule.schedulers]]
# type = "evict-leader"
# args = ["1"]

[replication]
# The number of replicas for each region.
max-replicas = 3
# The label keys specified the location of a store.
# The placement priorities is implied by the order of label keys.
# For example, ["zone", "rack"] means that we should place replicas to
# different zones first, then to different racks if we don't have enough zones.
location-labels = []

[label-property]
# Do not assign region leaders to stores that have these tags.
# [[label-property.reject-leader]]
# key = "zone"
# value = "cn1
Loading