quillsql 2.2.3__py3-none-any.whl → 2.2.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
quillsql/core.py CHANGED
@@ -91,8 +91,6 @@ class Quill:
91
91
  ):
92
92
  if not tenants:
93
93
  raise ValueError("You may not pass an empty tenants array.")
94
- if flags and not flags:
95
- raise ValueError("You may not pass an empty flags array.")
96
94
 
97
95
  responseMetadata = {}
98
96
  if not metadata:
@@ -108,7 +106,6 @@ class Quill:
108
106
 
109
107
  # Handle pivot-template task
110
108
  if task == "pivot-template":
111
- # Step 1: Get pivot template and queries from server
112
109
  pivot_payload = {
113
110
  **metadata,
114
111
  "tenants": tenants,
@@ -137,7 +134,6 @@ class Quill:
137
134
  distinct_values_query = pivot_template_response.get("metadata", {}).get("distinctValuesQuery")
138
135
  row_count_query = pivot_template_response.get("metadata", {}).get("rowCountQuery")
139
136
 
140
- # Step 2: Run the distinct values query to get unique values
141
137
  distinct_values = []
142
138
  if distinct_values_query:
143
139
  distinct_value_results = self.run_queries(
@@ -148,13 +144,11 @@ class Quill:
148
144
  None
149
145
  )
150
146
 
151
- # Parse distinct values from database results
152
147
  distinct_values = parse_distinct_values(
153
148
  distinct_value_results["queryResults"][0],
154
149
  config.get("databaseType")
155
150
  )
156
151
 
157
- # Step 3: Hydrate the template with the distinct values
158
152
  try:
159
153
  final_query = hydrate_pivot_template(template, distinct_values, config)
160
154
  except Exception as err:
@@ -164,10 +158,8 @@ class Quill:
164
158
  "data": {},
165
159
  }
166
160
 
167
- # Step 4: Run queries - pivot query and optional row count query
168
161
  queries_to_run = [final_query]
169
162
  if row_count_query:
170
- # Hydrate the rowCountQuery with the same distinct values
171
163
  hydrated_row_count_query = hydrate_pivot_template(
172
164
  row_count_query,
173
165
  distinct_values,
@@ -184,7 +176,6 @@ class Quill:
184
176
  )
185
177
 
186
178
  responseMetadata = pivot_template_response.get("metadata") or {}
187
- # Set rows and fields from first query result (the pivot query)
188
179
  if final_results.get("queryResults") and len(final_results["queryResults"]) >= 1:
189
180
  query_results = final_results["queryResults"][0]
190
181
  if query_results.get("rows"):
@@ -192,7 +183,6 @@ class Quill:
192
183
  if query_results.get("fields"):
193
184
  responseMetadata["fields"] = query_results["fields"]
194
185
 
195
- # Remove internal SDK fields before returning to frontend
196
186
  if "template" in responseMetadata:
197
187
  del responseMetadata["template"]
198
188
  if "distinctValuesQuery" in responseMetadata:
@@ -237,21 +227,34 @@ class Quill:
237
227
  )
238
228
 
239
229
  tenant_flags = []
240
- query_order = response.get('metadata', {}).get('queryOrder') or []
230
+ query_order = (response.get('metadata') or {}).get('queryOrder') or []
241
231
  query_results = (flag_query_results or {}).get('queryResults') or []
242
- for tenant_field, query_result in zip(query_order, query_results):
243
- rows = []
244
- if isinstance(query_result, dict):
245
- rows = query_result.get('rows') or []
246
- flags = {
247
- row.get('quill_flag')
248
- for row in rows
249
- if isinstance(row, dict) and row.get('quill_flag') is not None
250
- }
232
+ for index, tenant_field in enumerate(query_order):
233
+ query_result = (
234
+ query_results[index]
235
+ if index < len(query_results)
236
+ else {}
237
+ )
238
+ rows = (
239
+ query_result.get('rows')
240
+ if isinstance(query_result, dict)
241
+ else []
242
+ )
243
+ ordered_flags = []
244
+ seen = set()
245
+ for row in rows or []:
246
+ if not isinstance(row, dict):
247
+ continue
248
+ flag = row.get('quill_flag')
249
+ if flag is None or flag in seen:
250
+ continue
251
+ seen.add(flag)
252
+ ordered_flags.append(flag)
251
253
  tenant_flags.append({
252
254
  'tenantField': tenant_field,
253
- 'flags': list(flags),
255
+ 'flags': ordered_flags,
254
256
  })
