chainalysis.data_solutions_table.data_solutions_table - Data Solutions Python SDK 0.7.0 documentation

Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
Toggle table of contents sidebar

# Source code for chainalysis.data_solutions_table.data_solutions_table

    import copy
    from abc import ABC, abstractmethod
    from typing import Union

    from sqlalchemy import (
        ColumnCollection,
        Select,
        Table,
        and_,
        between,
        case,
        distinct,
        except_,
        except_all,
        exists,
        func,
        intersect,
        intersect_all,
        join,
        lateral,
        literal,
        not_,
        or_,
        outerjoin,
        union,
        union_all,
    )

    from chainalysis.exceptions import ValueException
    from chainalysis.sql.analytical import Analytical
    from chainalysis.sql.transactional import Transactional

    __all__ = [
        "Select",
        "and_",
        "or_",
        "not_",
        "case",
        "func",
        "literal",
        "between",
        "exists",
        "distinct",
        "except_",
        "except_all",
        "intersect",
        "intersect_all",
        "join",
        "outerjoin",
        "lateral",
        "union",
        "union_all",
    ]

    class Select(Select, ABC):
        """
        Select is an abstract base class that represents an interface
        for querying a chain-specific table within the Data Solutions system.

        It provides the structure for constructing and executing SQL queries
        using Common Table Expressions. Child classes must implement methods to retrieve
        tables and execute queries, which will return the appropriate result type.
        """

        def __init__(self, api_key: str, chain_table_name: str):
            """
            Initialize the Select object.

            :param api_key: The API key for the Data Solutions API.
            :type api_key: str
            :param chain_table_name: The chain and table name formatted as 'chain.table'.
            :type chain_table_name: str
            :raises ValueException: If the table name is not formatted correctly.
            """
            chain_table_name_split = chain_table_name.split(".")
            if len(chain_table_name_split) != 2:
                raise ValueException(
                    "Table must be formatted as 'chain.table'. Check your input."
                )
            self.api_key = api_key
            self.table = self.get_table(
                chain_table_name_split[0], chain_table_name_split[1]
            )
            super().__init__(self.table)

        @property
        def c(self) -> ColumnCollection:
            """
            Return the columns of the table.

            :return: A collection of column objects associated with the table.
            :rtype: ColumnCollection
            """
            return self.table.c

        def select(self, *columns) -> "Select":
            """
            Select specific columns from the table for querying.

            :param columns: The columns to be selected.
            :type columns: Column
            :return: The Select instance with the selected columns.
            :rtype: Select
            """
            super().__init__(*columns)
            return copy.copy(self)

        def sql(self) -> str:
            """
            Compile the query into a raw SQL string.

            :return: The compiled SQL query as a string.
            :rtype: str
            """
            return self.compile(compile_kwargs={"literal_binds": True}).string

        @abstractmethod
        def get_table(self, chain, table: str) -> Table:
            """
            Return a SQLAlchemy Table object for the given chain and table name.

            :param chain: The chain name.
            :param table: The table name.
            :return: A SQLAlchemy Table object.
            :rtype: Table
            :raises ValueException: If the chain or table does not exist in the database.
            """
            raise NotImplementedError(
                "Get schemas method must be implemented by child classes."
            )

        @abstractmethod
        def execute(self) -> Union[Transactional, Analytical]:
            """
            Execute the query and return a Transactional or Analytical object.

            :return: Transactional or Analytical object.
            :rtype: Union[Transactional, Analytical]
            """
            raise NotImplementedError(
                "Execute method must be implemented by child classes."
            )