Yes, this was a bug. It's fixed in Bulbs 0.3.23:
https://github.com/espeed/bulbs/commit/7f104cdbc30f27ea76b036cfa0d0a694f074153e
Question
I'm getting Unicode errors while trying to add data to Neo4J via Bulbs when the data contains non-ascii data.
the following code fails:
from bulbs.model import Node
from bulbs.property import String
from bulbs.neo4jserver import Graph
class User(Node):
element_type="user"
name = String(nullable=False)
g = Graph()
g.add_proxy("users", User)
user_data = {u'name': u'Aname M\xf6ller'}
g.users.create(**user_data)
with a UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 7: ordinal not in range(128)
The error is occurring in the bulbs.utils.u
function, via codecs.unicode_escape_decode()
.
Some hopefully relevant info:
$>python -V
'2.7.3'
>>>type(user_data['name'])
type('unicode')
>>>import bulbs
>>>bulbs.__version__
'0.3'
The Neo4J docs state that all String objects are saved as unicode, so why is my unicode data not being accepted? I hope I am just missing something silly.
Solution
Yes, this was a bug. It's fixed in Bulbs 0.3.23:
https://github.com/espeed/bulbs/commit/7f104cdbc30f27ea76b036cfa0d0a694f074153e
OTHER TIPS
After refreshing myself on Python and unicode, I got around the problem, though only by wrapping my problem line with a try, catch, and then encoding the problem data to 'utf-8'. Not the most elegant solution, but the following code seems to be working for me.
from bulbs.model import Node
from bulbs.property import String
from bulbs.neo4jserver import Graph
class User(Node):
element_type="user"
name = String(nullable=False)
g = Graph()
g.add_proxy("users", User)
user_data = {u'name': u'Aname M\xf6ller'}
try:
g.users.create(**user_data)
except UnicodeEncodeError:
for k, v in user_data.iteritems():
try:
user_data[k] = unicode.encode(v, 'utf-8')
except TypeError:
# Fails for non string values
pass
g.users.create(**user_data)
The only issue I have with this. If the bulbs
logger is active, then the error msg with a traceback are logged on the first call to create()
. Not a deal breaker, just a bit annoying.
Haven't tried this on Python 3, any one have something to chime in on the matter?