# Connections Everything here is importable from `agensgraph`. The awaiting class has the same methods as the blocking one, with those that wait for the server written `async def`; they are listed once, on `Connection`. ## Connecting ```{py:currentmodule} agensgraph ``` ```{py:function} connect(conninfo: str = '', **kwargs: object) -> Connection[object] Open a blocking connection. `conninfo` is a libpq connection string or URL, and `kwargs` are libpq settings or psycopg's own connection options, such as `autocommit=True`. The server's version is checked before this returns; one older than `MINIMUM_VERSION` raises `agensgraph.errors.CapabilityError`. TCP keepalive settings are filled in where not given. The same as `Connection.connect()`. See [Connecting](../../guide/connecting.md). ``` ```{py:data} MINIMUM_VERSION :value: (2, 17) The oldest AgensGraph line the driver reads, as `(major, minor)`. ``` ## Connection ````{py:class} Connection A psycopg 3 `Connection` that reads and writes graph values. Everything psycopg documents for a connection applies; the methods below are what the driver adds or changes. ```{py:method} connect(conninfo: str = '', **kwargs: Any) -> Connection[Any] :classmethod: Open a connection; `agensgraph.connect()` is this. ``` ```{py:method} graph(name: str) Select the graph Cypher resolves label names in (`SET graph_path`, with the name quoted), and read its labels into the label table. Part of the current transaction: commit it. See [Selecting a graph](../../guide/connecting.md#selecting-a-graph). ``` ```{py:method} refresh_labels() Read the labels of the graph the session is on into the label table again, after creating a label, for reads in the composite rendering. Does nothing when no graph is selected. ``` ```{py:property} label_table :type: LabelCache The labels of the selected graph, by id, as the composite rendering needs them. ``` ```{py:property} capabilities :type: Capabilities A `Capabilities` for this server, built from the version it reported. ``` ```{py:method} execute_query(query: Statement, params: Params | None = None, *, binary_: bool = False, counts_: bool = False, prepare_: bool | None = None, row_: RowFactory[Any] | None = None) -> Result Run one statement and read its whole result. `params` is a sequence for `%s` or a mapping for `%(name)s`. `binary_` asks for the composite rendering, `counts_` reads what the statement wrote, `prepare_` overrides when psycopg prepares it, and `row_` is a psycopg row factory. See [Running statements](../../guide/running-statements.md). ``` ```{py:method} stream(query: str, params: Params | None = None, *, size: int = 100, binary_: bool = False, name: str | None = None) -> Iterator[Any] Read a result a chunk of `size` rows at a time through a server-side cursor. Needs an open transaction, and refuses a statement that writes. A generator: its checks run when iteration starts. See [Streaming](../../guide/running-statements.md#streaming-a-large-result). ``` ```{py:method} pipeline_query(statements: Sequence[tuple[str, Params | None]] | Sequence[str], *, chunk: int = 100) -> list[Result] Run read statements in pipelines of `chunk`, returning a `Result` for each, in order. A failing chunk is run again statement by statement, so the error is the culprit's. ``` ```{py:method} pipeline_batch(statements: Sequence[tuple[str, Params | None]] | Sequence[str]) Send write statements in one pipeline and read nothing back. If any fails, none is applied, and `BatchFailed` is raised. ``` ```{py:method} transaction(savepoint_name: str | None = None, force_rollback: bool = False) -> Generator[psycopg.Transaction] psycopg's transaction block; a block inside another is a savepoint. ``` ```{py:method} read_only_transaction(*, allow_server_programs: bool = False) -> Generator[None] A transaction block the server will not let write, rolled back at the end. Refuses to begin for a role that can run programs on the server's host, unless `allow_server_programs`. See [Untrusted statements](../../production/untrusted-statements.md). ``` ```{py:method} can_run_server_programs() -> bool Whether this role is a superuser or a member of `pg_execute_server_program`. Asked once, then kept. ``` ```{py:method} deadline(budget: Deadline | float | None, *, gap: float = 0.5) -> Generator[Deadline] Bound the statements in a block by a budget, sent as `statement_timeout`, and put it back afterwards. Yields the `Deadline`. See [Deadlines](../../production/timeouts.md#deadlines). ``` ```{py:method} transaction_id(*, assign: bool = False) -> int | None The open transaction's id; with `assign=True`, give it one now. `None` before it has one. ``` ```{py:method} resolve_commit(transaction_id: int) -> CommitOutcome What became of a transaction, by its id: a `CommitOutcome`. Ask on a different connection. ``` ```{py:method} commit() psycopg's, keeping the label table in step with the session's graph. ``` ```{py:method} rollback() psycopg's, keeping the label table in step with the session's graph. ``` ```{py:method} pipeline() -> Generator[psycopg.Pipeline] psycopg's pipeline block. ``` ```{py:method} load_vertices(label: str, properties: Iterable[Mapping[str, Any]], *, graph: str | None = None) -> int Copy one vertex per property map into `label`; returns how many. See [Bulk loading](../../data/bulk-loading.md). ``` ```{py:method} load_edges(label: str, edges: Iterable[tuple[GraphId, GraphId, Mapping[str, Any] | None]], *, graph: str | None = None) -> int Copy one edge per `(start, end, properties)` into `label`; returns how many. ``` ```{py:method} load_vertex_frame(label: str, source: Any, *, graph: str | None = None, size: int = 8192) -> int Copy a frame's rows into `label`, each column a property. Needs the `arrow` extra. ``` ```{py:method} load_edge_frame(label: str, source: Any, *, start: str = 'start', end: str = 'end', graph: str | None = None, size: int = 8192) -> int Copy a frame's rows into `label` as edges, endpoints from the `start` and `end` columns. ``` ```{py:method} identity_map(label: str, key: str, *, keys: Iterable[Any] | None = None, graph: str | None = None) -> dict[str, GraphId] `{key: GraphId}` for a label, keyed by the text of a property. Refuses a key that does not identify one element. With `keys` and a unique key, looks up only those. ``` ```{py:method} upsert_vertices(label: str, key: str, rows: Iterable[Mapping[str, Any]], *, on_existing: str = 'skip', require_unique: bool = True, graph: str | None = None) -> UpsertCounts Copy the rows whose `key` is not there yet; with `on_existing="update"`, merge the rest into what is there. Needs a uniqueness guarantee on the key unless `require_unique=False`. Returns `UpsertCounts`. ``` ```{py:method} upsert_edges(label: str, edges: Iterable[tuple[GraphId, GraphId, Mapping[str, Any] | None]], *, on_existing: str = 'skip', require_unique: bool = True, graph: str | None = None) -> UpsertCounts Copy the edges whose pair of endpoints is not there yet; with `on_existing="update"`, merge the rest. Needs a unique index on `(start, "end")` unless `require_unique=False`. ``` ```{py:method} graphs() -> list[Graph] Every graph in the database. See [Inspecting a graph](../../schema/inspecting.md). ``` ```{py:method} labels(*, graph: str | None = None) -> list[Label] The graph's labels, built-ins included, as `LabelInfo`. ``` ```{py:method} element_counts(*, graph: str | None = None) -> dict[str, int] How many elements each label holds; a label with none is left out. ``` ```{py:method} declared_properties(label: str | None = None, *, graph: str | None = None) -> list[DeclaredProperty] The properties kept in columns of their own, as `DeclaredProperty`. ``` ```{py:method} can_promote_properties() -> bool Whether this server can keep a property in a column of its own. Asked once, then kept. ``` ```{py:method} indexes(label: str | None = None, *, graph: str | None = None) -> list[Index] The property indexes, as `Index`. A uniqueness constraint is in `constraints()`. ``` ```{py:method} constraints(label: str | None = None, *, graph: str | None = None) -> list[Constraint] The uniqueness and check constraints, as `Constraint`. ``` ```{py:method} vector_indexes(label: str | None = None, *, graph: str | None = None) -> list[VectorIndex] The vector indexes, read in parts, as `VectorIndex`. ``` ```{py:method} describe(*, sample: int = 100, refresh: bool = False, graph: str | None = None) -> GraphDescription Labels, property shapes from a sample of `sample` elements per label, triples and counts, as a `GraphDescription`. `refresh=True` gathers the triple catalog first, which is a write. ``` ```{py:method} meta_is_current(*, graph: str | None = None) -> bool Whether the triple catalog is current for the graph. ``` ```{py:method} ensure_labels(desired: Sequence[DesiredLabel], *, graph: str | None = None, dry_run: bool = False) -> list[str] Create the labels and columns in `desired` that are missing; never drops. Returns the statements run, or with `dry_run` the statements it would run. See [Declaring a schema](../../schema/declaring.md). ``` ```{py:method} ensure_indexes(desired: Sequence[DesiredIndex], *, graph: str | None = None, drop_extra: bool = False, dry_run: bool = False) -> list[str] Create, and with `drop_extra` drop, property indexes to match `desired`. ``` ```{py:method} ensure_constraints(desired: Sequence[Unique | Check], *, graph: str | None = None, drop_extra: bool = False, dry_run: bool = False) -> list[str] Create, and with `drop_extra` drop, constraints to match `desired`. ``` ```{py:method} register_vectors() -> tuple[str, ...] Read and write pgvector's types on this connection. Returns the types found. See [Embedding vectors](../../data/vectors.md). ``` ```{py:method} has_vectors() -> bool Whether pgvector is created in this database. ``` ```{py:method} vector_version() -> tuple[int, ...] | None pgvector's version in this database, or `None`. ``` ```{py:method} vector_search_options(options: Mapping[str, object], *, local: bool = True) Set pgvector's search settings for the transaction, or with `local=False` the session. ``` ```{py:method} listen(*channels: str) Listen on channels. See [LISTEN and NOTIFY](../../data/notifications.md). ``` ```{py:method} unlisten(*channels: str) Stop listening on channels, or on all with none given. ``` ```{py:method} listening() -> list[str] The channels this connection listens on. ``` ```{py:method} notify(channel: str, payload: str = '') Send a notification on a channel. ``` ```{py:method} notifications(*, timeout: float | None = None, stop_after: int | None = None) -> Iterator[psycopg.Notify] Yield notifications as they arrive, for up to `timeout` seconds or `stop_after` of them. ``` ```` ````{py:class} AsyncConnection The same as `Connection`, for `asyncio`: its methods that wait for the server are coroutines, and `stream()` and `notifications()` are asynchronous iterators. Open one with `await AsyncConnection.connect(...)`. ```{py:method} connect(conninfo: str = '', **kwargs: Any) -> AsyncConnection[Any] :classmethod: :async: Open a connection, awaited. ``` ```` ## Results ````{py:class} Result(records: list[Any], keys: list[str], counts: GraphWriteCounts, oids: tuple[int, ...] = ()) What `execute_query()` returns. A named tuple, so `len(result)` is 4: iterate over `records`. ```{py:attribute} records :type: list[Any] the rows, a list of tuples (or of what `row_` builds) ``` ```{py:attribute} keys :type: list[str] the column names ``` ```{py:attribute} counts :type: GraphWriteCounts a `GraphWriteCounts`; all `None` unless `counts_=True` ``` ```{py:attribute} oids :type: tuple[int, ...] the PostgreSQL type oid of each column ``` ```` ````{py:class} GraphWriteCounts(inserted_vertices: int | None, inserted_edges: int | None, deleted_vertices: int | None, deleted_edges: int | None, updated_properties: int | None) What a statement wrote. A counter is `None` when it cannot be attributed to the statement. ```{py:attribute} inserted_vertices :type: int | None ``` ```{py:attribute} inserted_edges :type: int | None ``` ```{py:attribute} deleted_vertices :type: int | None ``` ```{py:attribute} deleted_edges :type: int | None ``` ```{py:attribute} updated_properties :type: int | None ``` ```{py:property} complete :type: bool Whether all five are known. ``` ```{py:property} total :type: int | None Their sum, or `None` unless `complete`. ``` ```` ## Server capabilities ````{py:class} Capabilities(reported: str) What one server can do, from the version it reported. Read it as `conn.capabilities`. Each `has_` method returns a `bool`, or with `check=True` raises `CapabilityError` naming the version needed. ```{py:property} reported :type: str The version string the server sent, such as `2.18.6.0`. ``` ```{py:property} version :type: tuple[int, int] Its first two numbers, `(2, 18)`. ``` ```{py:method} has_property_promotion(*, check: bool = False) -> bool A property kept in a column of its own (2.18). ``` ```{py:method} has_gql_clauses(*, check: bool = False) -> bool The GQL clauses, such as `LET`, `NEXT`, `FILTER`, `FINISH`, `FOR` and `CALL` (2.18). ``` ```{py:method} has_element_ordering(*, check: bool = False) -> bool `ORDER BY` on a vertex or an edge (2.18). ``` ```{py:method} has_endpoint_elision(*, check: bool = False) -> bool The planner skipping endpoint reads (2.18). ``` ```{py:method} of(conn: _Reports) -> Capabilities :classmethod: The capabilities of a connection. ``` ````