The database interface type. Keys of this type must be table names in the database and values must be interfaces that describe the rows in those tables. See the examples above.
Returns a the DynamicModule module.
The DynamicModule module can be used to bypass strict typing and passing in dynamic values for the queries.
Returns a FunctionModule that can be used to write type safe function calls.
await db.selectFrom('person')
.innerJoin('pet', 'pet.owner_id', 'person.id')
.select((eb) => [
'person.id',
eb.fn.count('pet.id').as('pet_count')
])
.groupBy('person.id')
.having((eb) => eb.fn.count('pet.id'), '>', 10)
.execute()
The generated SQL (PostgreSQL):
select "person"."id", count("pet"."id") as "pet_count"
from "person"
inner join "pet" on "pet"."owner_id" = "person"."id"
group by "person"."id"
having count("pet"."id") > $1
Returns a database introspector.
Returns true if this Kysely
instance is a transaction.
You can also use db instanceof Transaction
.
Returns the SchemaModule module for building database schema.
Creates a case
statement/operator.
See case for more information.
Provides a kysely instance bound to a single database connection.
await db
.connection()
.execute(async (db) => {
// `db` is an instance of `Kysely` that's bound to a single
// database connection. All queries executed through `db` use
// the same connection.
await doStuff(db)
})
Creates a delete query.
See the where method for examples on how to specify a where clause for the delete operation.
The return value of the query is an instance of DeleteResult.
Delete a single row:
const result = await db
.deleteFrom('person')
.where('person.id', '=', '1')
.executeTakeFirst()
console.log(result.numDeletedRows)
The generated SQL (PostgreSQL):
delete from "person" where "person"."id" = $1
Some databases such as MySQL support deleting from multiple tables:
const result = await db
.deleteFrom(['person', 'pet'])
.using('person')
.innerJoin('pet', 'pet.owner_id', '=', 'person.id')
.where('person.id', '=', 1)
.executeTakeFirst()
The generated SQL (MySQL):
delete from `person`, `pet`
using `person`
inner join `pet` on `pet`.`owner_id` = `person`.`id`
where `person`.`id` = ?
Executes a given compiled query or query builder.
See splitting build, compile and execute code recipe for more information.
Creates an insert query.
The return value of this query is an instance of InsertResult. InsertResult has the insertId field that holds the auto incremented id of the inserted row if the db returned one.
See the values method for more info and examples. Also see the returning method for a way to return columns on supported databases like PostgreSQL.
const result = await db
.insertInto('person')
.values({
first_name: 'Jennifer',
last_name: 'Aniston'
})
.executeTakeFirst()
console.log(result.insertId)
Some databases like PostgreSQL support the returning
method:
const { id } = await db
.insertInto('person')
.values({
first_name: 'Jennifer',
last_name: 'Aniston'
})
.returning('id')
.executeTakeFirst()
Creates a merge query.
The return value of the query is a MergeResult.
See the using method for examples on how to specify the other table.
const result = await db
.mergeInto('person')
.using('pet', 'pet.owner_id', 'person.id')
.whenMatched((and) => and('has_pets', '!=', 'Y'))
.thenUpdateSet({ has_pets: 'Y' })
.whenNotMatched()
.thenDoNothing()
.executeTakeFirstOrThrow()
console.log(result.numChangedRows)
The generated SQL (PostgreSQL):
merge into "person"
using "pet" on "pet"."owner_id" = "person"."id"
when matched and "has_pets" != $1 then
update set "has_pets" = $2
when not matched then
do nothing
Creates a replace query.
A MySQL-only statement similar to onDuplicateKeyUpdate that deletes and inserts values on collision instead of updating existing rows.
The return value of this query is an instance of InsertResult. InsertResult has the insertId field that holds the auto incremented id of the inserted row if the db returned one.
See the values method for more info and examples.
const result = await db
.replaceInto('person')
.values({
first_name: 'Jennifer',
last_name: 'Aniston'
})
.executeTakeFirst()
console.log(result.insertId)
Creates a select
query builder for the given table or tables.
The tables passed to this method are built as the query's from
clause.
Create a select query for one table:
db.selectFrom('person').selectAll()
The generated SQL (PostgreSQL):
select * from "person"
Create a select query for one table with an alias:
const persons = await db.selectFrom('person as p')
.select(['p.id', 'first_name'])
.execute()
console.log(persons[0].id)
The generated SQL (PostgreSQL):
select "p"."id", "first_name" from "person" as "p"
Create a select query from a subquery:
const persons = await db.selectFrom(
(eb) => eb.selectFrom('person').select('person.id as identifier').as('p')
)
.select('p.identifier')
.execute()
console.log(persons[0].identifier)
The generated SQL (PostgreSQL):
select "p"."identifier",
from (
select "person"."id" as "identifier" from "person"
) as p
Create a select query from raw sql:
import { sql } from 'kysely'
const items = await db
.selectFrom(sql<{ one: number }>`(select 1 as one)`.as('q'))
.select('q.one')
.execute()
console.log(items[0].one)
The generated SQL (PostgreSQL):
select "q"."one",
from (
select 1 as one
) as q
When you use the sql
tag you need to also provide the result type of the
raw snippet / query so that Kysely can figure out what columns are
available for the rest of the query.
The selectFrom
method also accepts an array for multiple tables. All
the above examples can also be used in an array.
import { sql } from 'kysely'
const items = await db.selectFrom([
'person as p',
db.selectFrom('pet').select('pet.species').as('a'),
sql<{ one: number }>`(select 1 as one)`.as('q')
])
.select(['p.id', 'a.species', 'q.one'])
.execute()
The generated SQL (PostgreSQL):
select "p".id, "a"."species", "q"."one"
from
"person" as "p",
(select "pet"."species" from "pet") as a,
(select 1 as one) as "q"
Creates a select
query builder without a from
clause.
If you want to create a select from
query, use the selectFrom
method instead.
This one can be used to create a plain select
statement without a from
clause.
This method accepts the same inputs as select. See its documentation for more examples.
const result = db.selectNoFrom((eb) => [
eb.selectFrom('person')
.select('id')
.where('first_name', '=', 'Jennifer')
.limit(1)
.as('jennifer_id'),
eb.selectFrom('pet')
.select('id')
.where('name', '=', 'Doggo')
.limit(1)
.as('doggo_id')
])
.executeTakeFirstOrThrow()
console.log(result.jennifer_id)
console.log(result.doggo_id)
The generated SQL (PostgreSQL):
select (
select "id"
from "person"
where "first_name" = $1
limit $2
) as "jennifer_id", (
select "id"
from "pet"
where "name" = $3
limit $4
) as "doggo_id"
Creates a TransactionBuilder that can be used to run queries inside a transaction.
The returned TransactionBuilder can be used to configure the transaction. The execute method can then be called to run the transaction. execute takes a function that is run inside the transaction. If the function throws, the transaction is rolled back. Otherwise the transaction is committed.
The callback function passed to the execute method gets the transaction object as its only argument. The transaction is of type Transaction which inherits Kysely. Any query started through the transaction object is executed inside the transaction.
This example inserts two rows in a transaction. If an error is thrown inside
the callback passed to the execute
method, the transaction is rolled back.
Otherwise it's committed.
const catto = await db.transaction().execute(async (trx) => {
const jennifer = await trx.insertInto('person')
.values({
first_name: 'Jennifer',
last_name: 'Aniston',
age: 40,
})
.returning('id')
.executeTakeFirstOrThrow()
return await trx.insertInto('pet')
.values({
owner_id: jennifer.id,
name: 'Catto',
species: 'cat',
is_favorite: false,
})
.returningAll()
.executeTakeFirst()
})
Setting the isolation level:
await db
.transaction()
.setIsolationLevel('serializable')
.execute(async (trx) => {
await doStuff(trx)
})
Creates an update query.
See the where method for examples on how to specify a where clause for the update operation.
See the set method for examples on how to specify the updates.
The return value of the query is an UpdateResult.
const result = await db
.updateTable('person')
.set({ first_name: 'Jennifer' })
.where('person.id', '=', 1)
.executeTakeFirst()
console.log(result.numUpdatedRows)
Creates a with
query (Common Table Expression).
await db
.with('jennifers', (db) => db
.selectFrom('person')
.where('first_name', '=', 'Jennifer')
.select(['id', 'age'])
)
.with('adult_jennifers', (db) => db
.selectFrom('jennifers')
.where('age', '>', 18)
.select(['id', 'age'])
)
.selectFrom('adult_jennifers')
.where('age', '<', 60)
.selectAll()
.execute()
The CTE name can optionally specify column names in addition to a name. In that case Kysely requires the expression to retun rows with the same columns.
await db
.with('jennifers(id, age)', (db) => db
.selectFrom('person')
.where('first_name', '=', 'Jennifer')
// This is ok since we return columns with the same
// names as specified by `jennifers(id, age)`.
.select(['id', 'age'])
)
.selectFrom('jennifers')
.selectAll()
.execute()
The first argument can also be a callback. The callback is passed
a CTEBuilder
instance that can be used to configure the CTE:
await db
.with(
(cte) => cte('jennifers').materialized(),
(db) => db
.selectFrom('person')
.where('first_name', '=', 'Jennifer')
.select(['id', 'age'])
)
.selectFrom('jennifers')
.selectAll()
.execute()
Returns a copy of this Kysely instance with the given plugin installed.
Creates a recursive with
query (Common Table Expression).
Note that recursiveness is a property of the whole with
statement.
You cannot have recursive and non-recursive CTEs in a same with
statement.
Therefore the recursiveness is determined by the first with
or
withRecusive
call you make.
See the with method for examples and more documentation.
Returns a copy of this Kysely instance with tables added to its database type.
This method only modifies the types and doesn't affect any of the executed queries in any way.
The following example adds and uses a temporary table:
await db.schema
.createTable('temp_table')
.temporary()
.addColumn('some_column', 'integer')
.execute()
const tempDb = db.withTables<{
temp_table: {
some_column: number
}
}>()
await tempDb
.insertInto('temp_table')
.values({ some_column: 100 })
.execute()
Generated using TypeDoc
The main Kysely class.
You should create one instance of
Kysely
per database using the Kysely constructor. EachKysely
instance maintains it's own connection pool.Examples
This example assumes your database has tables
person
andpet
: