.. autoclass:: TypeInfo
- .. automethod:: fetch
- .. automethod:: fetch_async
+ .. method:: fetch(conn, name)
+ :classmethod:
+
+ .. method:: fetch(aconn, name)
+ :classmethod:
+ :async:
+ :noindex:
+
+ Query a system catalog to read information about a type.
+
+ :param conn: the connection to query
+ :type conn: ~psycopg.Connection or ~psycopg.AsyncConnection
+ :param name: the name of the type to query. It can include a schema
+ name.
+ :type name: `!str` or `~psycopg.sql.Identifier`
+ :return: a `!TypeInfo` object (or subclass) populated with the type
+ information, `!None` if not found.
+
+ If the connection is async the function will behave as a coroutine and
+ the caller will need to `await` on it to get the result::
+
+ t = await TypeInfo.fetch(aconn, "mytype")
+
.. automethod:: register
- The *context* can be a `~psycopg.Connection` or `~psycopg.Cursor`.
- Specifying no context will register the `!TypeInfo` globally.
+ :param context: the context where the type is registered, for instance
+ a `~psycopg.Connection` or `~psycopg.Cursor`. `!None` registers
+ the `!TypeInfo` globally.
+ :type context: Optional[~psycopg.abc.AdaptContext]
Registering the `TypeInfo` in a context allows the adapters of that
context to look up type information: for instance it allows to
# Copyright (C) 2020-2021 The Psycopg Team
-from typing import Any, Dict, Iterator, Optional
+from typing import Any, Dict, Iterator, Optional, overload
from typing import Sequence, Type, TypeVar, Union, TYPE_CHECKING
from . import errors as e
f" {self.name} (oid: {self.oid}, array oid: {self.array_oid})>"
)
+ @overload
@classmethod
def fetch(
cls: Type[T], conn: "Connection[Any]", name: Union[str, "Identifier"]
) -> Optional[T]:
- """
- Query a system catalog to read information about a type.
+ ...
+
+ @overload
+ @classmethod
+ async def fetch(
+ cls: Type[T],
+ conn: "AsyncConnection[Any]",
+ name: Union[str, "Identifier"],
+ ) -> Optional[T]:
+ ...
+
+ @classmethod
+ def fetch(
+ cls: Type[T],
+ conn: "Union[Connection[Any], AsyncConnection[Any]]",
+ name: Union[str, "Identifier"],
+ ) -> Any:
+ """Query a system catalog to read information about a type."""
+ from .connection_async import AsyncConnection
+
+ if isinstance(conn, AsyncConnection):
+ return cls._fetch_async(conn, name)
- :param conn: the connection to query
- :param name: the name of the type to query. It can include a schema
- name.
- :type name: `!str` or `~psycopg.sql.Identifier`
- :return: a `!TypeInfo` object populated with the type information,
- `!None` if not found.
- """
from .sql import Composable
if isinstance(name, Composable):
return None
recs = cur.fetchall()
- return cls._fetch(name, recs)
+ return cls._from_records(name, recs)
@classmethod
- async def fetch_async(
+ async def _fetch_async(
cls: Type[T],
conn: "AsyncConnection[Any]",
name: Union[str, "Identifier"],
return None
recs = await cur.fetchall()
- return cls._fetch(name, recs)
+ return cls._from_records(name, recs)
@classmethod
- def _fetch(
- cls: Type[T],
- name: str,
- recs: Sequence[Dict[str, Any]],
+ def _from_records(
+ cls: Type[T], name: str, recs: Sequence[Dict[str, Any]]
) -> Optional[T]:
if len(recs) == 1:
return cls(**recs[0])
assert rows == [('"a"=>"1", "b"=>"2"',)]
- register_hstore(await TypeInfo.fetch_async(aconn, "hstore"), cur)
+ register_hstore(await TypeInfo.fetch(aconn, "hstore"), cur)
async with cur.copy(command) as copy:
copy.set_types(["hstore"])
rows = [row async for row in copy.rows()]
await aconn.execute("select 1")
assert aconn.info.transaction_status == status
- info = await TypeInfo.fetch_async(aconn, name)
+ info = await TypeInfo.fetch(aconn, name)
assert aconn.info.transaction_status == status
assert info.name == "text"
await aconn.execute("select 1")
assert aconn.info.transaction_status == status
- info = await TypeInfo.fetch_async(aconn, name)
+ info = await TypeInfo.fetch(aconn, name)
assert aconn.info.transaction_status == status
assert info is None
@pytest.mark.asyncio
@pytest.mark.parametrize("name, fields", fetch_cases)
async def test_fetch_info_async(aconn, testcomp, name, fields):
- info = await CompositeInfo.fetch_async(aconn, name)
+ info = await CompositeInfo.fetch(aconn, name)
assert info.name == "testcomp"
assert info.oid > 0
assert info.oid != info.array_oid > 0
@pytest.mark.asyncio
@pytest.mark.parametrize("name, subtype", fetch_cases)
async def test_fetch_info_async(aconn, testrange, name, subtype):
- info = await RangeInfo.fetch_async(aconn, name)
+ info = await RangeInfo.fetch(aconn, name)
assert info.name == "testrange"
assert info.oid > 0
assert info.oid != info.array_oid > 0
@pytest.mark.asyncio
async def test_fetch_info_not_found_async(aconn):
- assert await RangeInfo.fetch_async(aconn, "nosuchrange") is None
+ assert await RangeInfo.fetch(aconn, "nosuchrange") is None
def test_dump_custom_empty(conn, testrange):