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

feat: use kysely for handling migrations & add scripts #20

Merged
merged 4 commits into from
Nov 4, 2024

Conversation

0xnigir1
Copy link
Collaborator

@0xnigir1 0xnigir1 commented Oct 29, 2024

🤖 Linear

Closes GIT-113 GIT-114 GIT-115

Description

  • use Kysely for handling database migrations in a cleaner way
  • write initial migration with current Indexer schema
  • add migration scripts in apps/scripts folder

Checklist before requesting a review

  • I have conducted a self-review of my code.
  • I have conducted a QA.
  • If it is a core feature, I have included comprehensive tests.

@0xyaco 0xyaco self-assigned this Oct 30, 2024
0xyaco
0xyaco previously approved these changes Oct 30, 2024
Copy link
Collaborator

@0xyaco 0xyaco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR is looking good!

I left some comments that might be interesting to think about; overall the code is looking neat.

Comment on lines +78 to +90
Example migration file:

```typescript
import { Kysely } from "kysely";

export async function up(db: Kysely<any>): Promise<void> {
// Your migration code here
}

export async function down(db: Kysely<any>): Promise<void> {
// Code to reverse the migration
}
```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extremely nice to have but it'd be cool to have a third script to be able to run something like:

pnpm script:db:prepare <migration name>

And automagically generate the timestamped migration file with this sweet placeholder.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aaa 💯 i think kysely has a cli-tool but i can easily home-craft it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +31 to +53
## Usage

First, install dependencies:

```bash
pnpm install
```

### Running Migrations

To apply all pending migrations:

```bash
pnpm script:db:migrate
```

This will:

1. Load environment variables
2. Connect to the database
3. Create the schema if it doesn't exist
4. Run any pending migrations
5. Log the results
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about the "productive" stage of this app, how should migrations be applied? Should the operator stop the indexer, apply the migrations and then restart the indexer? Can we afford the indexer to be stopped to apply migrations or do you need a more sophisticated strategy?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice question ser, we yet have to discuss how this should work in prod but definitely the processor will need to be stopped

Copy link
Collaborator

@0xkenj1 0xkenj1 Nov 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

migrationTableSchema: config.schema,
});

const { error, results } = await migrator.migrateToLatest();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be absolutely sure, this migrateToLatest short-circuits if one migration fails, right? So migrations after the failing one are not applied

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does short-circuit (and also skips migrations already applied), but i'm not sure if it applied 2 migrations and the 3rd failed, if it rollbacks all (like apply all migrations or none), will research more about this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesn't rollback successful migrations, just short-circuit on failed migration

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loved the update, sounds good though


await db.destroy();

process.exit(0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This process.exit(0) might not be needed as 0 should be the default Node exit code (unless there's something I'm missing and you want to explicitly exit the process)

* @returns A configured Kysely instance for the Database.
*
* This function sets up a PostgreSQL database connection using Kysely ORM.
*
* It uses the `CamelCasePlugin` to convert all table names to camel case.
* It uses the `WithSchemaPlugin` to automatically prefix all table names with the schema name on queries.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank god for this plugin

* ref: https://kysely.dev/docs/migrations#migration-files
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function up(db: Kysely<any>): Promise<void> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know if Kysely applies every of these SQL clauses inside a DB transaction or something similar? Thinking about what would happen if the n-th create table query fails: would the previous create table queries be reverted automatically?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's in a transaction, all or nothing because i've had some errors while writing the migration and that's how i found out xd

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to Kysely for using sane defaults

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xd to nigiri's comment

Copy link
Collaborator

@0xkenj1 0xkenj1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💎

Comment on lines +31 to +53
## Usage

First, install dependencies:

```bash
pnpm install
```

### Running Migrations

To apply all pending migrations:

```bash
pnpm script:db:migrate
```

This will:

1. Load environment variables
2. Connect to the database
3. Create the schema if it doesn't exist
4. Run any pending migrations
5. Log the results
Copy link
Collaborator

@0xkenj1 0xkenj1 Nov 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +4 to +13
* Since WithSchemaPlugin doesn't work with `sql.table`, we need to get the schema name manually.
* ref: https://github.com/kysely-org/kysely/issues/761
*/
export const getSchemaName = (schema: SchemaModule): string => {
let name = "public";
schema.createTable("test").$call((b) => {
name = b.toOperationNode().table.table.schema?.name ?? "public";
});
return name;
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand what is this function for

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so queries in migration have the 'schemaName.field/enumType' format. the plugin doesn't support all of kysely features and some don't get the schemaName appended automatically

* ref: https://kysely.dev/docs/migrations#migration-files
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function up(db: Kysely<any>): Promise<void> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xd to nigiri's comment

@0xnigir1 0xnigir1 merged commit 4996b56 into dev Nov 4, 2024
6 checks passed
@0xnigir1 0xnigir1 deleted the feat/database-migrations branch November 4, 2024 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants