Skip to content

Commit 3502121

Browse files
committed
fixed json handling issue
1 parent 1eb00f6 commit 3502121

File tree

4 files changed

+49
-17
lines changed

4 files changed

+49
-17
lines changed

CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
# Changelog
22

3-
## v3.7.1 (2024-11-19)
3+
## v3.7.2 (2024-11-19)
44

55
### Updates
66

77
- Added `http_debug` constructor argument to return HTTP log information
88

9+
### Bug Fixes
10+
11+
- Fixed issue passing JSON strings to queries, added test
12+
913
## v3.7.0 (2024-11-08)
1014

1115
### Updates

pystackql/stackql.py

+29-15
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import sys, subprocess, json, os, asyncio, functools
1212
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
1313
import pandas as pd
14-
import tempfile
14+
import tempfile, shlex
1515

1616
from io import StringIO
1717

@@ -205,8 +205,9 @@ def _run_query(self, query, custom_auth=None, env_vars=None):
205205
:raises FileNotFoundError: If the StackQL binary isn't found.
206206
:raises Exception: For any other exceptions during the execution, providing a generic error message.
207207
"""
208+
208209
local_params = self.params.copy()
209-
local_params.insert(1, f'"{query}"')
210+
local_params.insert(1, shlex.quote(query))
210211
script_path = None
211212

212213
# Handle custom authentication if provided
@@ -240,19 +241,32 @@ def _run_query(self, query, custom_auth=None, env_vars=None):
240241
full_command = " ".join([self.bin_path] + local_params)
241242

242243
try:
243-
with subprocess.Popen(full_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as iqlPopen:
244-
stdout, stderr = iqlPopen.communicate()
245-
246-
if self.debug:
247-
self._debug_log(f"query: {query}")
248-
self._debug_log(f"stdout: {stdout}")
249-
self._debug_log(f"stderr: {stderr}")
250-
251-
# Process stdout and stderr
252-
if stderr:
253-
output["error"] = stderr.decode('utf-8') if isinstance(stderr, bytes) else str(stderr)
254-
if stdout:
255-
output["data"] = stdout.decode('utf-8') if isinstance(stdout, bytes) else str(stdout)
244+
245+
full_command = full_command.replace("\n", " ")
246+
247+
result = subprocess.run(
248+
full_command,
249+
shell=True,
250+
text=True,
251+
capture_output=True
252+
)
253+
254+
stdout = result.stdout
255+
stderr = result.stderr
256+
returncode = result.returncode
257+
258+
if self.debug:
259+
self._debug_log(f"fullcommand: {full_command}")
260+
self._debug_log(f"returncode: {returncode}")
261+
self._debug_log(f"stdout: {stdout}")
262+
self._debug_log(f"stderr: {stderr}")
263+
264+
# Process stdout and stderr
265+
if stderr:
266+
output["error"] = stderr.decode('utf-8') if isinstance(stderr, bytes) else str(stderr)
267+
if stdout:
268+
output["data"] = stdout.decode('utf-8') if isinstance(stdout, bytes) else str(stdout)
269+
256270

257271
except FileNotFoundError:
258272
output["exception"] = f"ERROR: {self.bin_path} not found"

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
setup(
1212
name='pystackql',
13-
version='v3.7.1',
13+
version='v3.7.2',
1414
description='A Python interface for StackQL',
1515
long_description=readme,
1616
author='Jeffrey Aven',

tests/pystackql_tests.py

+14
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@ def test_18_execute_custom_auth_env_vars(self):
263263
self.assertEqual(result, expected_result, f"Expected result: {expected_result}, got: {result}")
264264
print_test_result(f"Test 18 execute with custom auth and command-specific environment variables\nRESULT: {result}", result == expected_result)
265265

266+
@pystackql_test_setup()
267+
def test_19_json_extract_function(self):
268+
query = """
269+
SELECT
270+
json_extract('{"Key":"StackName","Value":"aws-stack"}', '$.Key') as key,
271+
json_extract('{"Key":"StackName","Value":"aws-stack"}', '$.Value') as value
272+
"""
273+
expected_result = [
274+
{'key': {'String': 'StackName', 'Valid': True}, 'value': {'String': 'aws-stack', 'Valid': True}}
275+
]
276+
result = self.stackql.execute(query)
277+
self.assertEqual(result, expected_result, f"Expected result: {expected_result}, got: {result}")
278+
print_test_result(f"Test 19 complex object handling\nRESULT: {result}", result == expected_result)
279+
266280

267281
@unittest.skipIf(platform.system() == "Windows", "Skipping async tests on Windows")
268282
class PyStackQLAsyncTests(PyStackQLTestsBase):

0 commit comments

Comments
 (0)