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, cookie,
foreign_key_checks = true, foreign_key_checks = true,
raw = false, raw = false,
insertOneByOneAsFallback = false,
}: { }: {
chunkSize?: number; chunkSize?: number;
cookie?: any; cookie?: any;
foreign_key_checks?: boolean; foreign_key_checks?: boolean;
raw?: boolean; raw?: boolean;
insertOneByOneAsFallback?: boolean;
} = {}, } = {},
) { ) {
let trx; let trx;
@ -2135,14 +2137,17 @@ class BaseModelSqlv2 {
let response; let response;
if (this.isSqlite) { // insert one by one as fallback to get ids for sqlite and mysql
// sqlite doesnt support returning, so insert one by one and return ids if (insertOneByOneAsFallback && (this.isSqlite || this.isMySQL)) {
// sqlite and mysql doesnt support returning, so insert one by one and return ids
response = []; response = [];
const aiPkCol = this.model.primaryKeys.find((pk) => pk.ai);
for (const insertData of insertDatas) { for (const insertData of insertDatas) {
const query = trx(this.tnPath).insert(insertData); const query = trx(this.tnPath).insert(insertData);
const id = (await query)[0]; const id = (await query)[0];
response.push(id); response.push(aiPkCol ? { [aiPkCol.title]: id } : id);
} }
} else { } else {
response = 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 then do bulk insert
if (Array.isArray(param.body)) { const result = await baseModel.bulkInsert(
return await baseModel.bulkInsert(param.body, { cookie: param.cookie }); Array.isArray(param.body) ? param.body : [param.body],
} else { { cookie: param.cookie, insertOneByOneAsFallback: true },
return await baseModel.insert(param.body, null, param.cookie); );
}
return Array.isArray(param.body) ? result : result[0];
} }
async dataUpdate(param: { async dataUpdate(param: {
@ -119,7 +120,7 @@ export class DataTableService {
const baseModel = await Model.getBaseModelSQL({ const baseModel = await Model.getBaseModelSQL({
id: model.id, id: model.id,
viewId: view?.id, viewId: view?.id,
dbDriver: await NcConnectionMgrv2.get(base) dbDriver: await NcConnectionMgrv2.get(base),
}); });
// //
// // todo: Should have error http status code // // todo: Should have error http status code
@ -129,7 +130,6 @@ export class DataTableService {
// } // }
// return await baseModel.delByPk(param.rowId, null, param.cookie); // return await baseModel.delByPk(param.rowId, null, param.cookie);
const res = await baseModel.bulkUpdate( const res = await baseModel.bulkUpdate(
Array.isArray(param.body) ? param.body : [param.body], Array.isArray(param.body) ? param.body : [param.body],
{ cookie: param.cookie }, { cookie: param.cookie },
@ -190,4 +190,29 @@ export class DataTableService {
return { model, view }; 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