1
1
import { flatten } from 'lodash'
2
+ import { v4 as uuidv4 } from 'uuid'
2
3
import { createClient } from '@supabase/supabase-js'
3
4
import { Document } from '@langchain/core/documents'
4
5
import { Embeddings } from '@langchain/core/embeddings'
@@ -213,7 +214,7 @@ class Supabase_VectorStores implements INode {
213
214
}
214
215
215
216
class SupabaseUpsertVectorStore extends SupabaseVectorStore {
216
- async addVectors ( vectors : number [ ] [ ] , documents : Document [ ] ) : Promise < string [ ] > {
217
+ async addVectors ( vectors : number [ ] [ ] , documents : Document [ ] , options ?: { ids ?: string [ ] | number [ ] } ) : Promise < string [ ] > {
217
218
if ( vectors . length === 0 ) {
218
219
return [ ]
219
220
}
@@ -223,23 +224,36 @@ class SupabaseUpsertVectorStore extends SupabaseVectorStore {
223
224
metadata : documents [ idx ] . metadata
224
225
} ) )
225
226
226
- let idx = 0
227
- const { count } = await this . client . from ( this . tableName ) . select ( '*' , { count : 'exact' , head : true } )
228
- if ( count ) {
229
- idx = count
230
- }
231
-
232
227
let returnedIds : string [ ] = [ ]
233
228
for ( let i = 0 ; i < rows . length ; i += this . upsertBatchSize ) {
234
- const chunk = rows . slice ( i , i + this . upsertBatchSize ) . map ( ( row ) => {
235
- idx = idx += 1
236
- return { id : idx , ...row }
229
+ const chunk = rows . slice ( i , i + this . upsertBatchSize ) . map ( ( row , j ) => {
230
+ if ( options ?. ids ) {
231
+ return { id : options . ids [ i + j ] , ...row }
232
+ }
233
+ return row
237
234
} )
238
235
239
- const res = await this . client . from ( this . tableName ) . upsert ( chunk ) . select ( )
236
+ let res = await this . client . from ( this . tableName ) . upsert ( chunk ) . select ( )
237
+
240
238
if ( res . error ) {
241
- throw new Error ( `Error inserting: ${ res . error . message } ${ res . status } ${ res . statusText } ` )
239
+ // If the error is due to null value in column "id", we will generate a new id for the row
240
+ if ( res . error . message . includes ( `null value in column "id"` ) ) {
241
+ const chunk = rows . slice ( i , i + this . upsertBatchSize ) . map ( ( row , y ) => {
242
+ if ( options ?. ids ) {
243
+ return { id : options . ids [ i + y ] , ...row }
244
+ }
245
+ return { id : uuidv4 ( ) , ...row }
246
+ } )
247
+ res = await this . client . from ( this . tableName ) . upsert ( chunk ) . select ( )
248
+
249
+ if ( res . error ) {
250
+ throw new Error ( `Error inserting: ${ res . error . message } ${ res . status } ${ res . statusText } ` )
251
+ }
252
+ } else {
253
+ throw new Error ( `Error inserting: ${ res . error . message } ${ res . status } ${ res . statusText } ` )
254
+ }
242
255
}
256
+
243
257
if ( res . data ) {
244
258
returnedIds = returnedIds . concat ( res . data . map ( ( row ) => row . id ) )
245
259
}
0 commit comments