Skip to content

TensorflowGNN transformer #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

post2web
Copy link

@post2web post2web commented May 19, 2025

Description

Contribution for issue #350

Pull request type

Please delete options that are not relevant.

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring with functional or API changes
  • Refactoring without functional or API changes
  • Build or packaging related changes
  • Documentation content changes
  • Other (please describe):

Related issues

Closes #350

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

######################################

Reviewer checklist (the reviewer checks this part)

  • Core feature implementation
  • Tests
  • Code documentation
  • Documentation on gqlalchemy/docs

######################################

@CLAassistant
Copy link

CLAassistant commented May 19, 2025

CLA assistant check
All committers have signed the CLA.

@post2web post2web changed the title CI test TensorflowGNN transformer May 19, 2025
@post2web post2web marked this pull request as ready for review May 19, 2025 03:29
@katarinasupe katarinasupe requested a review from antejavor May 19, 2025 09:27
@katarinasupe katarinasupe added this to the GQLAlchemy 1.8.0 milestone May 27, 2025
Comment on lines +16 to +32
from typing import List, Dict, Any, Set, Tuple
import tensorflow as tf
import tensorflow_gnn as tfgnn
from collections import defaultdict
from gqlalchemy.transformations.constants import DEFAULT_NODE_LABEL, TFGNN_ID
from gqlalchemy.transformations.translators.translator import Translator
import numpy as np

from gqlalchemy.memgraph_constants import (
MG_HOST,
MG_PORT,
MG_USERNAME,
MG_PASSWORD,
MG_ENCRYPTED,
MG_CLIENT_NAME,
MG_LAZY,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the order of imports + add blank lines (1. Standard library imports, 2. Third-party library imports, 3. Local application/library imports; all grouped and alphabetized within each block)

Suggested change
from typing import List, Dict, Any, Set, Tuple
import tensorflow as tf
import tensorflow_gnn as tfgnn
from collections import defaultdict
from gqlalchemy.transformations.constants import DEFAULT_NODE_LABEL, TFGNN_ID
from gqlalchemy.transformations.translators.translator import Translator
import numpy as np
from gqlalchemy.memgraph_constants import (
MG_HOST,
MG_PORT,
MG_USERNAME,
MG_PASSWORD,
MG_ENCRYPTED,
MG_CLIENT_NAME,
MG_LAZY,
)
from collections import defaultdict
from typing import Any, Dict, List, Set, Tuple
import numpy as np
import tensorflow as tf
import tensorflow_gnn as tfgnn
from gqlalchemy.memgraph_constants import (
MG_CLIENT_NAME,
MG_ENCRYPTED,
MG_HOST,
MG_LAZY,
MG_PASSWORD,
MG_PORT,
MG_USERNAME,
)
from gqlalchemy.transformations.constants import DEFAULT_NODE_LABEL, TFGNN_ID
from gqlalchemy.transformations.translators.translator import Translator

"age": tf.ragged.constant([[30], []], dtype=tf.int64)
}

Convertion rules:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Convertion rules:
Conversion rules:

properties_with_missing_values.add(key)
return all_property_names, list_properties, dtypes, properties_with_missing_values

def _convert_properties_to_tensors(self, properties_list: List[Dict[str, Any]]) -> Dict[str, tf.Tensor]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens with temporal, Enum or Point types from Memgraph?

Comment on lines +290 to +298
"""Produce cypher queries for data saved as part of the TFGNN graph. If the graph is homogeneous, a default TFGNN's labels will be used.
_N as a node label and _E as edge label. The method converts 1D as well as multidimensional features. If there are some isolated nodes inside TFGNN graph, they won't get transferred. Nodes and edges
created in Memgraph DB will, for the consistency reasons, have property `dgl_id` set to the id they have as part of the TFGNN graph. Note that this method doesn't insert anything inside the database,
it just creates cypher queries. To insert queries the following code can be used:
>>> memgraph = Memgraph()
graph_tensor = TFGNNTranslator(...)
for query in TFGNNTranslator().to_cypher_queries(graph_tensor):
memgraph.execute(query)
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Produce cypher queries for data saved as part of the TFGNN graph. If the graph is homogeneous, a default TFGNN's labels will be used.
_N as a node label and _E as edge label. The method converts 1D as well as multidimensional features. If there are some isolated nodes inside TFGNN graph, they won't get transferred. Nodes and edges
created in Memgraph DB will, for the consistency reasons, have property `dgl_id` set to the id they have as part of the TFGNN graph. Note that this method doesn't insert anything inside the database,
it just creates cypher queries. To insert queries the following code can be used:
>>> memgraph = Memgraph()
graph_tensor = TFGNNTranslator(...)
for query in TFGNNTranslator().to_cypher_queries(graph_tensor):
memgraph.execute(query)
"""
"""Produce Cypher queries for data saved as part of the TFGNN graph. If the graph is homogeneous, a default TFGNN's labels will be used (_N as a node label and _E as edge label). The method converts 1D as well as multidimensional features. If there are some isolated nodes inside TFGNN graph, they won't get transferred. Nodes and edges
created in Memgraph DB will, for the consistency reasons, have property `tfgnn_id` set to the id they have as part of the TFGNN graph. Note that this method doesn't insert anything inside the database,
it just creates Cypher queries. To insert queries the following code can be used:
memgraph = Memgraph()
graph_tensor = TFGNNTranslator(...)
for query in TFGNNTranslator().to_cypher_queries(graph_tensor):
memgraph.execute(query)
"""

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • cypher -> Cypher
  • put default node and edge labels in ()
  • dgl_id -> tfgnn_id
  • removed >>> in code example to avoid incorrect indentation


def to_cypher_index_queries(self, graph_tensor: tfgnn.GraphTensor) -> List[str]:
"""
Creates cypher index queries for the graph.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Creates cypher index queries for the graph.
Creates Cypher index queries for the graph.

Comment on lines +26 to +29
def test_export_homoginious_graph(memgraph: Memgraph):
"""
Test exporting homoginious graph (nodes without labels)
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

homogeneous graph (not homoginious). Fix in test name and docstring

Comment on lines +43 to +46
def test_export_heteroghinious_graph(memgraph: Memgraph):
"""
Test exporting heteroghinious graph (nodes with one label)
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heterogeneous graph (not heteroghinious). Fix in test name and docstring

Comment on lines +57 to +60
def test_export_heteroghinious_multi_label_graph(memgraph: Memgraph):
"""
Test exporting heteroghinious graph and nodes with more than one label
GraphTensor will create a node for every label and edge type for each combination of source / target labels
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heterogeneous graph (not heteroghinious). Fix in test name and docstring

@katarinasupe
Copy link
Contributor

katarinasupe commented Jun 2, 2025

Hi @post2web, I left some comments, if you can take a look.
Also, I added changes made with black formatter locally (poetry run black .), so I recommend you do that before the next commit 🙏
My colleague @antejavor will also take a look at the PR and leave some comments if needed.

Also, it would be great if you could contribute to the translators documentation, which refers to import and export guides.

Copy link
Contributor

@antejavor antejavor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just two small comments, the rest looks good IMO.

EDIT: I have deleted my comments, leaving to @katarinasupe to approve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create TensorflowGNN translator
4 participants