K
Kysely10mo ago
mike

Migrations in transaction and self management

Hi, I have a questions regarding migrations: - Is it possible to run all migrations in one transaction? - If I want to use kysely migrations for only generating raw sql for another db migration framework (such as umzug), should I use compile()? - How to handle deprecated models? If I remove a column from a model how will this be supported by the typing? Thanks in advance Mike
4 Replies
koskimas
koskimas10mo ago
1. The dialect decides whether migrations are run in a transaction or not. I think postgres is the only one that fully supports transactional DDL. The built-in PostgresDialect always runs migrations in a transaction. 2. Yes, you can use compile. 3. Depends. If you use some kind of generation tool for the types, then it may or may not have a way to add deprecation annotations above the fields. If you manage the types by hand, you can do whatever you like. The types don't need to have all columns that exist in the db.
mike
mike10mo ago
Ok, I get it. My idea is to create my own class which extends Kysely<any> and I would like to add some methods to compile() so the result would be like this:
export class MyClass extends Kysely<any> {}
new MyClass()
.schema
.createTable('my-table')
.compile()
.doSomethingWithTheResult(options: any) // my own method
export class MyClass extends Kysely<any> {}
new MyClass()
.schema
.createTable('my-table')
.compile()
.doSomethingWithTheResult(options: any) // my own method
can you give me a hint how to do it? Thanks
koskimas
koskimas10mo ago
Extending the classes won't be feasible I'm afraid. You could extend Kysely but there's no way to extend the SchemaModule that has the createTable function. Well, you could extend that too, but there's no easy way to make Kysely create an instance of your overridden type. Kysely is not designed to be extendable in that way. Even if you were able to override all the involved classes and interfaces, you'd need to override EVERY method of those classes to return the new subtype. Othertwise you'd lose the overridden class type after the first chained call to any method. Instead, I'd create helper functions and do something like
doSomethingWithTheResult(
db.schema.createTable('my-table'),
options,
)
doSomethingWithTheResult(
db.schema.createTable('my-table'),
options,
)
mike
mike10mo ago
first of all, thank you for the answer. that's what I've done before and wanted to have it "smoother"... 🙂 but if this is suggested way - I have not problem with that. I've created new class named KyselyBroker which digest the CompiledQuery and do "something" with it. I use it basically for transforming query+parameters to be compatible with sequelize. What I am still a little confused about is the ExpressionBuilder which I use (as suggested on this channel) for setting aliases. It works as expected but I still wonder if it's d be possible to The result is like this:
function kyselyActivePricing(
eb: ExpressionBuilder<Database & { Pricing: PricingKysely }, 'Pricing'>,
params: ActivePricingParams,
) {
return eb
// query using the database with the aliases
.compile();
}

function sqlActivePricing(params: ActivePricingParams) {
return new KyselyBroker(kyselyActivePricing(kysely as any, params));
}
function kyselyActivePricing(
eb: ExpressionBuilder<Database & { Pricing: PricingKysely }, 'Pricing'>,
params: ActivePricingParams,
) {
return eb
// query using the database with the aliases
.compile();
}

function sqlActivePricing(params: ActivePricingParams) {
return new KyselyBroker(kyselyActivePricing(kysely as any, params));
}
Would it be possible to make it easier? Currently I have: - ExpressionBuilder with aliases (compilation) - helper function - KyselyBroker class which is agostic to the query source but transform the output the requested way