AttributeError: 'str' object has no attribute 'decode'
luisdemarchi opened this issue · 2 comments
Your library is the one that has update and less time (almost 1 year hehe). I hope I can still get support with you, and I'm sorry for my English because I'm Brazilian.
I am getting an error that may be due to Python 3.x (3.6). There is a method that tries to recode an already encoded string.
import rom
class Presence(rom.Model):
name = rom.String(required=True, unique=True, index=True, keygen=rom.SIMPLE)
>>> Presence(channel_name='Luis').save()
15 <---- Number of records for this model
>>> Presence.get_by(channel_name='Luis')
ERROR 1
>>> Presence.query.filter(channel_name='Luis').all()
[] <--- ERROR 2: Not register
ERROR 1
....
File "/Volumes/MacHD/Users/Git/project-webservice/.env/lib/python3.6/site-packages/rom/columns.py", line 529, in _to_redis
return value.decode('latin-1').encode('utf-8')
AttributeError: 'str' object has no attribute 'decode'
Sorry. I found a new library and it worked in the right way. Thank you
https://walrus.readthedocs.io/en/latest/models.html#creating-updating-and-deleting
Okay, your problem with using rom is caused by a few issues:
- You are trying to use a byte string column to store a unicode string, instead of
rom.String()
, tryrom.Text()
- You are using the wrong index type for
Model.query.filter()
to work, as per: http://pythonhosted.org/rom/rom.html#rom.Column:
- SIMPLE/SIMPLE_CI - sorting only with
query.order_by('x')
- https://pythonhosted.org/rom/rom.html#rom.util.SIMPLE- IDENTITY/IDENTITY_CI - equality only with
query.filter(x=...)
- https://pythonhosted.org/rom/rom.html#rom.util.IDENTITY- FULL_TEXT - bag of words inverted index for
query.filter(x=...)
- https://pythonhosted.org/rom/rom.html#rom.util.FULL_TEXT
- If you want to keep the ordering, but still be able to get your data by identity, you can use
Presence.get_by()
, but again, you'll have to keep consistent with both your column types, column values, and query arguments:
$ python3.6
Python 3.6.1 (default, Apr 22 2017, 00:00:00)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import rom
>>> class Presence(rom.Model):
... name = rom.String(required=True, unique=True, index=True, keygen=rom.SIMPLE)
...
>>> Presence(name='broken').save()
2
>>> a = Presence.get_by(name='broken')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/josiah/open-source/rom/rom/model.py", line 601, in get_by
qvalues = list(map(cls._columns[attr]._to_redis, value))
File "/home/josiah/open-source/rom/rom/columns.py", line 530, in _to_redis
return value.decode('latin-1').encode('utf-8')
AttributeError: 'str' object has no attribute 'decode'
>>> Presence(name=b'not broken').save()
2
>>> Presence.get_by(name=b'not broken')
<__main__.Presence object at 0x7f4952417be0>
>>> Presence.get_by(name=b'broken')
- Now, you wouldn't necessarily want to use this one (I might use the
rom.FULL_TEXT
index instead), but this demonstrates that it does work.
>>> class Fix(rom.Model):
... name = rom.Text(required=True, unique=True, index=True, keygen=rom.IDENTITY)
...
>>> Fix(name='Fixed').save()
2
>>> Fix.get_by(name='Fixed')
<__main__.Fix object at 0x7f494faa9048>
>>> Fix.query.filter(name='Fixed').all()
[<__main__.Fix object at 0x7f494faa9048>]
>>>