@@ -87,6 +87,126 @@ def test_upsert_vectors_upsertInputVectorsSparse(self, mocker):
87
87
sparse_values = SparseValues (indices = self .sparse_indices_2 , values = self .sparse_values_2 ))],
88
88
)
89
89
90
+ def test_upsert_dict (self , mocker ):
91
+ mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
92
+ dict1 = {'id' : 'vec1' , 'values' : self .vals1 }
93
+ dict2 = {'id' : 'vec2' , 'values' : self .vals2 }
94
+ self .index .upsert ([dict1 , dict2 ], namespace = 'ns' )
95
+ self ._assert_called_once ([
96
+ self .expected_vec1 ,
97
+ self .expected_vec2 ]
98
+ )
99
+
100
+ def test_upsert_dict_md (self , mocker ):
101
+ mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
102
+ dict1 = {'id' : 'vec1' , 'values' : self .vals1 , 'metadata' : self .md1 }
103
+ dict2 = {'id' : 'vec2' , 'values' : self .vals2 , 'metadata' : self .md2 }
104
+ self .index .upsert ([dict1 , dict2 ], namespace = 'ns' )
105
+ self ._assert_called_once ([
106
+ self .expected_vec_md1 ,
107
+ self .expected_vec_md2 ]
108
+ )
109
+
110
+ def test_upsert_dict_sparse (self , mocker ):
111
+ mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
112
+ dict1 = {'id' : 'vec1' , 'values' : self .vals1 ,
113
+ 'sparse_values' : {'indices' : self .sparse_indices_1 , 'values' : self .sparse_values_1 }}
114
+ dict2 = {'id' : 'vec2' , 'values' : self .vals2 ,
115
+ 'sparse_values' : {'indices' : self .sparse_indices_2 , 'values' : self .sparse_values_2 }}
116
+ self .index .upsert ([dict1 , dict2 ], namespace = 'ns' )
117
+ self ._assert_called_once ([
118
+ Vector (id = 'vec1' , values = self .vals1 , metadata = {},
119
+ sparse_values = SparseValues (indices = self .sparse_indices_1 , values = self .sparse_values_1 )),
120
+ Vector (id = 'vec2' , values = self .vals2 , metadata = {},
121
+ sparse_values = SparseValues (indices = self .sparse_indices_2 , values = self .sparse_values_2 ))]
122
+ )
123
+
124
+ def test_upsert_dict_sparse_md (self , mocker ):
125
+ mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
126
+ dict1 = {'id' : 'vec1' , 'values' : self .vals1 ,
127
+ 'sparse_values' : {'indices' : self .sparse_indices_1 , 'values' : self .sparse_values_1 },
128
+ 'metadata' : self .md1 }
129
+ dict2 = {'id' : 'vec2' , 'values' : self .vals2 ,
130
+ 'sparse_values' : {'indices' : self .sparse_indices_2 , 'values' : self .sparse_values_2 },
131
+ 'metadata' : self .md2 }
132
+ self .index .upsert ([dict1 , dict2 ], namespace = 'ns' )
133
+ self ._assert_called_once ([
134
+ Vector (id = 'vec1' , values = self .vals1 , metadata = dict_to_proto_struct (self .md1 ),
135
+ sparse_values = SparseValues (indices = self .sparse_indices_1 , values = self .sparse_values_1 )),
136
+ Vector (id = 'vec2' , values = self .vals2 , metadata = dict_to_proto_struct (self .md2 ),
137
+ sparse_values = SparseValues (indices = self .sparse_indices_2 , values = self .sparse_values_2 ))]
138
+ )
139
+
140
+ def test_upsert_dict_negative (self , mocker ):
141
+ mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
142
+
143
+ # Missing required keys
144
+ dict1 = {'values' : self .vals1 }
145
+ dict2 = {'id' : 'vec2' }
146
+ with pytest .raises (ValueError ):
147
+ self .index .upsert ([dict1 , dict2 ])
148
+ with pytest .raises (ValueError ):
149
+ self .index .upsert ([dict1 ])
150
+ with pytest .raises (ValueError ):
151
+ self .index .upsert ([dict2 ])
152
+
153
+ # Excess keys
154
+ dict1 = {'id' : 'vec1' , 'values' : self .vals1 }
155
+ dict2 = {'id' : 'vec2' , 'values' : self .vals2 , 'animal' : 'dog' }
156
+ with pytest .raises (ValueError ) as e :
157
+ self .index .upsert ([dict1 , dict2 ])
158
+ assert 'animal' in str (e .value )
159
+
160
+ dict1 = {'id' : 'vec1' , 'values' : self .vals1 , 'metadatta' : self .md2 }
161
+ dict2 = {'id' : 'vec2' , 'values' : self .vals2 }
162
+ with pytest .raises (ValueError ) as e :
163
+ self .index .upsert ([dict1 , dict2 ])
164
+ assert 'metadatta' in str (e .value )
165
+
166
+ @pytest .mark .parametrize ("key,new_val" , [
167
+ ("id" , 4.2 ),
168
+ ("id" , ['vec1' ]),
169
+ ("values" , ['the' , 'lazy' , 'fox' ]),
170
+ ("values" , 'the lazy fox' ),
171
+ ("values" , 0.5 ),
172
+ ("metadata" , np .nan ),
173
+ ("metadata" , ['key1' , 'key2' ]),
174
+ ("sparse_values" , 'cat' ),
175
+ ("sparse_values" , []),
176
+ ])
177
+ def test_upsert_dict_negative_types (self , mocker , key , new_val ):
178
+ mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
179
+
180
+ full_dict1 = {'id' : 'vec1' , 'values' : self .vals1 ,
181
+ 'sparse_values' : {'indices' : self .sparse_indices_1 , 'values' : self .sparse_values_1 },
182
+ 'metadata' : self .md1 }
183
+
184
+ dict1 = deepcopy (full_dict1 )
185
+ dict1 [key ] = new_val
186
+ with pytest .raises (TypeError ) as e :
187
+ self .index .upsert ([dict1 ])
188
+ assert key in str (e .value )
189
+
190
+ @pytest .mark .parametrize ("key,new_val" , [
191
+ ("indices" , 3 ),
192
+ ("indices" , [1.2 , 0.5 ]),
193
+ ("values" , ['1' , '4.4' ]),
194
+ ("values" , 0.5 ),
195
+ ])
196
+ def test_upsert_dict_negative_types_sparse (self , mocker , key , new_val ):
197
+ mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
198
+
199
+ full_dict1 = {'id' : 'vec1' , 'values' : self .vals1 ,
200
+ 'sparse_values' : {'indices' : self .sparse_indices_1 , 'values' : self .sparse_values_1 },
201
+ 'metadata' : self .md1 }
202
+
203
+ dict1 = deepcopy (full_dict1 )
204
+ dict1 ['sparse_values' ][key ] = new_val
205
+ with pytest .raises (TypeError ) as e :
206
+ self .index .upsert ([dict1 ])
207
+ assert 'sparse' in str (e .value )
208
+ assert key in str (e .value )
209
+
90
210
def test_upsert_async_upsertInputVectorsAsync (self , mocker ):
91
211
mocker .patch .object (self .index , '_wrap_grpc_call' , autospec = True )
92
212
self .index .upsert ([self .expected_vec_md1 ,
0 commit comments