kysely-org / kysely

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

Progressively migrate from knex to kysely. #630

Open alnorris opened 1 year ago

alnorris commented 1 year ago

Has anyone done this before? Just wondering if there is anything I should be aware of that might cause issues? I thought about keeping my knex schema migrations until all queries are transitioned over while using kysely-codegen for types.

Perhaps a knex -> kysely migration guide in the docs + a codemod would be a good idea?

koskimas commented 1 year ago

You should be able to use knex and Kysely side by side in the same project without any issues. The only thing I can think of, off the top of my head is that, depending on the setup, you might end up with two connection pools. That might not be an issue, but something to keep in mind.

Knex uses it's own connection pool, so there's no way to share that with Kysely currently. We could in theory create a KnexDialect that takes a knex instance and uses it as the driver 🤔

korichdaniel commented 1 year ago

I did a small patch to work with same connection until I move completely to kysely.


class KnexDatabaseConnection implements DatabaseConnection {
    private trx: Knex.Transaction<unknown, unknown>;

    public async startTransaction(settings: TransactionSettings) {
        this.trx = await knex.transaction(null, settings);
    }

    public async commit() {
        await this.trx?.commit();
    }

    public async rollback() {
        await this.trx.rollback();
    }

    public async executeQuery<R>(compiledQuery: CompiledQuery<unknown>): Promise<QueryResult<R>> {
        return await (this.trx || knex).raw(adaptQueryToKnex(compiledQuery.sql), [
            ...compiledQuery.parameters
        ] as any[]);
    }

    public async *streamQuery<R>(
        _compiledQuery: CompiledQuery<unknown>,
        _chunkSize?: number
    ): AsyncIterableIterator<QueryResult<R>> {
        yield;
    }
}

PostgresDriver.prototype.acquireConnection = async function (): Promise<DatabaseConnection> {
    return new KnexDatabaseConnection();
};

PostgresDriver.prototype.releaseConnection = function (): Promise<void> {
    return;
};

PostgresDriver.prototype.beginTransaction = async function (
    connection: DatabaseConnection,
    settings: TransactionSettings
): Promise<void> {
    await (connection as KnexDatabaseConnection).startTransaction(settings);
};

PostgresDriver.prototype.commitTransaction = async function (connection: DatabaseConnection): Promise<void> {
    await (connection as KnexDatabaseConnection).commit();
};

PostgresDriver.prototype.rollbackTransaction = async function (connection: DatabaseConnection): Promise<void> {
    await (connection as KnexDatabaseConnection).rollback();
};

const kysely = new Kysely<DB>({
    // @ts-expect-error PostgresDialect requires a connection to the DB, we want to avoid it as
    // we are only using kysely as a pure query builder and performing the actual operation via knex
    dialect: new PostgresDialect({})
});

function adaptQueryToKnex(kyselyQuery: string) {
    return kyselyQuery.replace(/\$[0-9]+/g, '?');
}
lghartmann commented 6 months ago

At my company we started migrating from knex to Kysely last week, everything was going fine until today, the file with the generated types is pretty long and the autocomplete stopped working (it was working fine last week), my senior is testing different TS versions and some other stuff

igalklebanov commented 6 months ago

At my company we started migrating from knex to Kysely last week, everything was going fine until today, the file with the generated types is pretty long and the autocomplete stopped working (it was working fine last week), my senior is testing different TS versions and some other stuff

How many tables?

lghartmann commented 6 months ago

At my company we started migrating from knex to Kysely last week, everything was going fine until today, the file with the generated types is pretty long and the autocomplete stopped working (it was working fine last week), my senior is testing different TS versions and some other stuff

How many tables?

Currently 629 tables, the generated types file is approximately 9.5k lines long, we're currently using typescript 5.3.3.

igalklebanov commented 6 months ago

At my company we started migrating from knex to Kysely last week, everything was going fine until today, the file with the generated types is pretty long and the autocomplete stopped working (it was working fine last week), my senior is testing different TS versions and some other stuff

How many tables?

Currently 629 tables, the generated types file is approximately 9.5k lines long, we're currently using typescript 5.3.3.

Try splitting - e.g. kysely-codegen has a filter argument. There's no healthy way a single service should know all tables.

lghartmann commented 6 months ago

At my company we started migrating from knex to Kysely last week, everything was going fine until today, the file with the generated types is pretty long and the autocomplete stopped working (it was working fine last week), my senior is testing different TS versions and some other stuff

How many tables?

Currently 629 tables, the generated types file is approximately 9.5k lines long, we're currently using typescript 5.3.3.

Try splitting - e.g. kysely-codegen has a filter argument. There's no healthy way a single service should know all tables.

We spent the afternoon investigating this issue. Whenever i started a fresh file autocomplete worked just fine (even with 629 tables generated), as soon as finished and saved, closed the files, reloaded window (VSCode) and reopened the TS file the autocomplete stayed as "loading..." Then we applied your mentioned filter, generated tables we're reduced to 49, i recreated the same file, tested it again, working fine, sometimes it gets a little slow to load the autocomplete but its pretty ok, it looks like as the file gets bigger the autocomplete gets slower (already felt it slower with 2 simple select queries). Thanks igalklebanov

igalklebanov commented 5 months ago

We've published https://github.com/kysely-org/kysely-knex, give it a try. Let us know how it went!

the21st commented 5 months ago

@koskimas @igalklebanov How would you suggest we migrate existing database migrations managed by knex if we want to migrate to kysely?

Edit: to be more specific, how would you suggest we handle the transition from our existing knex_migrations table in our production DB to kysely_migrations ?

igalklebanov commented 5 months ago

The easy way - just delete the old migrations and start anew. The hard way - I'll investigate.

igalklebanov commented 5 months ago

v0.2 released with a custom migration source that allows using Kysely in Knex-managed migrations, side-by-side with Knex.

the21st commented 5 months ago

@igalklebanov wow, thanks so much! Will check it out with our team soon 🙂