neo4j-contrib / neomodel

An Object Graph Mapper (OGM) for the Neo4j graph database.
https://neomodel.readthedocs.io
MIT License
961 stars 232 forks source link

Can't inflate <class 'neo4j.time.DateTime'> to datetime. #545

Open YuriyKortev opened 3 years ago

YuriyKortev commented 3 years ago

Hi,

im trying to get list of node in neomodel

m = Meet.nodes.all()

and getting this:

Traceback (most recent call last):
  File "venv\lib\site-packages\neomodel\properties.py", line 510, in inflate
    epoch = float(value)
TypeError: float() argument must be a string or a number, not 'DateTime'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "venv\lib\site-packages\neomodel\properties.py", line 123, in _validator
    return fn(self, value)
  File "venv\lib\site-packages\neomodel\properties.py", line 516, in inflate
    "Float or integer expected. Can't inflate {0} to datetime.".format(type(value)))
TypeError: Float or integer expected. Can't inflate <class 'neo4j.time.DateTime'> to datetime.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "venv\lib\site-packages\neomodel\match.py", line 524, in all
    return self.query_cls(self).build_ast()._execute(lazy)
  File "venv\lib\site-packages\neomodel\match.py", line 499, in _execute
    results, _ = db.cypher_query(query, self._query_params, resolve_objects=True)
  File "venv\lib\site-packages\neomodel\util.py", line 35, in wrapper
    return func(self, *args, **kwargs)
  File "venv\lib\site-packages\neomodel\util.py", line 224, in cypher_query
    results = self._object_resolution(results)
  File "venv\lib\site-packages\neomodel\util.py", line 174, in _object_resolution
    a_result_attribute[1])
  File "venv\lib\site-packages\neomodel\core.py", line 483, in inflate
    props[key] = prop.inflate(node_properties[db_property], node)
  File "venv\lib\site-packages\neomodel\properties.py", line 125, in _validator
    raise exc_class(self.name, self.owner, str(e), obj)
neomodel.exceptions.InflateError: Attempting to inflate property 'meet_datetime' on <Node id=8 labels=frozenset({'Meet'}) properties={'meet_datetime': neo4j.time.DateTime(2021, 1, 27, 11, 57, 49.477, tzinfo=<UTC>)}> of class 'Meet': Float or integer expected. Can't inflate <class 'neo4j.time.DateTime'> to datetime.

Class definition:

class Meet(StructuredNode):
       notes = StringProperty()
       meet_datetime = DateTimeProperty()
       patient = RelationshipTo('Patient', 'PATIENT', cardinality=One)
       doctor = RelationshipTo('Doctor', 'DOCTOR', cardinality=One)

meet_datetime property in database: m.meet_datetime """2021-01-27T11:57:49.477000000Z""" """2021-01-27T11:57:49.477000000Z""" """2021-01-27T11:57:49.477000000Z""" """2021-01-27T11:57:49.477000000Z"""

Thanks in advance.

alexlitvinenko commented 3 years ago

Hi, neomodel.DateTimeProperty expects float but you provided str.

YuriyKortev commented 3 years ago

@alexlitvinenko Thanks for answer, i'm not providing anything, i'm just calling

StructuredNode.nodes.all()

and getting error. Property meet_datetime in cypher has datetime type, was created with following command: m.meet_time=datetime()

alexlitvinenko commented 3 years ago

Try my example:

class Meet(StructuredNode):
    notes = StringProperty()
    meet_datetime = DateTimeProperty()

Meet(notes='test1', meet_datetime=datetime.now()).save()
Meet(notes='test2', meet_datetime=datetime.now()).save()

m = Meet.nodes.all()

print(m)

Printed: [<Meet: {'notes': 'test1', 'meet_datetime': datetime.datetime(2021, 1, 27, 13, 43, 45, 44876, tzinfo=), 'id': 645129}>, <Meet: {'notes': 'test2', 'meet_datetime': datetime.datetime(2021, 1, 27, 13, 43, 45, 56322, tzinfo=), 'id': 645138}>]

Then cypher: match (n:Meet) return n.notes, n.meet_datetime image

YuriyKortev commented 3 years ago

@alexlitvinenko thanks, but which way i can create meet_datetime in cypher and read by neomodel?

alexlitvinenko commented 3 years ago

Try this:

CREATE (n:Meet) 
SET n.notes = 'test 3'
SET n.meet_datetime = datetime().epochSeconds
return n

This is how to turn obscure float into pretty datetime string: match (n:Meet) where exists(n.meet_datetime) return apoc.date.format(n.meet_datetime, 's', 'yyyy/MM/dd HH:mm:ss')

apoc.date.format

YuriyKortev commented 3 years ago

@alexlitvinenko it works, thank you!