Перейти к основному содержанию

Вставка с использованием QueryBuilder

Неофициальный Бета-перевод

Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →

Вы можете создавать INSERT-запросы с помощью QueryBuilder. Примеры:

await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values([
{ firstName: "Timber", lastName: "Saw" },
{ firstName: "Phantom", lastName: "Lancer" },
])
.execute()

Это наиболее производительный способ вставки строк в вашу базу данных. Таким же образом можно выполнять массовую вставку данных.

Поддержка сырого SQL

В некоторых случаях при выполнении SQL-запросов необходимо использовать значение в виде функции:

await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: () => "CONCAT('S', 'A', 'W')",
})
.execute()

Внимание: При работе с сырым SQL убедитесь, что значения должным образом санированы для предотвращения SQL-инъекций.

Обновление значений при конфликте (ON CONFLICT)

Если вставляемые значения конфликтуют с существующими данными, функция orUpdate позволяет обновить конкретные значения в конфликтующей цели.

await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"])
.execute()

Обновление значений при конфликте с условием (Postgres, Oracle, MSSQL, SAP HANA)

await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"], {
overwriteCondition: {
where: {
firstName: Equal("Phantom"),
},
},
})
.execute()

Игнорирование ошибок (IGNORE для MySQL) или отсутствие действий (DO NOTHING для Postgres, Oracle, MSSQL, SAP HANA) при вставке

Если вставляемые данные конфликтуют с существующими или содержат недопустимые значения, функция orIgnore позволяет подавить ошибки и вставить только валидные строки.

await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orIgnore()
.execute()

Пропуск обновления данных при неизменных значениях (Postgres, Oracle, MSSQL, SAP HANA)

await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"], {
skipUpdateIfNoValuesChanged: true,
})
.execute()

Использование частичного индекса (Postgres)

await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"], {
skipUpdateIfNoValuesChanged: true,
indexPredicate: "date > 2020-01-01",
})
.execute()

Вставка из выборки (SELECT)

Вы можете вставлять данные из одной таблицы в другую с помощью запроса SELECT, используя метод valuesFromSelect(). Это создаёт инструкцию INSERT INTO ... SELECT FROM, которая полезна для миграции данных, архивирования или копирования между таблицами.

Использование SelectQueryBuilder напрямую

// Create a select query to get the source data
const selectQuery = dataSource
.createQueryBuilder()
.select(["user.firstName", "user.lastName"])
.from(User, "user")
.where("user.isActive = :isActive", { isActive: true })

// Insert the selected data into another table
await dataSource
.createQueryBuilder()
.insert()
.into(ArchivedUser, ["firstName", "lastName"])
.valuesFromSelect(selectQuery)
.execute()

Использование функции обратного вызова

Для построения запроса выборки также можно использовать функцию обратного вызова:

await dataSource
.createQueryBuilder()
.insert()
.into(ArchivedUser, ["firstName", "lastName", "archivedAt"])
.valuesFromSelect((qb) =>
qb
.select(["user.firstName", "user.lastName", "NOW()"])
.from(User, "user")
.where("user.deletedAt IS NOT NULL"),
)
.execute()

С использованием соединений (JOIN)

В запросе выборки можно применять соединения для объединения данных из нескольких таблиц:

await dataSource
.createQueryBuilder()
.insert()
.into(UserReport, ["userName", "orderCount"])
.valuesFromSelect((qb) =>
qb
.select(["user.name", "COUNT(order.id)"])
.from(User, "user")
.leftJoin("user.orders", "order")
.groupBy("user.id"),
)
.execute()

Примечание: При использовании valuesFromSelect() обработчики событий сущностей и подписчики (@BeforeInsert, @AfterInsert) не вызываются, поскольку в процессе вставки не создаются экземпляры сущностей.

Примечание: Опция updateEntity не действует с valuesFromSelect(), так как отсутствуют экземпляры сущностей для обновления.