65
65
the variable name (ex. ``$my_dict_var``). See ``In[6]`` and ``In[7]``
66
66
in the Examples section below.
67
67
68
- .. note::
69
-
70
- Due to the way IPython argument parser works, negative numbers in
71
- dictionaries are incorrectly "recognized" as additional arguments,
72
- resulting in an error ("unrecognized arguments"). To get around this,
73
- pass such dictionary as a JSON string variable.
74
-
75
68
* ``<query>`` (required, cell argument):
76
69
SQL query to run. If the query does not contain any whitespace (aside
77
70
from leading and trailing whitespace), it is assumed to represent a
159
152
except ImportError : # pragma: NO COVER
160
153
raise ImportError ("This module can only be loaded in IPython." )
161
154
155
+ import six
156
+
162
157
from google .api_core import client_info
163
158
from google .api_core .exceptions import NotFound
164
159
import google .auth
165
160
from google .cloud import bigquery
166
161
import google .cloud .bigquery .dataset
167
162
from google .cloud .bigquery .dbapi import _helpers
168
- import six
163
+ from google . cloud . bigquery . ipython_magics import line_arg_parser as lap
169
164
170
165
171
166
IPYTHON_USER_AGENT = "ipython-{}" .format (IPython .__version__ )
@@ -473,7 +468,11 @@ def _cell_magic(line, query):
473
468
Returns:
474
469
pandas.DataFrame: the query results.
475
470
"""
476
- args = magic_arguments .parse_argstring (_cell_magic , line )
471
+ # The built-in parser does not recognize Python structures such as dicts, thus
472
+ # we extract the "--params" option and inteprpret it separately.
473
+ params_option_value , rest_of_args = _split_args_line (line )
474
+
475
+ args = magic_arguments .parse_argstring (_cell_magic , rest_of_args )
477
476
478
477
if args .use_bqstorage_api is not None :
479
478
warnings .warn (
@@ -484,11 +483,17 @@ def _cell_magic(line, query):
484
483
use_bqstorage_api = not args .use_rest_api
485
484
486
485
params = []
487
- if args .params is not None :
488
- try :
489
- params = _helpers .to_query_parameters (
490
- ast .literal_eval ("" .join (args .params ))
486
+ if params_option_value :
487
+ # A non-existing params variable is not expanded and ends up in the input
488
+ # in its raw form, e.g. "$query_params".
489
+ if params_option_value .startswith ("$" ):
490
+ msg = 'Parameter expansion failed, undefined variable "{}".' .format (
491
+ params_option_value [1 :]
491
492
)
493
+ raise NameError (msg )
494
+
495
+ try :
496
+ params = _helpers .to_query_parameters (ast .literal_eval (params_option_value ))
492
497
except Exception :
493
498
raise SyntaxError (
494
499
"--params is not a correctly formatted JSON string or a JSON "
@@ -598,6 +603,25 @@ def _cell_magic(line, query):
598
603
close_transports ()
599
604
600
605
606
+ def _split_args_line (line ):
607
+ """Split out the --params option value from the input line arguments.
608
+
609
+ Args:
610
+ line (str): The line arguments passed to the cell magic.
611
+
612
+ Returns:
613
+ Tuple[str, str]
614
+ """
615
+ lexer = lap .Lexer (line )
616
+ scanner = lap .Parser (lexer )
617
+ tree = scanner .input_line ()
618
+
619
+ extractor = lap .QueryParamsExtractor ()
620
+ params_option_value , rest_of_args = extractor .visit (tree )
621
+
622
+ return params_option_value , rest_of_args
623
+
624
+
601
625
def _make_bqstorage_client (use_bqstorage_api , credentials ):
602
626
if not use_bqstorage_api :
603
627
return None
0 commit comments