257
+
255
258
  elif tenants[0] == SINGLE_TENANT and flags:
256
259
  if flags and isinstance(flags[0], dict):
257
260
  tenant_flags = [{'tenantField': SINGLE_TENANT, 'flags': flags}]
@@ -283,13 +286,14 @@ class Quill:
283
286
  and metadata.get("runQueryConfig").get("getColumns")
284
287
  else None
285
288
  )
286
- payload: dict = {
289
+ payload = {
287
290
  **metadata,
288
291
  "tenants": tenants,
289
292
  "flags": tenant_flags,
290
293
  "viewQuery": view_query,
291
- "preQueryResultsColumns": pre_query_columns,
292
294
  }
295
+ if pre_query_columns is not None:
296
+ payload["preQueryResultsColumns"] = pre_query_columns
293
297
  if admin_enabled is not None:
294
298
  payload["adminEnabled"] = admin_enabled
295
299
  if filters is not None:
@@ -336,21 +340,25 @@ class Quill:
336
340
  normalized_results.get("queryResults") or []
337
341
  )
338
342
 
339
- run_query_config = responseMetadata.get("runQueryConfig") or {}
340
- array_to_map = run_query_config.get("arrayToMap")
341
- if normalized_results.get("mapped_array") and array_to_map:
342
- target_collection = responseMetadata.get(array_to_map.get("arrayName"))
343
+ if (
344
+ normalized_results.get("mapped_array")
345
+ and metadata.get("runQueryConfig", {}).get("arrayToMap")
346
+ ):
347
+ array_to_map = metadata["runQueryConfig"]["arrayToMap"]
348
+ target_collection = responseMetadata.get(array_to_map["arrayName"])
343
349
  if isinstance(target_collection, list):
344
- for index, mapped_rows in enumerate(normalized_results["mapped_array"]):
350
+ for index, array in enumerate(normalized_results["mapped_array"]):
345
351
  if index >= len(target_collection):
346
352
  continue
347
353
  target_entry = target_collection[index]
348
- if isinstance(target_entry, dict):
349
- target_entry[array_to_map.get("field")] = mapped_rows
350
- normalized_results.pop("mapped_array", None)
354
+ if not isinstance(target_entry, dict):
355
+ target_entry = {}
356
+ target_collection[index] = target_entry
357
+ target_entry[array_to_map["field"]] = array if array is not None else []
358
+ del normalized_results["mapped_array"]
351
359
 
352
360
  query_results_list = normalized_results.get("queryResults") or []
353
- if len(query_results_list) == 1:
361
+ if len(query_results_list) == 1 and isinstance(query_results_list[0], dict):
354
362
  query_result = query_results_list[0]
355
363
  quill_results["metadata"]["rows"] = query_result.get("rows")
356
364
  quill_results["metadata"]["fields"] = query_result.get("fields")
@@ -483,3 +483,4 @@ def validate_template(template: str, config: PivotConfig) -> Dict[str, Any]:
483
483
  "errors": errors
484
484
  }
485
485
 
486
+
@@ -1,14 +1,21 @@
1
1
  def remove_fields(query_result, fields_to_remove):
2
+ if not isinstance(query_result, dict):
3
+ return query_result
2
4
  fields = [
3
5
  {"name": field["name"], "dataTypeID": field["dataTypeID"]}
4
- for field in query_result["fields"]
5
- if field["name"] not in fields_to_remove
6
+ for field in (query_result.get("fields") or [])
7
+ if field.get("name") not in fields_to_remove
6
8
  ]
7
- rows = [row for row in query_result["rows"]]
8
- for row in rows:
9
+ rows = []
10
+ for row in query_result.get("rows") or []:
11
+ if not isinstance(row, dict):
12
+ rows.append(row)
13
+ continue
14
+ filtered = dict(row)
9
15
  for field in fields_to_remove:
10
- if field in row:
11
- del row[field]
16
+ if field in filtered:
17
+ del filtered[field]
18
+ rows.append(filtered)
12
19
  return {"fields": fields, "rows": rows}
13
20
 
14
21
 
@@ -16,5 +23,8 @@ def array_to_map(queries, array_to_map, metadata, target_pool):
16
23
  mapped_array = []
