espeed / bulbs

A Python persistence framework for graph databases like Neo4j, OrientDB and Titan.
http://bulbflow.org
Other
623 stars 82 forks source link

Strange behavior of the __eq__ method. #106

Closed adurieux closed 11 years ago

adurieux commented 11 years ago

Hi,

I am facing a strange behaviour when testing the equality of nodes:

from bulbs.model import Node
from bulbs.property import String, DateTime
from bulbs.utils import current_datetime

class User(Node):
    name = String()
    createdAt = DateTime(default=current_datetime)

graph.add_proxy('User', User)
user = graph.User.create()
user.name = 'Joe'

print "Before save :"
print user._data
print user.data()

user.save()
print "After save :"
print user._data
print user.data()

print "Retrieved through gremlin :"
results = graph.gremlin.query('g.v('+str(user.eid)+')', {})
result = next(results)
print result._data
print result.data()
print result == user

print "Retrieved through User.get :"
result = graph.User.get(user.eid)
print result._data
print result.data()
print result == user

Outputs :

Before save :
{u'createdAt': 1376346337}
{'name': u'Joe', u'createdAt': datetime.datetime(2013, 8, 12, 22, 25, 37)}

After save :
{'name': u'Joe', u'createdAt': datetime.datetime(2013, 8, 12, 22, 25, 37)}
{'name': u'Joe', u'createdAt': datetime.datetime(2013, 8, 12, 22, 25, 37)}

Retrieved through gremlin :
{u'name': u'Joe', u'createdAt': 1376346337}
{u'name': u'Joe', u'createdAt': 1376346337}
False

Retrieved through User.get :
{u'name': u'Joe', u'createdAt': 1376346337}
{u'name': u'Joe', u'createdAt': 1376346337}
False

As you can see, equality verification fails because of:

espeed commented 11 years ago

Actually, it's not coercing the Unix timestamp to a Python datetime object when it should be.

You defined a DateTime property on your User model so it should be coercing the Unix timestamp to a Python datetime object .

See https://github.com/espeed/bulbs/blob/master/bulbs/property.py#L521

After you retrieve it through get and gremlin, print type(result) -- it should return User, but I suspect it's returning Vertex because it looks like the User model's _initialize_element() method isn't being called.

See

espeed commented 11 years ago

Oh, the reason is you didn't set element_type = "user" on your User model -- element_type is required for all Vertex (Node) models and label is required for Edge (Relationship) models.

Bulbs uses element_type instead of the Python class name to make it easy to use with different client libraries or languages. You can change the variable name Bulbs uses for element_type by changing the value of type_var in Config:

See https://github.com/espeed/bulbs/blob/master/bulbs/config.py#L56

However, we should be doing a check to ensure that element_type and label are set on models.