efaj efaj - 5 months ago 11
Python Question

must be str, not bytes | 'str' has no attribute 'decode'

I have this simple code to extract from a mongo database:

import sys
import codecs
import datetime
from pymongo import MongoClient

sys.stdout = codecs.getwriter('utf8')(sys.stdout)

mongo_db = "database"
collectionId = "coll name"

def main(argv):
client = MongoClient("mongodb://localhost:27017")
db = client[mongo_db]
collection = db[collectionId]

cursor = collection.find({})
for document in cursor:
# if "content" in document:
# sys.stdout.write(
# "|"+(document['content'] if document['content'] is not None else "")+"\n")
for key, value in document.items() :
sys.stdout.write(key.decode('utf-8'))

if __name__ == "__main__":
main(sys.argv)


running it like this, gets me


AttributeError: 'str' object has no attribute 'decode'


So... it's a str object, then? but if I remove the decode, I get


TypeError: must be str, not bytes


and, it's not like it's printing anything, so, it must be failing at the first key? but... can the first key be neither str nor bytes??? how can I print this?

EDIT testing with flush:

for key, value in document.items() :
sys.stdout.write("1")
sys.stdout.flush()
sys.stdout.write(key.decode('utf-8'))
sys.stdout.flush()


I changed the for to that, getting the error

~/Desktop$ python3 sentimongo.py
Traceback (most recent call last):
File "sentimongo.py", line 30, in <module>
main(sys.argv)
File "sentimongo.py", line 24, in main
sys.stdout.write("1")
File "/usr/lib/python3.4/codecs.py", line 374, in write
self.stream.write(data)
TypeError: must be str, not bytes

Answer
sys.stdout = codecs.getwriter('utf8')(sys.stdout)

This line changes the standard output, so it does different things than you normally see. In Python 3 you don’t really need to care about converting things to utf8 since everything already is a unicode string.

If you remove that line, writing a normal string (or even printing one) should work fine.