emehrkay / Pypher

Python Cypher Querybuilder
MIT License
164 stars 29 forks source link

Operators not allow for Nested Python dictionaires to be passed in #23

Closed tolmanam closed 5 years ago

tolmanam commented 5 years ago

I ran into an issue when trying to use a python dictionary to set the values for a node, when there happened to be a list with a nested dictionary in my dataset.

Example Code

args = { 'nested': [{'item': 'one'}], 'toplevel': 1}

new_node = Pypher()
new_node.MATCH.node('updated')
new_node.SET.updated += args
new_node.RETURN('updated')
str(new_node)

Results

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-26-3a12a1ff433a> in <module>
      6 new_node.SET.updated += args
      7 new_node.RETURN('updated')
----> 8 str(new_node)

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in __str__(self)
    235 
    236     def __str__(self):
--> 237         return self.__unicode__()
    238 
    239     def __unicode__(self):

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in __unicode__(self)
    265                 suff = ' '
    266 
--> 267             part = '{}{}{}'.format(pre, str(token), suff)
    268             tokens.append(part)
    269 

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in __str__(self)
    235 
    236     def __str__(self):
--> 237         return self.__unicode__()
    238 
    239     def __unicode__(self):

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in __unicode__(self)
    881                 return new
    882 
--> 883             value = params(self.value)
    884         elif self._BIND_PARAMS:
    885             param = self.bind_param(self.value)

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in params(item)
    861                     for k, v in item.items():
    862                         if isinstance(v, (list, set, tuple, dict)):
--> 863                             v = params(v)
    864                         elif self._BIND_PARAMS:
    865                             param = self.bind_param(v)

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in params(item)
    872                     for v in item:
    873                         if self._BIND_PARAMS:
--> 874                             param = self.bind_param(v)
    875                             v = param.placeholder
    876 

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in bind_param(self, value, name)
    206 
    207     def bind_param(self, value, name=None):
--> 208         return self.params.bind_param(value=value, name=name)
    209 
    210     def __getattr__(self, attr):

~/sandbox/krawler/.venv/lib/python3.6/site-packages/pypher/builder.py in bind_param(self, value, name)
    114                     name = k
    115                     break
--> 116         elif value in self._bound_params.keys():
    117             for k, v in self._bound_params.items():
    118                 if k == value:

TypeError: unhashable type: 'dict'
emehrkay commented 5 years ago

Thanks for the report. This should be fixed in 0.14.4 let me know if it works for you

tolmanam commented 5 years ago

Thanks! I've verified that this works now.