You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
distinct() (query results are always unique from this version)
❌ Usage Change: Previous behavior / usage (usually a parameter type, return type, or internal behavior) is replaced completely by the new one; see note to avoid surprises. (May have been deprecated in previous versions or not)
query.set() → query.set_val()
Returned value of query.order_by(): A new query with sorted nodes → A sorted list of nodes
Return type of engine.get_nodes_of_type(): list[Node] → set[Node]
Return type of engine.get_relations_from(): list[Relation] → set[Relation]
Return type of engine.get_relations_to(): list[Relation] → set[Relation]
Return type of query.get(): list[Node] → set[Node]
Return type of query.relations(): list[Relation] → set[Relation]
Return type of query.ids(): list[str] → set[str]
Return type of query.group_by(): dict[Any, list[Node]] → dict[Any, set[Node]]
query.min() will raise TypeError when all values are non‑numeric in the given field instead of returning 0.0
query.max() will raise TypeError when all values are non‑numeric in the given field instead of returning 0.0
query.avg() will raise TypeError when all values are non‑numeric in the given field instead of returning 0.0
Using the internal query.edges attribute returns a set of relation object IDs instead of a list of relation objects (use query.relations() instead)
Unused types.Field.default removed
auto_distinct from query.union() removed
None instead of NotFoundError for invalid query start points
Relation System Refactor
The indexing system for relations was refactored in the database and in queries, resulting in extreme speed‑ups in:
Queries with relation changes like exclude(), intersect() (6‑10× faster)
Methods with relation search and indexing like remove_node() and remove_relation() (6× faster)
Save / Load database (2× faster)
Improvements for all data mutations
As well as some usage changes:
❌ Usage Change (3): Return type of get_nodes_of_type(), get_relations_from(), get_relations_to() changed to set
❌ Usage Change (4): Return type of get(), relations(), and ids() queries changed to set, and group_by() to dict[Any, set[Node]]
❌ Usage Change: Using the internal edges query attribute returns a set of relation object IDs instead of a list of relation objects, so users must use the standard relations() from this version
Atomic Queries and validate()
To keep Graphite atomic, query logic was improved to be completely atomic (with a fail‑fast strategy) and a new validate() query was added to keep results valid based on engine content.
Benchmark Suite
In tests, a new benchmark.py is available to track speed of engine actions. With this new section we improved performance in many areas and can now provide more detailed performance reports:
See result of last benchmark (click to expand)
GRAPHITE BENCHMARK REPORT
Size factor: 5000, Runs: 10
1 Engine Memory Overhead (information)
Size
Bytes
Bytes per Node
memory_overhead(n: 5000, r: 2500)
6.2 MB
6534968 B
1306.9936 B
Metric (information)
Avg
Min
Max
StDev
Parse DSL (378 lines)
3.040 ms
2.785 ms
4.078 ms
0.381 ms
Get node (n: 5000)
0.006 ms
0.003 ms
0.013 ms
0.003 ms
Get all nodes with type (n: 5000, with subtypes)
0.007 ms
0.005 ms
0.010 ms
0.002 ms
Create node (n: 5000)
77.356 ms
69.867 ms
97.034 ms
9.496 ms
Query: avg (n: 100)
0.074 ms
0.070 ms
0.082 ms
0.003 ms
Query: count (n: 100)
0.003 ms
0.002 ms
0.005 ms
0.001 ms
Query: exclude (n: 100 + 1000)
0.059 ms
0.051 ms
0.110 ms
0.018 ms
Query: get_relations_from (n: 5000)
0.006 ms
0.004 ms
0.009 ms
0.001 ms
Query: get_relations_to (n: 5000)
0.006 ms
0.004 ms
0.009 ms
0.001 ms
Query: group_by (n: 100)
0.055 ms
0.052 ms
0.060 ms
0.003 ms
Query: intersect (n: 100 + 1000)
0.145 ms
0.123 ms
0.237 ms
0.036 ms
Query: max (n: 100)
0.087 ms
0.083 ms
0.095 ms
0.004 ms
Query: min (n: 100)
0.086 ms
0.083 ms
0.091 ms
0.002 ms
Query: order_by (n: 100)
0.065 ms
0.061 ms
0.069 ms
0.003 ms
Query: outgoing (n: 5000, typed)
4.386 ms
4.003 ms
6.281 ms
0.693 ms
Query: remove (n: 100)
0.548 ms
0.525 ms
0.680 ms
0.047 ms
Query: set_val (n: 100)
0.064 ms
0.058 ms
0.078 ms
0.006 ms
Query: sum (n: 100)
0.055 ms
0.052 ms
0.058 ms
0.002 ms
Query: union (n: 100 + 1000)
0.148 ms
0.138 ms
0.169 ms
0.012 ms
Query: where (n: 5000, lambda)
2.138 ms
2.032 ms
2.649 ms
0.194 ms
Query: where (n: 5000, string)
6.853 ms
6.549 ms
7.151 ms
0.227 ms
Create Relation (r: 5000)
17.085 ms
16.470 ms
18.651 ms
0.667 ms
Define Node Type (nt: 500)
3.177 ms
2.587 ms
5.032 ms
0.722 ms
Define Relation Type (rt: 250)
0.992 ms
0.908 ms
1.381 ms
0.148 ms
Load (n: 5000, r: 2500, unsafe mode)
41.596 ms
40.762 ms
42.589 ms
0.603 ms
Load (n: 5000, r: 2500, validate off)
41.788 ms
40.400 ms
43.174 ms
1.015 ms
Load (n: 5000, r: 2500, validate on)
45.216 ms
42.830 ms
47.927 ms
1.574 ms
Save(n: 5000, r: 2500)
251.755 ms
240.355 ms
264.306 ms
7.411 ms
Updated Remove Nodes / Relations Methods
Allow multiple removals in a single call for remove_nodes() and remove_relations()
⚠️ Deprecation (2): Old functions deprecated (remove_node() → remove_nodes() and remove_relation() → remove_relations())
Hash Support for Nodes and Relations
With string‑ID‑based hash for nodes and object‑ID‑based hash for relations, you can finally use them as dict keys, in sets, and in equality checks.
Review of Sorting and Uniqueness in Queries
With a review of sorting solutions on queries and structural changes to the node / relation indexing system in the engine (including queries):
Sort support added for limit(), paginate(), and first(): query result nodes / relations are sets from this version, so sorting them with order_by() can’t help. We combined the .order_by(<field>, <descending>).limit(<count>) chain into .limit(<count>, <field>, <descending>) as a solution (and similarly for paginate() and first()). These queries are therefore sort‑and‑slice actions and their results have no intrinsic order. Sorting is optional; by default node IDs are used.
❌ Usage Change:order_by() returns a sorted list of nodes instead of a query with sorted results (impossible for sets)
⚠️ Deprecation:distinct() deprecated because query results are always unique from this version
❌ Usage Change:auto_distinct from query.union() removed because the result is always unique
Renamed set() Query to set_val()
❌ Usage Change: We noticed a minor name conflict between the set() query, Python’s set class, and the node/relation set() method. This isn’t a blocking issue, but for improved readability the set() query has been renamed to set_val().
Behavior Fix for min(), max(), and avg() Queries
❌ Usage Change (3):min(), max(), and avg() queries will raise TypeError when all values in the given field are non‑numeric, instead of returning 0.0.
Fix Confusing Parse Fallback
The parser converts the given value to a string instead of always 'None' for incorrectly parsed string values. This was a typo.
Fixed Parser Unexpected Behavior When Using node and relation in Definitions
In 0.3 the parser replaced all occurrences of node and relation in node ... or relation ... lines, leading to unexpected behavior when node or relation appeared in type names. This issue was fixed by removing only the leading identifier keyword.
Save File Improvements
Previously, indexes were added to the saved database while at loading these indexes were rebuilt from scratch. By removing this data and with other optimizations, serialization is now faster and the resulting file is smaller.
Other
❌ Usage Change: Unused default removed from types.Field (the field object for node and relation types). This wasn’t used anywhere, so you will not see any change unless you create fields with the low‑level API (not recommended).
❌ Usage Change: Invalid query start points (like engine.query.UndefinedNodeType) now return None instead of raising NotFoundError.
Installation
This version is available on https://pypi.org and you can install it into your device or virtual environment with the pip command:
pip install graphitedb --upgrade
To install exactly this version:
pip install graphitedb==0.4
Then you can use it in Python:
import graphite
Please see examples/ in the GitHub repository and the documentation for usage examples and guides.
Graphite is open source and free, so feel free to use it, customize it, and share problems, ideas, and comments with us in Issues and Discussions!
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Graphite
v0.4Note
This is a
0.xrelease, therefore it is considered not ready for production use.This is a major design change with high value!
Changes since
0.3:Tip
This is a new section: Overview of important changes for previous users.
engine.remove_node()→engine.remove_nodes()engine.remove_relation()→engine.remove_relations()distinct()(query results are always unique from this version)query.set()→query.set_val()query.order_by(): A new query with sorted nodes → A sorted list of nodesengine.get_nodes_of_type():list[Node]→set[Node]engine.get_relations_from():list[Relation]→set[Relation]engine.get_relations_to():list[Relation]→set[Relation]query.get():list[Node]→set[Node]query.relations():list[Relation]→set[Relation]query.ids():list[str]→set[str]query.group_by():dict[Any, list[Node]]→dict[Any, set[Node]]query.min()will raiseTypeErrorwhen all values are non‑numeric in the given field instead of returning0.0query.max()will raiseTypeErrorwhen all values are non‑numeric in the given field instead of returning0.0query.avg()will raiseTypeErrorwhen all values are non‑numeric in the given field instead of returning0.0query.edgesattribute returns a set of relation object IDs instead of a list of relation objects (usequery.relations()instead)types.Field.defaultremovedauto_distinctfromquery.union()removedNoneinstead ofNotFoundErrorfor invalid query start pointsRelation System Refactor
The indexing system for relations was refactored in the database and in queries, resulting in extreme speed‑ups in:
exclude(),intersect()(6‑10× faster)remove_node()andremove_relation()(6× faster)As well as some usage changes:
get_nodes_of_type(),get_relations_from(),get_relations_to()changed tosetget(),relations(), andids()queries changed toset, andgroup_by()todict[Any, set[Node]]edgesquery attribute returns a set of relation object IDs instead of a list of relation objects, so users must use the standardrelations()from this versionAtomic Queries and
validate()To keep Graphite atomic, query logic was improved to be completely atomic (with a fail‑fast strategy) and a new
validate()query was added to keep results valid based on engine content.Benchmark Suite
In tests, a new
benchmark.pyis available to track speed of engine actions. With this new section we improved performance in many areas and can now provide more detailed performance reports:See result of last benchmark (click to expand)
Updated Remove Nodes / Relations Methods
remove_nodes()andremove_relations()remove_node()→remove_nodes()andremove_relation()→remove_relations())Hash Support for Nodes and Relations
With string‑ID‑based hash for nodes and object‑ID‑based hash for relations, you can finally use them as
dictkeys, insets, and in equality checks.Review of Sorting and Uniqueness in Queries
With a review of sorting solutions on queries and structural changes to the node / relation indexing system in the engine (including queries):
limit(),paginate(), andfirst(): query result nodes / relations aresets from this version, so sorting them withorder_by()can’t help. We combined the.order_by(<field>, <descending>).limit(<count>)chain into.limit(<count>, <field>, <descending>)as a solution (and similarly forpaginate()andfirst()). These queries are therefore sort‑and‑slice actions and their results have no intrinsic order. Sorting is optional; by default node IDs are used.order_by()returns a sorted list of nodes instead of a query with sorted results (impossible forsets)distinct()deprecated because query results are always unique from this versionauto_distinctfromquery.union()removed because the result is always uniqueRenamed
set()Query toset_val()❌ Usage Change: We noticed a minor name conflict between the
set()query, Python’ssetclass, and the node/relationset()method. This isn’t a blocking issue, but for improved readability theset()query has been renamed toset_val().Behavior Fix for
min(),max(), andavg()Queries❌ Usage Change (3):
min(),max(), andavg()queries will raiseTypeErrorwhen all values in the given field are non‑numeric, instead of returning0.0.Fix Confusing Parse Fallback
The parser converts the given value to a string instead of always
'None'for incorrectly parsed string values. This was a typo.Fixed Parser Unexpected Behavior When Using
nodeandrelationin DefinitionsIn
0.3the parser replaced all occurrences ofnodeandrelationinnode ...orrelation ...lines, leading to unexpected behavior whennodeorrelationappeared in type names. This issue was fixed by removing only the leading identifier keyword.Save File Improvements
Previously, indexes were added to the saved database while at loading these indexes were rebuilt from scratch. By removing this data and with other optimizations, serialization is now faster and the resulting file is smaller.
Other
defaultremoved fromtypes.Field(the field object for node and relation types). This wasn’t used anywhere, so you will not see any change unless you create fields with the low‑level API (not recommended).engine.query.UndefinedNodeType) now returnNoneinstead of raisingNotFoundError.Installation
This version is available on https://pypi.org and you can install it into your device or virtual environment with the
pipcommand:To install exactly this version:
Then you can use it in Python:
Please see
examples/in the GitHub repository and the documentation for usage examples and guides.Graphite is open source and free, so feel free to use it, customize it, and share problems, ideas, and comments with us in Issues and Discussions!
This discussion was created from the release 0.4.
Beta Was this translation helpful? Give feedback.
All reactions