Skip to content
This repository has been archived by the owner on Feb 15, 2023. It is now read-only.

Commit

Permalink
Handle Neo4j date time part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
sim51 committed Mar 26, 2019
1 parent 56e8b14 commit 2f25614
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
69 changes: 67 additions & 2 deletions neo4jPg/neo4jfdw.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
import re
import json
import datetime
from multicorn import ForeignDataWrapper, Qual, ANY, ALL
from multicorn.utils import log_to_postgres, ERROR, WARNING, DEBUG, INFO
from neo4j import GraphDatabase, basic_auth, CypherError
Expand Down Expand Up @@ -76,7 +77,7 @@ def execute(self, quals, columns, sortkeys=None):

params = {}
for qual in quals:
params[unicode(qual.field_name)] = qual.value
params[unicode(qual.field_name)] = self.convert_to_neo4j(self.columns[qual.field_name], qual.value)

log_to_postgres('Neo4j query is : ' + unicode(statement), DEBUG)
log_to_postgres('With params : ' + unicode(params), DEBUG)
Expand All @@ -88,7 +89,7 @@ def execute(self, quals, columns, sortkeys=None):
line = {}
for column_name in columns:
# TODO: from neo4j type to pg types
line[column_name] = record[column_name]
line[column_name] = self.convert_to_pg(self.columns[column_name], record[column_name])
yield line
except CypherError:
raise RuntimeError("Bad cypher query : " + statement)
Expand Down Expand Up @@ -260,3 +261,67 @@ def compute_table_stat(self):
log_to_postgres('Table stat is :' + unicode(stats), DEBUG)
return stats

def convert_to_pg(self, column, value):
"""
Convert a value to a PG type.
We do nothing for now, but can be usefull for the futur
"""
log_to_postgres('Convert column:' + unicode(column), DEBUG)
return value

def convert_to_neo4j(self, column, value):
"""
Convert the value to the adequate a Neo4j type.
This is used for the quals.
"""
result = value
log_to_postgres('Convert for neo4j column type:' + unicode(column.type_name), DEBUG)

# we want a date
if column.type_name == 'date':
if isinstance(value, datetime.datetime):
result = value.date()
elif isinstance(value, datetime.date):
result = value
else:
log_to_postgres('Value ' + unicode(value) + ' can not be compared with a field of type ' + column.type, DEBUG)

# we want a time
elif column.type_name == 'time':
# remove the timezone !
if isinstance(value, datetime.time):
result = value.replace(tzinfo=None)
elif isinstance(value, datetime.datetime):
result = value.replace(tzinfo=None).time()
else:
log_to_postgres('Value ' + unicode(value) + ' can not be compared with a field of type ' + column.type, DEBUG)

elif column.type_name == 'time with time zone':
# Add the timezone if needed
if isinstance(value, datetime.time):
result = value
elif isinstance(value, datetime.datetime):
result = value.time()
else:
log_to_postgres('Value ' + unicode(value) + ' can not be compared with a field of type ' + column.type, DEBUG)

elif column.type_name == 'timestamp with time zone':
# Add the timezone if needed
if isinstance(value, datetime.datetime):
result = value
elif isinstance(value, datetime.date):
result = value #TODO: change the date to a datetime with default time + default T
else:
log_to_postgres('Value ' + unicode(value) + ' can not be compared with a field of type ' + column.type, DEBUG)

elif column.type_name == 'timestamp':
# Add the timezone if needed
if isinstance(value, datetime.datetime):
result = value
elif isinstance(value, datetime.date):
result = value #TODO: change the date to a datetime with default time + default T
else:
log_to_postgres('Value ' + unicode(value) + ' can not be compared with a field of type ' + column.type, DEBUG)

return result

12 changes: 12 additions & 0 deletions scripts/docker/postgres/initdb.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ CREATE FOREIGN TABLE actedIn (
) SERVER multicorn_neo4j OPTIONS (
cypher 'MATCH (p:Person)-[r:ACTED_IN]->(m:Movie) RETURN id(r) AS id, id(p) AS person_id, id(m) AS movie_id'
);

CREATE FOREIGN TABLE temporal (
my_date DATE,
my_localtime TIME,
my_time TIME WITH TIME ZONE,
my_datetime TIMESTAMP WITH TIME ZONE,
my_localdatetime TIMESTAMP,
my_duration INTERVAL
) SERVER multicorn_neo4j OPTIONS (
cypher 'MATCH (n:TemporalNode) RETURN n.date AS my_date, n.time AS my_time, n.localtime AS my_localtime, n.datetime AS my_datetime, n.localdatetime AS my_localdatetime, n.duration AS my_duration'
);

CREATE EXTENSION plpythonu;
CREATE OR REPLACE FUNCTION cypher(query text) RETURNS SETOF json
LANGUAGE plpythonu
Expand Down

0 comments on commit 2f25614

Please sign in to comment.