Browse Source

fix: insert one by one in mysql and sqlite

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5901/head
Pranav C 1 year ago
parent
commit
5df92404e2
  1. 11
      packages/nocodb/src/db/BaseModelSqlv2.ts
  2. 39
      packages/nocodb/src/services/data-table.service.ts

11
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -2091,11 +2091,13 @@ class BaseModelSqlv2 {
cookie,
foreign_key_checks = true,
raw = false,
insertOneByOneAsFallback = false,
}: {
chunkSize?: number;
cookie?: any;
foreign_key_checks?: boolean;
raw?: boolean;
insertOneByOneAsFallback?: boolean;
} = {},
) {
let trx;
@ -2135,14 +2137,17 @@ class BaseModelSqlv2 {
let response;
if (this.isSqlite) {
// sqlite doesnt support returning, so insert one by one and return ids
// insert one by one as fallback to get ids for sqlite and mysql
if (insertOneByOneAsFallback && (this.isSqlite || this.isMySQL)) {
// sqlite and mysql doesnt support returning, so insert one by one and return ids
response = [];
const aiPkCol = this.model.primaryKeys.find((pk) => pk.ai);
for (const insertData of insertDatas) {
const query = trx(this.tnPath).insert(insertData);
const id = (await query)[0];
response.push(id);
response.push(aiPkCol ? { [aiPkCol.title]: id } : id);
}
} else {
response =

39
packages/nocodb/src/services/data-table.service.ts

@ -66,11 +66,12 @@ export class DataTableService {
});
// if array then do bulk insert
if (Array.isArray(param.body)) {
return await baseModel.bulkInsert(param.body, { cookie: param.cookie });
} else {
return await baseModel.insert(param.body, null, param.cookie);
}
const result = await baseModel.bulkInsert(
Array.isArray(param.body) ? param.body : [param.body],
{ cookie: param.cookie, insertOneByOneAsFallback: true },
);
return Array.isArray(param.body) ? result : result[0];
}
async dataUpdate(param: {
@ -119,7 +120,7 @@ export class DataTableService {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: await NcConnectionMgrv2.get(base)
dbDriver: await NcConnectionMgrv2.get(base),
});
//
// // todo: Should have error http status code
@ -129,7 +130,6 @@ export class DataTableService {
// }
// return await baseModel.delByPk(param.rowId, null, param.cookie);
const res = await baseModel.bulkUpdate(
Array.isArray(param.body) ? param.body : [param.body],
{ cookie: param.cookie },
@ -190,4 +190,29 @@ export class DataTableService {
return { model, view };
}
private async extractPks({ model, rows }: { rows: any[]; model?: Model }) {
return await Promise.all(
rows.map(async (row) => {
// if not object then return the value
if (typeof row !== 'object') return row;
let pk;
// if model is passed then use the model to get the pk columns and extract the pk values
if (model) {
pk = await model.getColumns().then((cols) =>
cols
.filter((col) => col.pk)
.map((col) => row[col.title])
.join('___'),
);
} else {
// if model is not passed then get all the values and join them
pk = Object.values(row).join('___');
}
return pk;
}),
);
}
}

Loading…
Cancel
Save