Skip to content

Commit ad075c6

Browse files
authored
fix(pgvector): add skipInitializationCheck option to disable schema c… (#8414)
2 parents 6e349ee + 9367769 commit ad075c6

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

libs/langchain-community/src/vectorstores/pgvector.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface PGVectorStoreArgs {
2626
collectionMetadata?: Metadata | null;
2727
schemaName?: string | null;
2828
extensionSchemaName?: string | null;
29+
skipInitializationCheck?: boolean;
2930
columns?: {
3031
idColumnName?: string;
3132
vectorColumnName?: string;
@@ -213,6 +214,8 @@ export class PGVectorStore extends VectorStore {
213214

214215
extensionSchemaName: string | null;
215216

217+
skipInitializationCheck: boolean;
218+
216219
metadataColumnName: string;
217220

218221
filter?: Metadata;
@@ -247,6 +250,7 @@ export class PGVectorStore extends VectorStore {
247250
this.collectionMetadata = config.collectionMetadata ?? null;
248251
this.schemaName = config.schemaName ?? null;
249252
this.extensionSchemaName = config.extensionSchemaName ?? null;
253+
this.skipInitializationCheck = config.skipInitializationCheck ?? false;
250254

251255
this.filter = config.filter;
252256

@@ -741,6 +745,9 @@ export class PGVectorStore extends VectorStore {
741745
* @returns Promise that resolves when the table has been ensured.
742746
*/
743747
async ensureTableInDatabase(dimensions?: number): Promise<void> {
748+
if (this.skipInitializationCheck) {
749+
return;
750+
}
744751
const vectorQuery =
745752
this.extensionSchemaName == null
746753
? "CREATE EXTENSION IF NOT EXISTS vector;"
@@ -772,6 +779,9 @@ export class PGVectorStore extends VectorStore {
772779
*/
773780
async ensureCollectionTableInDatabase(): Promise<void> {
774781
try {
782+
if (this.skipInitializationCheck) {
783+
return;
784+
}
775785
const queryString = `
776786
CREATE TABLE IF NOT EXISTS ${this.computedCollectionTableName} (
777787
uuid uuid NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,

libs/langchain-community/src/vectorstores/tests/pgvector/pgvector.int.test.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,131 @@ describe("PGVectorStore with schema", () => {
821821
});
822822
});
823823

824+
describe("PGVectorStore with skipInitializationCheck", () => {
825+
let pgvectorVectorStore: PGVectorStore;
826+
const tableName = "testlangchain_skip_init";
827+
828+
afterEach(async () => {
829+
const pool = new pg.Pool(postgresConnectionOptions);
830+
await pool.query(`DROP TABLE IF EXISTS "${tableName}"`);
831+
await pool.end();
832+
});
833+
834+
test("skipInitializationCheck=false (default) should initialize tables", async () => {
835+
const config: PGVectorStoreArgs = {
836+
postgresConnectionOptions,
837+
tableName,
838+
columns: {
839+
idColumnName: "id",
840+
vectorColumnName: "vector",
841+
contentColumnName: "content",
842+
metadataColumnName: "metadata",
843+
},
844+
};
845+
846+
pgvectorVectorStore = await PGVectorStore.initialize(
847+
embeddingsEngine,
848+
config
849+
);
850+
851+
const result = await pgvectorVectorStore.pool.query(
852+
`SELECT EXISTS (
853+
SELECT FROM information_schema.tables
854+
WHERE table_schema = 'public'
855+
AND table_name = '${tableName}'
856+
)`
857+
);
858+
859+
expect(result.rows[0].exists).toBe(true);
860+
await pgvectorVectorStore.end();
861+
});
862+
863+
test("skipInitializationCheck=true should skip table initialization", async () => {
864+
const config: PGVectorStoreArgs = {
865+
postgresConnectionOptions,
866+
tableName,
867+
skipInitializationCheck: true,
868+
columns: {
869+
idColumnName: "id",
870+
vectorColumnName: "vector",
871+
contentColumnName: "content",
872+
metadataColumnName: "metadata",
873+
},
874+
};
875+
876+
pgvectorVectorStore = await PGVectorStore.initialize(
877+
embeddingsEngine,
878+
config
879+
);
880+
881+
const tableExists = await pgvectorVectorStore.pool.query(
882+
`SELECT EXISTS (
883+
SELECT FROM information_schema.tables
884+
WHERE table_schema = 'public'
885+
AND table_name = '${tableName}'
886+
)`
887+
);
888+
889+
expect(tableExists.rows[0].exists).toBe(false);
890+
891+
await pgvectorVectorStore.end();
892+
});
893+
894+
test("skipInitializationCheck=true should work with addDocuments", async () => {
895+
const setupPool = new pg.Pool(postgresConnectionOptions);
896+
897+
await setupPool.query(`CREATE EXTENSION IF NOT EXISTS vector`);
898+
await setupPool.query(`
899+
CREATE TABLE "${tableName}" (
900+
"id" uuid NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
901+
"content" text,
902+
"metadata" jsonb,
903+
"vector" vector(1536)
904+
);
905+
`);
906+
907+
await setupPool.end();
908+
909+
const config: PGVectorStoreArgs = {
910+
postgresConnectionOptions,
911+
tableName,
912+
skipInitializationCheck: true,
913+
columns: {
914+
idColumnName: "id",
915+
vectorColumnName: "vector",
916+
contentColumnName: "content",
917+
metadataColumnName: "metadata",
918+
},
919+
};
920+
921+
pgvectorVectorStore = await PGVectorStore.initialize(
922+
embeddingsEngine,
923+
config
924+
);
925+
926+
const documents = [
927+
{ pageContent: "Hello world", metadata: { source: "test" } },
928+
{
929+
pageContent: "Testing skipInitializationCheck",
930+
metadata: { source: "test" },
931+
},
932+
];
933+
934+
await pgvectorVectorStore.addDocuments(documents);
935+
936+
const query = await embeddingsEngine.embedQuery("Hello");
937+
const results = await pgvectorVectorStore.similaritySearchVectorWithScore(
938+
query,
939+
1
940+
);
941+
942+
expect(results).toHaveLength(1);
943+
expect(results[0][0].pageContent).toBe("Hello world");
944+
945+
await pgvectorVectorStore.end();
946+
});
947+
});
948+
824949
describe("PGVectorStore with HNSW index", () => {
825950
let pgvectorVectorStore: PGVectorStore;
826951
const tableName = "testlangchain";

0 commit comments

Comments
 (0)