Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## v1.9.0 - June 23, 2026

### Features and improvements


* Fix release process (#387)
* feat: Build for Python 3.14 (#383)
* feat: Migrate to uv (#382)
* Add DOT import (#377)
* Add TensorflowGNN transformer (#353)
* Support Transport of ZonedDateTimes (#370)
* Added missing dependency for publish docs workflow (#368)


## v1.8.0 - June 12, 2025

### Features and improvements
Expand Down
9 changes: 9 additions & 0 deletions docs/reference/gqlalchemy/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ Converts the GraphObject class into the appropriate subclass.
This is used when deserialising a json representation of the class,
or the object returned from the GraphDatabase.

#### model\_validate

```python
@classmethod
def model_validate(cls, obj, *args, **kwargs)
```

Used to convert a dictionary object into the appropriate GraphObject.

#### parse\_obj

```python
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ Load data from a CSV file by executing a Cypher query for each row.

**Arguments**:

- `path` - A string representing the path to the CSV file. If beginning with `http://`, `https://`, or `ftp://`, the CSV file will be fetched over the network.
- `path` - A string representing the path to the CSV file. If beginning with
"http://", "https://" or "ftp://", the CSV file will be fetched over the network.
- `header` - A bool indicating if the CSV file starts with a header row.
- `row` - A string representing the name of the variable for iterating
over each row.
Expand All @@ -34,13 +35,27 @@ Load data from a CSV file by executing a Cypher query for each row.

Load CSV with header:

- `Python` - `load_csv(path="path/to/my/file.csv", header=True, row="row").return_().execute()`
- `Cypher` - `LOAD CSV FROM "path/to/my/file.csv" WITH HEADER AS row RETURN *;`
- Python:
```python
load_csv(path="path/to/my/file.csv", header=True, row="row").return_().execute()
```

- Cypher:
```cypher
LOAD CSV FROM "path/to/my/file.csv" WITH HEADER AS row RETURN *;
```

Load CSV without header:

- `Python` - `load_csv(path="path/to/my/file.csv", header=False, row="row").return_().execute()`
- `Cypher` - `LOAD CSV FROM "path/to/my/file.csv" NO HEADER AS row RETURN *;`
- Python:
```python
load_csv(path="path/to/my/file.csv", header=False, row="row").return_().execute()
```

- Cypher:
```cypher
LOAD CSV FROM "path/to/my/file.csv" NO HEADER AS row RETURN *;
```

#### call

Expand All @@ -55,7 +70,7 @@ def call(procedure: str,
subgraph_path: str = None) -> "DeclarativeBase"
```

Override of base class method to support Memgraph subgraph functionality.
Override of base class method to support Memgraph's subgraph functionality.

Method can be called with node labels and relationship types, both being optional, which are used to construct
a subgraph, or if neither is provided, a subgraph query is used, which can be passed as a string representing a
Expand All @@ -64,7 +79,7 @@ Cypher query defining the MATCH clause which selects the nodes and relationships
**Arguments**:

- `procedure` - A string representing the name of the procedure in the
format `query_module.procedure`.
format "query_module.procedure".
- `arguments` - A string representing the arguments of the procedure in
text format.
- `node_labels` - Either a string, which is then used as the label for all nodes, or
Expand All @@ -77,18 +92,34 @@ Cypher query defining the MATCH clause which selects the nodes and relationships

**Returns**:

A `DeclarativeBase` instance for constructing queries.
A DeclarativeBase instance for constructing queries.


**Examples**:

- `Python` - `call('export_util.json', '/home/user', "LABEL", ["TYPE1", "TYPE2"]).execute()`
- `Cypher` - `MATCH p=(a)-[:TYPE1 | :TYPE2]->(b) WHERE (a:LABEL) AND (b:LABEL) WITH project(p) AS graph CALL export_util.json(graph, "/home/user")`
- Python:
```python
call('export_util.json', '/home/user', "LABEL", ["TYPE1", "TYPE2"]).execute()
```

- Cypher:
```cypher
MATCH p=(a)-[:TYPE1 | :TYPE2]->(b) WHERE (a:LABEL) AND (b:LABEL)
WITH project(p) AS graph CALL export_util.json(graph, '/home/user')
```

or

- `Python` - `call("export_util.json", "/home/user", subgraph_path="(:LABEL)-[:TYPE]->(:LABEL)").execute()`
- `Cypher` - `MATCH p=(:LABEL)-[:TYPE1]->(:LABEL) WITH project(p) AS graph CALL export_util.json(graph, "/home/user")`
- Python:
```python
call('export_util.json', '/home/user', subgraph_path="(:LABEL)-[:TYPE]->(:LABEL)").execute()
```

- Cypher:
```cypher
MATCH p=(:LABEL)-[:TYPE1]->(:LABEL) WITH project(p) AS graph
CALL export_util.json(graph, '/home/user')
```

## ProjectPartialQuery Objects

Expand All @@ -104,6 +135,6 @@ def construct_query() -> str

Constructs a Project partial query.

Given path part of a query (e.g. (:LABEL)-[:TYPE]->(:LABEL2)),
Given path part of a query (e.g. (:LABEL)-[:TYPE]->(:LABEL2)),
adds MATCH, a path identifier and appends the WITH clause.

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ graph = transporter.export()

**Arguments**:

- `graph_type` - dgl, pyg or nx
- `graph_type` - dgl, pyg, nx or tfgnn

#### export

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,29 @@ Gets cypher queries using the underlying translator and then inserts all queries

**Arguments**:

- `graph` - dgl, pytorch geometric or nx graph instance.
- `graph` - dgl, pytorch geometric, dot or nx graph instance.

#### translate_dot_file
#### translate\_dot\_file

```python
def translate_dot_file(path: str) -> None
```

Parses a DOT file into a NetworkX graph and imports it to Memgraph. This method is available when `graph_type="NX"`.
Parses a DOT file to a NetworkX graph and imports it to Memgraph. This method is available when ```graph_type="NX"```

**Arguments**:

- `path` - Path to a DOT file.
- ``path`` - Path to a DOT file.

#### translate_dot_data
#### translate\_dot\_data

```python
def translate_dot_data(dot_data: str) -> None
```

Parses DOT content from a string into a NetworkX graph and imports it to Memgraph. This method is available when `graph_type="NX"`.
Parses DOT content to a NetworkX graph and imports it to Memgraph. This method is available when ```graph_type="NX"```.

**Arguments**:

- `dot_data` - Raw DOT graph content.
- ``dot_data`` - Raw DOT graph content.

38 changes: 30 additions & 8 deletions docs/reference/gqlalchemy/vendors/memgraph.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,6 @@ Terminate transactions in the database.

- `List[MemgraphTerminatedTransaction]` - A list of MemgraphTerminatedTransaction objects with info on their status.


#### get\_storage\_info

```python
Expand All @@ -351,7 +350,15 @@ Get detailed storage information about the database instance.

**Returns**:

- `List[dict]` - A list of dictionaries with 'storage info' and 'value' keys containing storage metrics like name, vertex_count, edge_count, memory_res, disk_usage, etc.
- `List[dict]` - A list of dictionaries with 'storage info' and 'value' keys containing:
- name: Current database name
- vertex_count: Total number of stored nodes
- edge_count: Total number of stored relationships
- average_degree: Average number of relationships per node
- memory_res: Non-swapped physical RAM memory used
- disk_usage: Data directory disk space consumption
- memory_tracked: RAM allocated and tracked by Memgraph
- and other storage-related metrics

#### get\_build\_info

Expand All @@ -363,7 +370,8 @@ Get build information about the Memgraph instance.

**Returns**:

- `List[dict]` - A list of dictionaries with 'build info' and 'value' keys containing build_type (the optimization level).
- `List[dict]` - A list of dictionaries with 'build info' and 'value' keys containing:
- build_type: The optimization level the instance was built with

#### analyze\_graph

Expand All @@ -378,11 +386,19 @@ to select more optimal indexes and MERGE operations.

**Arguments**:

- `labels` _Optional[List[str]]_ - Optional list of labels to analyze. If None, analyzes all labels.
- `labels` - Optional list of labels to analyze. If None, analyzes all labels.


**Returns**:

- `List[dict]` - A list of dictionaries containing analysis results with keys: label, property, num estimation nodes, num groups, avg group size, chi-squared value, avg degree.
- `List[dict]` - A list of dictionaries containing analysis results with keys:
- label: Index's label
- property: Index's property
- num estimation nodes: Nodes used for estimation
- num groups: Distinct property values
- avg group size: Average group size per value
- chi-squared value: Statistical distribution measure
- avg degree: Average degree of indexed nodes

#### delete\_graph\_statistics

Expand All @@ -392,12 +408,18 @@ def delete_graph_statistics(labels: Optional[List[str]] = None) -> List[dict]

Delete graph statistics previously calculated by analyze_graph.

Use this to reset the analysis data if you want to recalculate statistics
after significant changes to the graph structure or data.

**Arguments**:

- `labels` _Optional[List[str]]_ - Optional list of labels to delete statistics for. If None, deletes statistics for all labels.
labels ``_Optional[List[str]]_``: Optional list of labels to delete statistics for.
If None, deletes statistics for all labels.


**Returns**:

- `List[dict]` - A list of dictionaries containing deleted index info with keys: label, property.

- `List[dict]` - A list of dictionaries containing deleted index info with keys:
- label: The deleted index's label
- property: The deleted index's property

3 changes: 3 additions & 0 deletions gqlalchemy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,9 @@ def model_validate(cls, obj, *args, **kwargs):
def parse_obj(cls, obj):
"""Used to convert a dictionary object into the appropriate
GraphObject.

Compatibility note: `parse_obj` is retained for backward compatibility.
For Pydantic v2-style usage, prefer `model_validate`.
"""
return cls.model_validate(obj)

Expand Down
56 changes: 43 additions & 13 deletions gqlalchemy/query_builders/memgraph_query_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def load_csv(self, path: str, header: bool, row: str) -> "DeclarativeBase":
"""Load data from a CSV file by executing a Cypher query for each row.

Args:
path: A string representing the path to the CSV file. If beginning with `http://`, `https://`, or `ftp://`, the CSV file will be fetched over the network.
path: A string representing the path to the CSV file. If beginning with
"http://", "https://" or "ftp://", the CSV file will be fetched over the network.
header: A bool indicating if the CSV file starts with a header row.
row: A string representing the name of the variable for iterating
over each row.
Expand All @@ -69,13 +70,28 @@ def load_csv(self, path: str, header: bool, row: str) -> "DeclarativeBase":
Examples:
Load CSV with header:

Python: `load_csv(path="path/to/my/file.csv", header=True, row="row").return_().execute()`
Cypher: `LOAD CSV FROM 'path/to/my/file.csv' WITH HEADER AS row RETURN *;`
- Python:
```python
load_csv(path="path/to/my/file.csv", header=True, row="row").return_().execute()
```

- Cypher:
```cypher
LOAD CSV FROM "path/to/my/file.csv" WITH HEADER AS row RETURN *;
```

Load CSV without header:

Python: `load_csv(path='path/to/my/file.csv', header=False, row='row').return_().execute()`
Cypher: `LOAD CSV FROM 'path/to/my/file.csv' NO HEADER AS row RETURN *;`
- Python:
```python
load_csv(path="path/to/my/file.csv", header=False, row="row").return_().execute()
```

- Cypher:
```cypher
LOAD CSV FROM "path/to/my/file.csv" NO HEADER AS row RETURN *;
```

"""
self._query.append(LoadCsvPartialQuery(path, header, row))

Expand Down Expand Up @@ -123,7 +139,7 @@ def call(

Args:
procedure: A string representing the name of the procedure in the
format `query_module.procedure`.
format "query_module.procedure".
arguments: A string representing the arguments of the procedure in
text format.
node_labels: Either a string, which is then used as the label for all nodes, or
Expand All @@ -134,18 +150,32 @@ def call(
subgraph_path: Optional way to define the subgraph via a Cypher MATCH clause.

Returns:
A `DeclarativeBase` instance for constructing queries.
A DeclarativeBase instance for constructing queries.

Examples:
Python: `call('export_util.json', '/home/user', "LABEL", ["TYPE1", "TYPE2"]).execute()
Cypher: `MATCH p=(a)-[:TYPE1 | :TYPE2]->(b) WHERE (a:LABEL) AND (b:LABEL)
WITH project(p) AS graph CALL export_util.json(graph, '/home/user')`
- Python:
```python
call('export_util.json', '/home/user', "LABEL", ["TYPE1", "TYPE2"]).execute()
```

- Cypher:
```cypher
MATCH p=(a)-[:TYPE1 | :TYPE2]->(b) WHERE (a:LABEL) AND (b:LABEL)
WITH project(p) AS graph CALL export_util.json(graph, '/home/user')
```

or

Python: `call('export_util.json', '/home/user', subgraph_path="(:LABEL)-[:TYPE]->(:LABEL)").execute()
Cypher: `MATCH p=(:LABEL)-[:TYPE1]->(:LABEL) WITH project(p) AS graph
CALL export_util.json(graph, '/home/user')`
- Python:
```python
call('export_util.json', '/home/user', subgraph_path="(:LABEL)-[:TYPE]->(:LABEL)").execute()
```

- Cypher:
```cypher
MATCH p=(:LABEL)-[:TYPE1]->(:LABEL) WITH project(p) AS graph
CALL export_util.json(graph, '/home/user')
```
"""

if not (node_labels is None and relationship_types is None):
Expand Down
12 changes: 10 additions & 2 deletions gqlalchemy/transformations/importing/graph_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ def translate(self, graph) -> None:
memgraph.execute(query)

def translate_dot_file(self, path: str) -> None:
"""Parses a DOT file to a NetworkX graph and imports it to Memgraph."""
"""Parses a DOT file to a NetworkX graph and imports it to Memgraph. This method is available when ```graph_type="NX"```

Args:
- ``path`` - Path to a DOT file.
"""
self._raise_if_not_nx_importer()
raise_if_not_imported(dependency=pydot, dependency_name="pydot")

Expand All @@ -98,7 +102,11 @@ def translate_dot_file(self, path: str) -> None:
self.translate(graph)

def translate_dot_data(self, dot_data: str) -> None:
"""Parses DOT content to a NetworkX graph and imports it to Memgraph."""
"""Parses DOT content to a NetworkX graph and imports it to Memgraph. This method is available when ```graph_type="NX"```.

Args:
- ``dot_data`` - Raw DOT graph content.
"""
self._raise_if_not_nx_importer()
raise_if_not_imported(dependency=pydot, dependency_name="pydot")

Expand Down
Loading
Loading