Source code for asyncqlio.orm.schema.index
"""
Represents
"""
import io
import logging
import typing
from cached_property import cached_property
from asyncqlio.orm.schema import column as md_column, table as md_table
logger = logging.getLogger(__name__)
[docs]class Index(object):
"""
Represents an index in a table in a database.
.. code-block:: python3
class MyTable(Table):
id = Column(Integer, primary_key=True)
name = Column(Text)
# make an index on the name column
# by specifying it as the column
name_index = Index(name)
.. versionadded:: 0.2.0
"""
def __init__(self, *columns: 'typing.Union[md_column.Column, str]',
unique: bool = False,
table: 'md_table.Table' = None):
"""
:param columns: The :class:`.Column` objects that this index is on.
:param unique: Is this index unique?
:param table: The :class:`.Table` for this index. Can be None if the index is a member of \
a table.
"""
self.columns = columns
self.unique = unique
self.table = table
def __repr__(self):
return "<Index table={} columns={} name={}>".format(self.table_name, self.columns,
self.name)
def __hash__(self):
return super().__hash__()
def __set_name__(self, owner, name):
"""
Called to update the table and name of this Index.
:param owner: The :class:`.Table` this Column is on.
:param name: The str name of this table.
"""
self.table = owner
if name.startswith(self.table_name):
self.name = name
else:
self.name = "{}_{}".format(self.table_name, name)
logger.debug("Index created with name {} on {}".format(name, owner))
[docs] def get_column_names(self) -> typing.Generator[str, None, None]:
"""
:return: A generator that yields the names of the columns for this index.
"""
for column in self.columns:
if isinstance(column, str):
yield column
else:
yield column.name
@property
def table_name(self) -> str:
"""
The name of this index's table.
"""
if isinstance(self.table, str):
return self.table
return self.table.__tablename__
@cached_property
def quoted_name(self) -> str:
"""
Gets the quoted name for this Index.
This returns the column name in "index" format.
"""
return r'"{}"'.format(self.name)
@cached_property
def quoted_fullname(self) -> str:
"""
Gets the full quoted name for this index.
This returns the column name in "table"."index" format.
"""
return r'"{}"."{}"'.format(self.table_name, self.name)
[docs] @classmethod
def with_name(cls, name: str, *args, **kwargs) -> 'Index':
"""
Creates this column with a name and, optionally, table name already set.
"""
idx = cls(*args, **kwargs)
idx.name = name
return idx
[docs] def get_ddl_sql(self) -> str:
"""
Gets the DDL SQL for this index.
"""
base = io.StringIO()
base.write("CREATE ")
if self.unique:
base.write("UNIQUE ")
base.write("INDEX ")
base.write(self.name)
base.write(" ON ")
base.write(self.table_name)
base.write(" (")
base.write(', '.join(self.get_column_names()))
base.write(")")
return base.getvalue()
def _get_column_refs(self) -> 'typing.Generator[str, None, None]':
for column in self.columns:
if isinstance(column, str):
yield '"{}"'.format(column)
else:
yield column.name
[docs] def generate_schema(self, fp) -> str:
"""
Generates the library schema for this index.
"""
schema = fp or io.StringIO()
schema.write(self.name)
schema.write(" = ")
schema.write(type(self).__name__)
schema.write("(")
schema.write(", ".join(self._get_column_refs()))
if self.unique:
schema.write(", unique=True")
schema.write(")")
return schema.getvalue() if fp is None else ""