From b5a71c87df83f4db8f8096e73982334ffda3b6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoel=20Ben=C3=ADtez=20Fonseca?= Date: Wed, 11 Apr 2018 11:01:38 -0400 Subject: [PATCH 1/2] Fix reconstructing Query from dict Changes to be committed: modified: pydal/objects.py --- pydal/objects.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/pydal/objects.py b/pydal/objects.py index f4415fbad..64fd94023 100644 --- a/pydal/objects.py +++ b/pydal/objects.py @@ -46,12 +46,12 @@ 'id': '[1-9]\d*', 'decimal': '\d{1,10}\.\d{2}', 'integer': '[+-]?\d*', - 'float': '[+-]?\d*(\.\d*)?', + 'float': '[+-]?\d*(\.\d*)?', 'double': '[+-]?\d*(\.\d*)?', 'date': '\d{4}\-\d{2}\-\d{2}', 'time': '\d{2}\:\d{2}(\:\d{2}(\.\d*)?)?', 'datetime':'\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}(\:\d{2}(\.\d*)?)?', - } + } class Row(BasicStorage): @@ -380,9 +380,9 @@ def fields(self): def _structure(self): keys = ['name','type','writable','listable','searchable','regex','options', - 'default','label','unique','notnull','required'] + 'default','label','unique','notnull','required'] def noncallable(obj): return obj if not callable(obj) else None - return [{key: noncallable(getattr(field, key)) for key in keys} + return [{key: noncallable(getattr(field, key)) for key in keys} for field in self if field.readable and not field.type=='password'] @cachedprop @@ -782,7 +782,7 @@ def validate_and_insert(self, **fields): response.id = self.insert(**new_fields) return response - def validate_and_update(self, _key=DEFAULT, **fields): + def validate_and_update(self, _key=DEFAULT, **fields): response, new_fields = self._validate_fields(fields, 'update') #: select record(s) for update if _key is DEFAULT: @@ -878,9 +878,9 @@ def import_from_csv_file(self, null = '', unique = 'uuid', id_offset = None, # id_offset used only when id_map is None - transform = None, + transform = None, validate=False, - **kwargs + **kwargs ): """ Import records from csv file. @@ -1274,10 +1274,10 @@ def abs(self): return Expression( self.db, self._dialect.aggregate, self, 'ABS', self.type) - def cast(self, cast_as, **kwargs): + def cast(self, cast_as, **kwargs): return Expression( self.db, self._dialect.cast, self, self._dialect.types[cast_as] % kwargs, cast_as) - + def lower(self): return Expression( self.db, self._dialect.lower, self, None, self.type) @@ -1601,7 +1601,7 @@ class Field(Expression, Serializable): def __init__(self, fieldname, type='string', length=None, default=DEFAULT, required=False, requires=DEFAULT, ondelete='CASCADE', notnull=False, unique=False, uploadfield=True, widget=None, - label=None, comment=None, + label=None, comment=None, writable=True, readable=True, searchable=True, listable=True, regex=None, options=None, @@ -2172,14 +2172,15 @@ def build(self, d): d.get("second", None)) left = right = built = None - if op in ("AND", "OR"): + op = op.upper() + if op in ("_AND", "_OR"): if not (type(first), type(second)) == (dict, dict): raise SyntaxError("Invalid AND/OR query") - if op == "AND": + if op == "_AND": built = self.build(first) & self.build(second) else: built = self.build(first) | self.build(second) - elif op == "NOT": + elif op == "_NOT": if first is None: raise SyntaxError("Invalid NOT query") built = ~self.build(first) @@ -2195,8 +2196,8 @@ def build(self, d): else: right = v - if hasattr(self.db._adapter, op): - opm = getattr(self.db._adapter, op) + if hasattr(self.db._adapter.dialect, op.lower()): + opm = getattr(self.db._adapter.dialect, op.lower()) if op == "EQ": built = left == right From d517bc90bca9b1d7af3ec7a382e2483194f112ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoel=20Ben=C3=ADtez=20Fonseca?= Date: Wed, 11 Apr 2018 11:02:42 -0400 Subject: [PATCH 2/2] Typecasting name to unicode on uploadfs.open --- pydal/objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydal/objects.py b/pydal/objects.py index 64fd94023..7f7ae47be 100644 --- a/pydal/objects.py +++ b/pydal/objects.py @@ -1796,7 +1796,7 @@ def retrieve(self, name, path=None, nameonly=False): stream = BytesIO(to_bytes(data)) elif self.uploadfs: # ## if file is on pyfilesystem - stream = self.uploadfs.open(name, 'rb') + stream = self.uploadfs.open(unicode(name), 'rb') else: # ## if file is on regular filesystem # this is intentially a sting with filename and not a stream