17
24
  for i in range(len(queries)):
18
25
  query_result = target_pool.query(queries[i])
19
- mapped_array.append(query_result.get("rows"))
26
+ if isinstance(query_result, dict):
27
+ mapped_array.append(query_result.get("rows"))
28
+ else:
29
+ mapped_array.append([])
20
30
  return mapped_array
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quillsql
3
- Version: 2.2.3
3
+ Version: 2.2.5
4
4
  Summary: Quill SDK for Python.
5
5
  Home-page: https://github.com/quill-sql/quill-python
6
6
  Author: Quill
@@ -1,5 +1,5 @@
1
1
  quillsql/__init__.py,sha256=FiuoxaNZveKXOPB0hkpfGNlpZKmSn3pRwcqm9HKYbCQ,180
2
- quillsql/core.py,sha256=gUyM_To8Gdw30KFLqFLnvXykxCFoC7NE-A61cToEdXQ,23285
2
+ quillsql/core.py,sha256=OOvhFEya_DGmyE5U9nVUQ58ZBnePTNh5mKPg7OTSI_Q,23259
3
3
  quillsql/error.py,sha256=n9VKHw4FAgg7ZEAz2YQ8L_8FdRG_1shwGngf2iWhUSM,175
4
4
  quillsql/assets/__init__.py,sha256=oXQ2ZS5XDXkXTYjADxNfGt55cIn_rqfgWL2EDqjTyoI,45
5
5
  quillsql/assets/pgtypes.py,sha256=-B_2wUaoAsdX7_HnJhUlx4ptZQ6x-cXwuST9ACgGFdE,33820
@@ -10,11 +10,11 @@ quillsql/db/db_helper.py,sha256=qiIP-BM7R-3PhvWBELYjNazi-92EcQB0q9eN7Ej7XUA,2111
10
10
  quillsql/db/postgres.py,sha256=ZTLtUVTJHkqAj7nZkcwbmkSOwR2ySN7vS5snoxqLRN0,4156
11
11
  quillsql/utils/__init__.py,sha256=C2k9Xe0sG5XrP0XJo9K_-iej1S9PLMRKOYMeLxj7NYE,210
12
12
  quillsql/utils/filters.py,sha256=REXOLIQZDHL4EDKtConXY9_GaqUmc2uTcyUa2_4MvAg,6786
13
- quillsql/utils/pivot_template.py,sha256=NzHO7Ux8GVAKY-DUtsOmE7TUls2q6FJG2kgJxVWq-wQ,18282
14
- quillsql/utils/run_query_processes.py,sha256=FRmNvjTDLUBr7MqDKQmivdC0anwybMXUyzQbKnaZx70,698
13
+ quillsql/utils/pivot_template.py,sha256=HXtb-DigrqFhdHKX2jWeYeFZNuWCfZSyNw31Fy2fIok,18283
14
+ quillsql/utils/run_query_processes.py,sha256=QwnMr5UwXdtO_W88lv5nBaf6pJ_h5oWQnYd8K9oHQ5s,1030
15
15
  quillsql/utils/schema_conversion.py,sha256=TFfMibN9nOsxNRhHw5YIFl3jGTvipG81bxX4LFDulUY,314
16
16
  quillsql/utils/tenants.py,sha256=ZD2FuKz0gjBVSsThHDv1P8PU6EL8E009NWihE5hAH-Q,2022
17
- quillsql-2.2.3.dist-info/METADATA,sha256=m_GfCogVSbSTxw0MGKq-scyOyeipyRbcoU40BHE0yq4,1786
18
- quillsql-2.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- quillsql-2.2.3.dist-info/top_level.txt,sha256=eU2vHnVqwpYQJ3ADl1Q-DIBzbYejZRUhcMdN_4zMCz8,9
20
- quillsql-2.2.3.dist-info/RECORD,,
17
+ quillsql-2.2.5.dist-info/METADATA,sha256=AB1wJfgnGMitTW25kmjortFqmUVK4dlY74PFhFNXkL0,1786
18
+ quillsql-2.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
+ quillsql-2.2.5.dist-info/top_level.txt,sha256=eU2vHnVqwpYQJ3ADl1Q-DIBzbYejZRUhcMdN_4zMCz8,9
20
+ quillsql-2.2.5.dist-info/RECORD,,