The GQLDB Python driver supports a comprehensive set of data types for storing and querying graph data. This guide covers property types, enums, and type conversions.
The PropertyType enum defines all supported data types:
Pythonfrom gqldb.types import PropertyType
| Type | Description | Python Type |
|---|---|---|
INT32 | 32-bit signed integer | int |
UINT32 | 32-bit unsigned integer | int |
INT64 | 64-bit signed integer | int |
UINT64 | 64-bit unsigned integer | int |
FLOAT | 32-bit floating point | float |
DOUBLE | 64-bit floating point | float |
DECIMAL | Arbitrary precision decimal | GqldbDecimal |
| Type | Description | Python Type |
|---|---|---|
STRING | Variable-length string | str |
TEXT | Long text | str |
| Type | Description | Python Type |
|---|---|---|
BOOL | Boolean value | bool |
NULL | Null value | None |
UNSET | Unset/unknown type | None |
| Type | Description | Python Type |
|---|---|---|
BLOB | Binary data | bytes |
| Type | Description | Python Type |
|---|---|---|
TIMESTAMP | Unix timestamp with nanoseconds | datetime |
DATETIME | Date and time (deprecated) | datetime |
DATE | Date only | date |
LOCAL_DATETIME | Local date and time | GqldbLocalDateTime |
ZONED_DATETIME | Date and time with timezone | GqldbZonedDateTime |
LOCAL_TIME | Local time of day | GqldbLocalTime |
ZONED_TIME | Time with timezone | GqldbZonedTime |
| Type | Description | Python Type |
|---|---|---|
YEAR_TO_MONTH | Year-month duration | YearToMonth |
DAY_TO_SECOND | Day-second duration | DayToSecond |
| Type | Description | Python Type |
|---|---|---|
POINT | 2D geographic point | Point |
POINT3D | 3D point | Point3D |
| Type | Description | Python Type |
|---|---|---|
LIST | Ordered list | list |
SET | Unordered unique set | set |
MAP | Key-value map | dict |
VECTOR | Numeric vector | Vector |
| Type | Description | Python Type |
|---|---|---|
NODE | Graph node | GqldbNode |
EDGE | Graph edge | GqldbEdge |
PATH | Graph path | GqldbPath |
Pythonfrom gqldb.types import PropertyType class PropertyType(IntEnum): UNSET = 0 INT32 = 1 UINT32 = 2 INT64 = 3 UINT64 = 4 FLOAT = 5 DOUBLE = 6 STRING = 7 DATETIME = 8 # Deprecated, use TIMESTAMP TIMESTAMP = 9 TEXT = 10 BLOB = 11 POINT = 12 DECIMAL = 13 LIST = 14 SET = 15 MAP = 16 NULL = 17 BOOL = 18 LOCAL_DATETIME = 19 ZONED_DATETIME = 20 DATE = 21 ZONED_TIME = 22 LOCAL_TIME = 23 YEAR_TO_MONTH = 24 DAY_TO_SECOND = 25 RECORD = 26 POINT3D = 27 VECTOR = 28 TABLE = 29 PATH = 30 ERROR = 31 NODE = 32 EDGE = 33
Pythonfrom gqldb.types import GraphType class GraphType(IntEnum): OPEN = 0 # Schema-less graph CLOSED = 1 # Schema-enforced graph ONTOLOGY = 2 # Ontology-enabled graph
Pythonfrom gqldb.types import HealthStatus class HealthStatus(IntEnum): UNKNOWN = 0 SERVING = 1 NOT_SERVING = 2 SERVICE_UNKNOWN = 3
Pythonfrom gqldb.types import CacheType class CacheType(IntEnum): ALL = 0 AST = 1 PLAN = 2
Controls the GQL keyword emitted by insert_nodes(nodes, …) / insert_edges(edges, …):
Pythonfrom gqldb import InsertType class InsertType(IntEnum): NORMAL = 0 # INSERT — errors on duplicate _id OVERWRITE = 1 # INSERT OVERWRITE — replaces entity wholesale on duplicate _id UPSERT = 2 # UPSERT — merges new properties into existing entity on duplicate _id
OVERWRITE drops properties not present in the write. UPSERT preserves them and only overwrites the ones present in the write. They are not interchangeable.
Per-call configuration for the GQL-path insert convenience methods. Extends QueryConfig:
Pythonfrom gqldb import InsertConfig, InsertType @dataclass class InsertConfig(QueryConfig): insert_type: InsertType = InsertType.NORMAL # NORMAL / OVERWRITE / UPSERT # inherits from QueryConfig: # graph_name: str = "" # parameters: Dict[str, Any] = {} # transaction_id: int = 0 # timeout: int = 0 # read_only: bool = False # max_path_results: int = 0
Pythonfrom gqldb import NodeData, Node from gqldb.types import GqldbNode # Data for inserting nodes (input to insert_nodes) @dataclass class NodeData: id: str = "" # optional custom _id (auto-generated when empty) labels: List[str] = field(default_factory=list) properties: Dict[str, Any] = field(default_factory=dict) # Node from query results (returned by Response.as_nodes() / row.as_node()) @dataclass class Node: id: str = "" # user-facing identifier uuid: str = "" # system numeric handle (uint64 as decimal string); # empty when talking to pre-6.1.147 servers labels: List[str] = field(default_factory=list) properties: Dict[str, Any] = field(default_factory=dict) def to_dict(self) -> dict: ... # Internal/wire-level node representation @dataclass class GqldbNode: id: str = "" uuid: str = "" labels: List[str] = field(default_factory=list) properties: Dict[str, Any] = field(default_factory=dict)
Pythonfrom gqldb import EdgeData, Edge from gqldb.types import GqldbEdge # Data for inserting edges (input to insert_edges) @dataclass class EdgeData: id: str = "" # optional custom _id (requires WITH EDGE_ID graph) label: str = "" from_node_id: str = "" to_node_id: str = "" properties: Dict[str, Any] = field(default_factory=dict) # Edge from query results @dataclass class Edge: id: str = "" # user-facing identifier uuid: str = "" # system numeric handle; empty pre-6.1.147 label: str = "" from_node_id: str = "" to_node_id: str = "" properties: Dict[str, Any] = field(default_factory=dict) def to_dict(self) -> dict: ... # Internal/wire-level edge representation @dataclass class GqldbEdge: id: str = "" uuid: str = "" label: str = "" from_node_id: str = "" to_node_id: str = "" properties: Dict[str, Any] = field(default_factory=dict)
Pythonfrom gqldb.types import GqldbPath @dataclass class GqldbPath: nodes: List[GqldbNode] edges: List[GqldbEdge]
Pythonfrom gqldb.types import Point, Point3D @dataclass class Point: latitude: float longitude: float @property def x(self) -> float: ... # alias for longitude @property def y(self) -> float: ... # alias for latitude @dataclass class Point3D: x: float y: float z: float @property def longitude(self) -> float: ... # alias for x @property def latitude(self) -> float: ... # alias for y @property def height(self) -> float: ... # alias for z
The Point server validates WGS-84 bounds (longitude ∈ [-180, 180], latitude ∈ [-90, 90]). Point3D is Cartesian — the server does not enforce geographic bounds on Point3D, even when accessed through the lon/lat aliases.
Pythonfrom gqldb.types import YearToMonth, DayToSecond @dataclass class YearToMonth: months: int @dataclass class DayToSecond: seconds: int nanoseconds: int
Pythonfrom gqldb.types import Vector @dataclass class Vector: values: List[float] = field(default_factory=list) def __len__(self) -> int: ... # vector dimension def __iter__(self): ... # iterate over float components
len(vector) returns the dimension; iteration yields the float components in order. These mirror the server-side size(VECTOR) / ai.vector_dim(VECTOR) functions, so you don't have to round-trip a GQL query just to read a vector's dimension.
The driver uses TypedValue internally for type-safe data transfer:
Pythonfrom gqldb.types import TypedValue, PropertyType # Get typed values from a row row = response.first() if row: for tv in row.values: print(f"Type: {tv.type}, Value: {tv.to_python()}")
For explicit type specification:
Pythonfrom gqldb.types import Int32, UInt32, Float32, UInt64 # Wrap values with explicit types node = NodeData( labels=["Test"], properties={ "int32_val": Int32(42), "uint32_val": UInt32(100), "float32_val": Float32(3.14), "uint64_val": UInt64(9999999999) } )
Pythonfrom datetime import date, datetime # Insert with date client.gql(""" INSERT (e:Event { _id: 'e1', name: 'Conference', date: DATE('2024-06-15'), startTime: DATETIME('2024-06-15T09:00:00Z') }) """) # Query and convert response = client.gql("MATCH (e:Event) RETURN e.date, e.startTime") row = response.first() if row: event_date = row.get(0) start_time = row.get(1) print(f"Event date: {event_date}") print(f"Start time: {start_time}")
Python# Insert with location client.gql(""" INSERT (p:Place { _id: 'p1', name: 'Office', location: POINT(37.7749, -122.4194) }) """) # Query and access point response = client.gql("MATCH (p:Place) RETURN p.location") row = response.first() if row: location = row.get(0) if hasattr(location, 'latitude'): print(f"Lat: {location.latitude}, Lng: {location.longitude}")
Python# Insert with list and map client.gql(""" INSERT (u:User { _id: 'u1', name: 'Alice', tags: ['developer', 'blogger'], metadata: {level: 5, premium: true} }) """) # Query collections response = client.gql("MATCH (u:User) RETURN u.tags, u.metadata") row = response.first() if row: tags = row.get(0) # list metadata = row.get(1) # dict print(f"Tags: {tags}") print(f"Metadata: {metadata}")
Pythonfrom gqldb import GqldbClient, GqldbConfig from gqldb.types import PropertyType, NodeData from gqldb.errors import GqldbError def main(): config = GqldbConfig( hosts=["localhost:9000"], timeout=30 ) with GqldbClient(config) as client: client.login("admin", "password") client.create_graph("typeDemo") client.use_graph("typeDemo") # Insert data with various types client.gql(""" INSERT (u:User { _id: 'u1', name: 'Alice', age: 30, balance: 1234.56, active: true, joined: DATE('2023-01-15'), location: POINT(40.7128, -74.0060), tags: ['developer', 'mentor'], settings: {theme: 'dark', notifications: true} }) """) # Query and check types response = client.gql(""" MATCH (u:User {_id: 'u1'}) RETURN u.name, u.age, u.balance, u.active, u.joined, u.location, u.tags, u.settings """) row = response.first() if row: print(f"Name (str): {row.get_string(0)}") print(f"Age (int): {row.get_int(1)}") print(f"Balance (float): {row.get_float(2)}") print(f"Active (bool): {row.get_bool(3)}") print(f"Joined: {row.get(4)}") print(f"Location: {row.get(5)}") print(f"Tags: {row.get(6)}") print(f"Settings: {row.get(7)}") # Check property types print("\nProperty types:") for i, tv in enumerate(row.values): print(f" Column {i}: {tv.type.name}") client.drop_graph("typeDemo") if __name__ == "__main__": main()