"""SQLAlchemy mappings for tables in the UMLS database."""

from umls_tools import orm_mixin

try:
    # SQLAlchemy >= 1.4
    from sqlalchemy.orm import declarative_base
except ImportError:
    # SQLAlchemy <= 1.3
    from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import (
    Column,
    BigInteger,
    Integer,
    String,
    Text,
    Float,
    ForeignKey,
    Index,
)
from sqlalchemy.orm import relationship
from sqlalchemy.ext.compiler import compiles

Base = declarative_base()

_MAP = {"def": "define"}
"""A mapper between UMLS names and database names, not really needed any more
and will be removed (`dict`)
"""


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@compiles(String, "sqlite")
def compile_string(element, compiler, **kw):
    """To enable case insensitive matching for SQLite ``String`` fields."""
    element.collation = "NOCASE"
    return compiler.visit_string(element, **kw)


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@compiles(Text, "sqlite")
def compile_text(element, compiler, **kw):
    """To enable case insensitive matching for SQLite ``Text`` fields."""
    element.collation = "NOCASE"
    return compiler.visit_text(element, **kw)


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_colname(source):
    """Get a column name mapping between the UMLS expectation and the database.

    Parameters
    ----------
    source : `str`
        The UMLS column name.

    Returns
    -------
    target : `str`
        The name in the database. If there are no changes then the original
        name is returned in lowercase.

    Notes
    -----
    Most are 1:1 mappings but changes were originally made made to avoid
    conflicts with Python code. However, this was when I was using lower case
    names. I have since reverted back to uppercase to match the UMLS so this
    is not really needed and will be removed in future.
    """
    try:
        source = _MAP[source]
    except KeyError:
        pass
    return source.lower()


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def print_orm_obj(obj, exclude=None):
    """Prints the contents of the SQL Alchemy ORM object.

    Parameters
    ----------
    obj : `sqlalchemy.ext.declarative.Base`
        The SQLAlchemy declarative base model object. This should have a
        __table__ attribute that contains the corresponding SQLAlchemy table
        object.
    exclude : `NoneType` or `list` or `str`, optional, default: `NoneType`
        A list of attributes (these correspond to table columns) that you do
        not want to include in the string. ``None`` is normalized to an empty
        list.

    Returns
    -------
    formatted_string : `str`
        A formatted string that can be printed. The string contains the
        attributes of the object and the data they contain.

    Notes
    -----
    This is designed to be called from an SQLAlchemy ORM model object and it
    in the __repr__ method. It simply frovides a formatted string that has the
    data in the object.
    """
    exclude = exclude or []

    attr_values = []
    for i in obj.__table__.columns:
        if i.name in exclude:
            continue
        val = getattr(obj, i.name)
        if val.__class__.__name__ != "method":
            attr_values.append("{0}={1}".format(i.name, val))

    # Turn outlist into a string and return
    return "<{0}({1})>".format(obj.__class__.__name__, ", ".join(attr_values))


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrCols(Base):
    """A representation of the ``MRCOLS`` table. There is a row for each
    file/column pair.

    Parameters
    ----------
    MRCOLS_IDX : `int`
        The auto increment primary key.
    COL : `str`, optional, default: `NoneType`
        Column name (length 40).
    DES : `str`, optional, default: `NoneType`
        Column description (length 200).
    REF : `str`, optional, default: `NoneType`
        Documentation section number (length 40).
    MIN : `int`, optional, default: `NoneType`
        Minimum length in characters.
    AV : `float`, optional, default: `NoneType`
        Average length in characters.
    MAX : `int`, optional, default: `NoneType`
        Maximum length in characters.
    FIL : `str`, optional, default: `NoneType`
        File name the column belongs to (length 50).
    DTY : `str`, optional, default: `NoneType`
        SQL-92 data type for this column (length 40).
    """

    __tablename__ = "MRCOLS"

    MRCOLS_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    COL = Column(String(40), doc="Column name.")
    DES = Column(String(200), doc="Column description.")
    REF = Column(String(40), doc="Documentation section number.")
    MIN = Column(Integer, doc="Minimum length in characters.")
    AV = Column(Float, doc="Average length in characters.")
    MAX = Column(Integer, doc="Maximum length in characters.")
    FIL = Column(String(50), doc="File name the column belongs to.")
    DTY = Column(String(40), doc="SQL-92 data type for this column.")


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrConso(Base):
    """A representation of the ``MRCONSO`` table, this is the main concept and
    sources table in the UMLS.

    Parameters
    ----------
    MRCONSO_IDX : `int`
        The auto increment primary key.
    CUI : `str`
        The concept identifier, many ``AUI`` can share the single concept. This
        is indexed (length 8).
    LAT : `str`
        The language of the term (length 3).
    TS : `str`
        Term status (length 1).
    LUI : `str`
        Unique identifier for the term. This is indexed (length 10).
    STT : `str`
        String type (length 3).
    SUI : `str`
        Unique identifier for the string (``STR``). This is indexed (length
        10).
    ISPREF : `str`
        Atom status for this string within this concept - preferred (``Y``) or
        not preferred (``N``)  (length 1).
    AUI : `str`
        Unique identifier for the atom. This is indexed (length 9).
    SAUI : `str`, optional, default: `NoneType`
        Source asserted atom identifier (optional) (length 50).
    SCUI : `str`, optional, default: `NoneType`
        Source asserted concept identifier (optional). This is indexed (length
        100).
    SDUI : `str`, optional, default: `NoneType`
        Source asserted descriptor identifier (optional). This is indexed
        (length 100).
    SAB : `str`
        Abbreviated source name (``SAB``). Two source abbreviations are
        assigned: Root Source Abbreviation (``RSAB``) — short form, no version
        information, for example, ``AI/RHEUM, 1993``, has an ``RSAB`` of
        ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes version
        information, for example, ``AI/RHEUM, 1993``, has an ``VSAB`` of
        ``AIR93``. Official source names, ``RSAB``s, and ``VSAB`` s are included
        on the UMLS Source Vocabulary Documentation `page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.
        This is indexed (length 40).
    TTY : `str`
        Abbreviation for term type in source vocabulary, for example PN
        (Metathesaurus Preferred Name) or ``CD`` (clinical drug). Possible
        values are listed on the abbreviations used in data elements `page <htt
        ps://www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/rele
        ase/abbreviations.html>`__. This is indexed (length 40).
    CODE : `str`
        Most useful source asserted identifier (if the source vocabulary has
        more than one identifier), or a Metathesaurus-generated source entry
        identifier (if the source vocabulary has none). This is indexed (length
        100).
    STR : `str`
        Term string (length text).
    SRL : `int`
        Source restriction level.
    SUPPRESS : `str`
        Suppressible flag. Values = ``O``, ``E``, ``Y``, or ``N``. ``O``: All
        obsolete content, whether they are obsolesced by the source or by NLM.
        These will include all atoms having obsolete ``TTY``s, and other atoms
        becoming obsolete that have not acquired an obsolete ``TTY`` (e.g.
        RxNorm ``SCD`` s no longer associated with current drugs, ``LNC`` atoms
        derived from obsolete ``LNC`` concepts). ``E``: Non-obsolete content
        marked suppressible by an editor. These do not have a suppressible
        ``SAB``/``TTY`` combination. ``Y``: Non-obsolete content deemed
        suppressible during inversion. These can be determined by a specific
        ``SAB``/``TTY`` combination explicitly listed in ``MRRANK``. ``N``:
        None of the above. Defaultsuppressibility as determined by NLM should
        be used by most users, but may not be suitable in some specialized
        applications (length 1).
    CVF : `int`, optional, default: `NoneType`
        Content View Flag. Bit field used to flag rows included in Content
        View. I am not 100% sure of the purpose of this.

    Notes
    -----
    There is exactly one row in this file for each atom (each occurrence of
    each unique string or concept name within each source vocabulary) in the
    Metathesaurus, i.e., there is exactly one row for each unique AUI in the
    Metathesaurus. Every string or concept name in the Metathesaurus appears in
    this file, connected to its language, source vocabularies, and its concept
    identifier. The values of ``TS``, ``STT``, and ``ISPREF`` reflect the
    default order of precedence of vocabulary sources and term types in
    ``MRRANK``.
    """

    __tablename__ = "MRCONSO"
    __table_args__ = (Index("STR_IDX", "STR", mysql_length={"STR": 500}),)

    MRCONSO_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI = Column(
        String(8),
        nullable=False,
        index=True,
        doc="The concept identifier, many ``AUI`` can share the single "
        "concept.",
    )
    LAT = Column(String(3), nullable=False, doc="The language of the term")
    TS = Column(String(1), nullable=False, doc="Term status.")
    LUI = Column(
        String(10),
        nullable=False,
        index=True,
        doc="Unique identifier for the term",
    )
    STT = Column(String(3), nullable=False, doc="String type.")
    SUI = Column(
        String(10),
        nullable=False,
        index=True,
        doc="Unique identifier for the string (``STR``)",
    )
    ISPREF = Column(
        String(1),
        nullable=False,
        doc="Atom status for this string within this concept - preferred"
        " (``Y``) or not preferred (``N``) ",
    )
    AUI = Column(
        String(9),
        unique=True,
        nullable=False,
        index=True,
        doc="Unique identifier for the atom",
    )
    SAUI = Column(String(50), doc="Source asserted atom identifier (optional)")
    SCUI = Column(
        String(100),
        index=True,
        doc="Source asserted concept identifier (optional)",
    )
    SDUI = Column(
        String(100),
        index=True,
        doc="Source asserted descriptor identifier (optional)",
    )
    SAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviated source name (``SAB``). Two source abbreviations are "
        "assigned: Root Source Abbreviation (``RSAB``) — short form, no "
        "version information, for example, ``AI/RHEUM, 1993``, has an ``RSAB``"
        " of ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes"
        " version information, for example, ``AI/RHEUM, 1993``, has an "
        "``VSAB`` of ``AIR93``. Official source names, ``RSAB``s, and "
        "``VSAB`` s are included on the UMLS Source Vocabulary Documentation"
        " `page <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    TTY = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviation for term type in source vocabulary, for example"
        " PN (Metathesaurus Preferred Name) or ``CD`` (clinical drug). "
        "Possible values are listed on the abbreviations used in data elements "
        "`page <https://www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/release/abbreviations.html>`__.",
    )
    CODE = Column(
        String(100),
        nullable=False,
        index=True,
        doc="Most useful source asserted identifier (if the source vocabulary"
        " has more than one identifier), or a Metathesaurus-generated source"
        " entry identifier (if the source vocabulary has none)",
    )
    STR = Column(Text, nullable=False, doc="Term string")
    SRL = Column(Integer, nullable=False, doc="Source restriction level")
    SUPPRESS = Column(
        String(1),
        nullable=False,
        doc="Suppressible flag. Values = ``O``, ``E``, ``Y``, or ``N``."
        " ``O``: All obsolete content, whether they are obsolesced by"
        " the source or by NLM. These will include all atoms having obsolete"
        " ``TTY``s, and other atoms becoming obsolete that have not acquired "
        "an obsolete ``TTY`` (e.g. RxNorm ``SCD`` s no longer associated with "
        "current drugs, ``LNC`` atoms derived from obsolete ``LNC`` concepts)."
        " ``E``: Non-obsolete content marked suppressible by an editor. These"
        " do not have a suppressible ``SAB``/``TTY`` combination. ``Y``: "
        "Non-obsolete content deemed suppressible during inversion. These"
        " can be determined by a specific ``SAB``/``TTY`` combination "
        "explicitly listed in ``MRRANK``. ``N``: None of the above. Default"
        "suppressibility as determined by NLM should be used by most "
        "users, but may not be suitable in some specialized applications.",
    )
    CVF = Column(
        Integer,
        doc="Content View Flag. Bit field used to flag rows included"
        " in Content View. I am not 100% sure of the purpose of this.",
    )

    # #### Relationships ####
    unique_umls_cui = relationship(
        "UniqueUmlsCui", primaryjoin="MrConso.CUI==UniqueUmlsCui.CUI"
    )
    STY = relationship("MrSty", primaryjoin="MrConso.CUI == MrSty.CUI")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(
            self,
            exclude=[
                "lat",
                "ts",
                "lui",
                "stt",
                "saui",
                "scui",
                "sdui",
                "srl",
                "suppress",
                "ftstr",
            ],
        )


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrCui(Base):
    """A representation of the ``MRCUI`` table, this is the retired CUI mapping
    table.

    Parameters
    ----------
    MRCUI_IDX : `int`
        The auto increment primary key.
    CUI1 : `str`
        Unique identifier for first concept, the retired ``CUI`` that was
        present in some prior release, but is currently missing (length 8).
    VER : `str`
        The last release version in which ``CUI1`` was a valid ``CUI`` (length
        10).
    REL : `str`
        Relationship (length 4).
    RELA : `str`, optional, default: `NoneType`
        Relationship attribute (length 100).
    MAPREASON : `str`, optional, default: `NoneType`
        Reason for mapping (length text).
    CUI2 : `str`, optional, default: `NoneType`
        Unique identifier for second concept, the current ``CUI`` that ``CUI1``
        most closely maps to. This is indexed (length 8).
    MAPIN : `str`, optional, default: `NoneType`
        Is this map in current subset? Values of ``Y``, ``N``, or null.
        MetamorphoSys generates the ``Y`` or ``N`` to indicate whether the
        ``CUI2`` concept is or is not present in the subset. The null value is
        for rows where the ``CUI1`` was not present to begin with (i.e.,
        ``REL=DEL``) (length 1).

    Notes
    -----
    For each ``CUI`` that existed in any prior release but is not present in
    the current release. The file includes mappings to current ``CUI`` s as
    synonymous or to one or more related current ``CUI`` where possible. If a
    synonymous mapping cannot be found, other relationships between the
    ``CUI`` s can be created. These relationships can be broader (``RB``),
    narrower (``RN``), other related (``RO``), deleted (``DEL``) or removed
    from subset (``SUBX``). Rows with the ``SUBX`` relationship are added to
    ``MRCUI`` by MetamorphoSys for each ``CUI`` that met the exclusion criteria
    and was consequently removed from the subset. Some ``CUI`` s may be mapped
    to more than one other ``CUI`` using these relationships.  ``CUI`` s may be
    retired when ``(1)`` two released concepts are found to be synonyms and so
    are merged, retiring one ``CUI``; ``(2)`` the concept no longer appears in
    any source vocabulary and is not `rescued` by NLM; or (3) the concept is an
    acknowledged error in a source vocabulary or determined to be a
    Metathesaurus production error.
    """

    __tablename__ = "MRCUI"

    MRCUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI1 = Column(
        String(8),
        nullable=False,
        doc="Unique identifier for first concept, the retired ``CUI`` that "
        "was present in some prior release, but is currently missing.",
    )
    VER = Column(
        String(10),
        nullable=False,
        doc="The last release version in which ``CUI1`` was a valid ``CUI``.",
    )
    REL = Column(String(4), nullable=False, doc="Relationship.")
    RELA = Column(String(100), doc="Relationship attribute.")
    MAPREASON = Column(Text, doc="Reason for mapping.")
    CUI2 = Column(
        String(8),
        index=True,
        doc="Unique identifier for second concept, the current ``CUI`` that"
        " ``CUI1`` most closely maps to",
    )
    MAPIN = Column(
        String(1),
        doc="Is this map in current subset? Values of ``Y``, ``N``, or null."
        " MetamorphoSys generates the ``Y`` or ``N`` to indicate whether the "
        "``CUI2`` concept is or is not present in the subset. The null value "
        "is for rows where the ``CUI1`` was not present to begin with"
        " (i.e., ``REL=DEL``).",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrDef(Base):
    """A representation of the ``MRDEF`` table, this is the definitions table.

    Parameters
    ----------
    MRDEF_IDX : `int`
        The auto increment primary key.
    CUI : `str`
        Concept identifier. This is indexed (length 8).
    AUI : `str`
        Atom identifier. This is indexed (length 9).
    ATUI : `str`
        Identifier for the attribute. This is indexed (length 11).
    SATUI : `str`, optional, default: `NoneType`
        Source asserted attribute identifier (optional) (length 50).
    SAB : `str`
        Abbreviated source name (``SAB``). Two source abbreviations are
        assigned: Root Source Abbreviation (``RSAB``) — short form, no version
        information, for example, ``AI/RHEUM, 1993``, has an ``RSAB`` of
        ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes version
        information, for example, ``AI/RHEUM, 1993``, has an ``VSAB`` of
        ``AIR93``. Official source names, ``RSAB``s, and ``VSAB`` s are included
        on the UMLS Source Vocabulary Documentation `page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.
        This is indexed (length 40).
    DEFINE : `str`
        Definition (length text).
    SUPPRESS : `str`
        Suppressible flag. Values = ``O``, ``E``, ``Y``, or ``N``. Reflects the
        suppressible status of the attribute; not yet in use. See also
        ``SUPPRESS`` in ``MRCONSO``, ``MRREL``, and ``MRSAT`` (length 1).
    CVF : `int`, optional, default: `NoneType`
        Content View Flag. Bit field used to flag rows included in Content
        View. I am not 100% sure of the purpose of this.
    """

    __tablename__ = "MRDEF"

    MRDEF_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI = Column(
        String(8), nullable=False, index=True, doc="Concept identifier."
    )
    AUI = Column(String(9), nullable=False, index=True, doc="Atom identifier.")
    ATUI = Column(
        String(11),
        nullable=False,
        index=True,
        unique=True,
        doc="Identifier for the attribute.",
    )
    SATUI = Column(
        String(50), doc="Source asserted attribute identifier (optional)"
    )
    SAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviated source name (``SAB``). Two source abbreviations are "
        "assigned: Root Source Abbreviation (``RSAB``) — short form, no "
        "version information, for example, ``AI/RHEUM, 1993``, has an ``RSAB``"
        " of ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes"
        " version information, for example, ``AI/RHEUM, 1993``, has an "
        "``VSAB`` of ``AIR93``. Official source names, ``RSAB``s, and "
        "``VSAB`` s are included on the UMLS Source Vocabulary Documentation"
        " `page <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    DEFINE = Column(Text, nullable=False, doc="Definition.")
    SUPPRESS = Column(
        String(1),
        nullable=False,
        doc="Suppressible flag. Values = ``O``, ``E``, ``Y``, or ``N``."
        " Reflects the suppressible status of the attribute; not yet in"
        " use. See also ``SUPPRESS`` in ``MRCONSO``, ``MRREL``, and ``MRSAT``",
    )
    CVF = Column(
        Integer,
        doc="Content View Flag. Bit field used to flag rows included"
        " in Content View. I am not 100% sure of the purpose of this.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrDoc(Base):
    """A representation of the ``MRDOC`` table, documentation for abbreviated
    values.

    Parameters
    ----------
    MRDOC_IDX : `int`
        The auto increment primary key.
    DOCKEY : `str`
        Data element or attribute (length 50).
    VALUE : `str`, optional, default: `NoneType`
        Abbreviation that is one of its values (length 200).
    TYPE : `str`
        Type of information in ``EXPL`` column (length 50).
    EXPL : `str`, optional, default: `NoneType`
        Explanation of ``VALUE`` (length text).
    """

    __tablename__ = "MRDOC"

    MRDOC_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    DOCKEY = Column(
        String(50), nullable=False, doc="Data element or attribute."
    )
    VALUE = Column(String(200), doc="Abbreviation that is one of its values.")
    TYPE = Column(
        String(50),
        nullable=False,
        doc="Type of information in ``EXPL`` column.",
    )
    EXPL = Column(Text, doc="Explanation of ``VALUE``.")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrFiles(Base):
    """A representation of the ``MRFILES`` table, There is one row in this
    file.

    Parameters
    ----------
    MRFILES_IDX : `int`
        The auto increment primary key.
    FIL : `str`, optional, default: `NoneType`
        Physical filename (length 50).
    DES : `str`, optional, default: `NoneType`
        File description (length 200).
    FMT : `str`, optional, default: `NoneType`
        Comma separated list of column names in order (length text).
    CLS : `int`, optional, default: `NoneType`
        Number of columns.
    RWS : `int`, optional, default: `NoneType`
        Number of rows.
    BTS : `int`, optional, default: `NoneType`
        Size in bytes in this format (ISO/PC or Unix).
    """

    __tablename__ = "MRFILES"

    MRFILES_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    FIL = Column(String(50), doc="Physical filename")
    DES = Column(String(200), doc="File description.")
    FMT = Column(Text, doc="Comma separated list of column names in order")
    CLS = Column(Integer, doc="Number of columns")
    RWS = Column(Integer, doc="Number of rows")
    BTS = Column(
        BigInteger, doc="Size in bytes in this format (ISO/PC or Unix)"
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrHier(Base):
    """A representation of the ``MRHIER`` table, this is the computable
    hierarchies table.

    Parameters
    ----------
    MRHIER_IDX : `int`
        The auto increment primary key.
    CUI : `str`
        Concept identifier. This is indexed (length 8).
    AUI : `str`
        Atom identifier. This is indexed (length 9).
    CXN : `int`
        Context number (e.g., 1, 2, 3). This is indexed.
    PAUI : `str`, optional, default: `NoneType`
        Unique identifier of atom's immediate parent within this context. This
        is indexed (length 10).
    SAB : `str`
        Abbreviated source name (``SAB``). Two source abbreviations are
        assigned: Root Source Abbreviation (``RSAB``) — short form, no version
        information, for example, ``AI/RHEUM, 1993``, has an ``RSAB`` of
        ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes version
        information, for example, ``AI/RHEUM, 1993``, has an ``VSAB`` of
        ``AIR93``. Official source names, ``RSAB``s, and ``VSAB`` s are included
        on the UMLS Source Vocabulary Documentation `page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.
        This is indexed (length 40).
    RELA : `str`, optional, default: `NoneType`
        Relationship of atom to its immediate parent (length 100).
    PTR : `str`, optional, default: `NoneType`
        Path to the top or root of the hierarchical context from this atom,
        represented as a list of ``AUI``s, separated by periods (.) The first
        one in the list is top of the hierarchy; the last one in the list is
        the immediate parent of the atom, which also appears as the value of
        ``PAUI`` (length text).
    HCD : `str`, optional, default: `NoneType`
        Source asserted hierarchical number or code for this atom in this
        context; this field is only populated when it is different from the
        code (unique identifier or code for the string in that source) (length
        100).
    CVF : `int`, optional, default: `NoneType`
        Content View Flag. Bit field used to flag rows included in Content
        View. I am not 100% sure of the purpose of this.

    Notes
    -----
    If a source vocabulary does not contain hierarchies, its atoms will have no
    rows in this file. If a source vocabulary is multi-hierarchical (allows the
    same atom to appear in more than one hierarchy), some of its atoms will
    have more than one row in this file. ``MRHIER`` gives complete and
    representation of all hierarchies present in all Metathesaurus source
    vocabularies. Hierarchical displays can be computed by combining data in
    this file with data in ``MRCONSO``. The distance-1 relationships, i.e.,
    immediate parent and immediate child relationships, represented in
    ``MRHIER`` also appear in ``MRREL``.
    """

    __tablename__ = "MRHIER"
    __table_args__ = (Index("PTR_IDX", "PTR", mysql_length={"PTR": 500}),)

    MRHIER_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI = Column(
        String(8), nullable=False, index=True, doc="Concept identifier."
    )
    AUI = Column(String(9), nullable=False, index=True, doc="Atom identifier.")
    CXN = Column(
        Integer,
        nullable=False,
        index=True,
        doc="Context number (e.g., 1, 2, 3)",
    )
    PAUI = Column(
        String(10),
        index=True,
        doc="Unique identifier of atom's immediate parent within this context",
    )
    SAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviated source name (``SAB``). Two source abbreviations are "
        "assigned: Root Source Abbreviation (``RSAB``) — short form, no "
        "version information, for example, ``AI/RHEUM, 1993``, has an ``RSAB``"
        " of ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes"
        " version information, for example, ``AI/RHEUM, 1993``, has an "
        "``VSAB`` of ``AIR93``. Official source names, ``RSAB``s, and "
        "``VSAB`` s are included on the UMLS Source Vocabulary Documentation"
        " `page <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    RELA = Column(
        String(100), doc="Relationship of atom to its immediate parent"
    )
    PTR = Column(
        Text,
        doc="Path to the top or root of the hierarchical context from this"
        " atom, represented as a list of ``AUI``s, separated by periods (.)"
        " The first one in the list is top of the hierarchy; the last one in"
        " the list is the immediate parent of the atom, which also appears as "
        "the value of ``PAUI``.",
    )
    HCD = Column(
        String(100),
        doc="Source asserted hierarchical number or code for this atom in"
        " this context; this field is only populated when it is different"
        " from the code (unique identifier or code for the string in that"
        " source).",
    )
    CVF = Column(
        Integer,
        doc="Content View Flag. Bit field used to flag rows included"
        " in Content View. I am not 100% sure of the purpose of this.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrHist(Base):
    """A representation of the ``MRHIST`` table, this file tracks source-
    asserted history information. It currently includes ``SNOMED CT`` history
    only.

    Parameters
    ----------
    MRHIST_IDX : `int`
        The auto increment primary key.
    CUI : `str`, optional, default: `NoneType`
        . This is indexed (length 8).
    SOURCECUI : `str`, optional, default: `NoneType`
        Source asserted unique identifier. This is indexed (length 100).
    SAB : `str`
        Abbreviated source name (``SAB``). Two source abbreviations are
        assigned: Root Source Abbreviation (``RSAB``) — short form, no version
        information, for example, ``AI/RHEUM, 1993``, has an ``RSAB`` of
        ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes version
        information, for example, ``AI/RHEUM, 1993``, has an ``VSAB`` of
        ``AIR93``. Official source names, ``RSAB``s, and ``VSAB`` s are
        included on the UMLS Source Vocabulary Documentation `page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.
        This is indexed (length 40).
    SVER : `str`, optional, default: `NoneType`
        Release date or version number of a source (length 40).
    CHANGETYPE : `str`, optional, default: `NoneType`
        Source asserted code for type of change (length text).
    CHANGEKEY : `str`, optional, default: `NoneType`
        ``CONCEPTSTATUS`` (if history relates to a ``SNOMED CT`` concept) or
        ``DESCRIPTIONSTATUS`` (if history relates to a ``SNOMED CT`` atom)
        (length text).
    CHANGEVAL : `str`, optional, default: `NoneType`
        ``CONCEPTSTATUS`` value or ``DESCRIPTIONSTATUS`` value after the change
        took place. Note: The change may have affected something other than the
        status value (length text).
    REASON : `str`, optional, default: `NoneType`
        Explanation of change if present (length text).
    CVF : `int`, optional, default: `NoneType`
        Content View Flag. Bit field used to flag rows included in Content
        View. I am not 100% sure of the purpose of this.
    """

    __tablename__ = "MRHIST"

    MRHIST_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI = Column(String(8), index=True, doc="")
    SOURCECUI = Column(
        String(100), index=True, doc="Source asserted unique identifier"
    )
    SAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviated source name (``SAB``). Two source abbreviations are "
        "assigned: Root Source Abbreviation (``RSAB``) — short form, no "
        "version information, for example, ``AI/RHEUM, 1993``, has an ``RSAB``"
        " of ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes"
        " version information, for example, ``AI/RHEUM, 1993``, has an "
        "``VSAB`` of ``AIR93``. Official source names, ``RSAB``s, and "
        "``VSAB`` s are included on the UMLS Source Vocabulary Documentation"
        " `page <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    SVER = Column(String(40), doc="Release date or version number of a source")
    CHANGETYPE = Column(Text, doc="Source asserted code for type of change")
    CHANGEKEY = Column(
        Text,
        doc="``CONCEPTSTATUS`` (if history relates to a ``SNOMED CT`` concept)"
        " or ``DESCRIPTIONSTATUS`` (if history relates to a ``SNOMED CT`` "
        "atom)",
    )
    CHANGEVAL = Column(
        Text,
        doc="``CONCEPTSTATUS`` value or ``DESCRIPTIONSTATUS`` value after the"
        " change took place. Note: The change may have affected something other"
        " than the status value.",
    )
    REASON = Column(Text, doc="Explanation of change if present")
    CVF = Column(
        Integer,
        doc="Content View Flag. Bit field used to flag rows included"
        " in Content View. I am not 100% sure of the purpose of this.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrMap(Base):
    """A representation of the ``MRMAP`` table, This contains sets of mappings
    between vocabularies.

    Parameters
    ----------
    MRMAP_IDX : `int`
        The auto increment primary key.
    MAPSETCUI : `str`
        Unique identifier for the UMLS concept which represents the whole map
        set. This is indexed (length 8).
    MAPSETSAB : `str`
        Source abbreviation for the provider of the map set (length 40).
    MAPSUBSETID : `str`, optional, default: `NoneType`
        Map subset identifier used to identify a subset of related mappings
        within a map set. This is used for cases where the``FROMEXPR`` may have
        more than one potential mapping (optional) (length 10).
    MAPRANK : `int`, optional, default: `NoneType`
        Order in which mappings in a subset should be applied. Used only where
        ``MAPSUBSETID`` is used. (optional).
    MAPID : `str`
        Unique identifier for this individual mapping. Primary key of this
        table to identify a particular row (length 50).
    MAPSID : `str`, optional, default: `NoneType`
        Source asserted identifier for this mapping (optional) (length 50).
    FROMID : `str`
        Identifier for the entity being mapped from. This is an internal UMLS
        identifier used to point to an external entity in a source vocabulary
        (represented by the ``FROMEXPR``). When the source provides such an
        identifier, it is reused here. Otherwise, it is generated by NLM. The
        ``FROMID`` is only unique within a map set. It is not a pointer to UMLS
        entities like atoms or concepts. There is a one-to-one correlation
        between ``FROMID`` and a unique set of values in ``FROMSID``,
        ``FROMEXPR``, ``FROMTYPE``, ``FROMRULE``, and ``FROMRES`` within a map
        set (length 50).
    FROMSID : `str`, optional, default: `NoneType`
        Source asserted identifier for the entity being mapped from (optional)
        (length 50).
    FROMEXPR : `str`
        Entity being mapped from - can be a single code/identifier/concept name
        or a complex expression involving multiple codes/identifiers/concept
        names, Boolean operators and/or punctuation (length text).
    FROMTYPE : `str`
        Type of entity being mapped from (length 50).
    FROMRULE : `str`, optional, default: `NoneType`
        Machine processable rule applicable to the entity being mapped from
        (optional) (length text).
    FROMRES : `str`, optional, default: `NoneType`
        Restriction applicable to the entity being mapped from (optional)
        (length text).
    REL : `str`
        Relationship of the entity being mapped from to the entity being mapped
        to (length 4).
    RELA : `str`, optional, default: `NoneType`
        Additional relationship label (optional) (length 100).
    TOID : `str`, optional, default: `NoneType`
        Identifier for the entity being mapped to. This is an internal
        identifier used to point to an external entity in a source vocabulary
        (represented by the ``TOEXPR``). When the source provides such an
        identifier, it is reused here. Otherwise, it is generated by NLM. The
        ``TOID`` is only unique within a map set. It is not a pointer to UMLS
        entities like atoms or concepts. There is a one-to-one correlation
        between ``TOID`` and a unique set of values in ``TOSID``, ``TOEXPR``,
        ``TOTYPE``, ``TORULE``, ``TORES`` within a map set (length 50).
    TOSID : `str`, optional, default: `NoneType`
        Source asserted identifier for the entity being mapped to (optional)
        (length 50).
    TOEXPR : `str`, optional, default: `NoneType`
        Entity being mapped to - can be a single code/identifier/concept
        name or a complex expression involving multiple
        codes/identifiers/concept names, Boolean operators and/or punctuation
        (length text).
    TOTYPE : `str`, optional, default: `NoneType`
        Type of entity being mapped to (length 50).
    TORULE : `str`, optional, default: `NoneType`
        Machine processable rule applicable to the entity being mapped to
        (optional) (length text).
    TORES : `str`, optional, default: `NoneType`
        Restriction applicable to the entity being mapped to (optional) (length
        text).
    MAPRULE : `str`, optional, default: `NoneType`
        Machine processable rule applicable to this mapping (optional) (length
        text).
    MAPRES : `str`, optional, default: `NoneType`
        Restriction applicable to this mapping (optional) (length text).
    MAPTYPE : `str`, optional, default: `NoneType`
        Type of mapping (optional) (length 50).
    MAPATN : `str`, optional, default: `NoneType`
        The name of the attribute associated with this mapping (not yet in use)
        (length 100).
    MAPATV : `str`, optional, default: `NoneType`
        The value of the attribute associated with this mapping (not yet in
        use) (length text).
    CVF : `int`, optional, default: `NoneType`
        Content View Flag. Bit field used to flag rows included inContent View.
        I am not 100% sure of the purpose of this.

    Notes
    -----
    Most mappings are between codes/identifiers (or expressions formed by
    codes/identifiers) from two different vocabularies. At least one of the
    vocabularies in each set of mappings is present in the Metathesaurus;
    usually both of them are. The version of a vocabulary that appears in a set
    of mappings may be different from the version of that vocabulary that
    appears in the other Metathesaurus release files. The versions of the
    vocabularies in a map set are specified by the ``FROMVSAB`` and ``TOVSAB``
    attributes of the map set concept (see below). Users should be aware that
    the mappings are only valid between the versions of the vocabularies
    specified in these attributes. The version of the map set itself is
    specified by the ``MAPSETVERSION`` attribute of the map set concept.  MRMAP
    is complex, to allow for more complicated mappings. Where possible, all
    mappings are also represented in the simpler ``MRSMAP`` table described
    below.  Each set of mappings is represented by a map set concept in
    ``MRCONSO`` (with ``TTY = XM``) identified by a ``CUI`` (``MAPSETCUI``).
    Metadata of a map set are found in ``MRSAT`` as attributes of the map set
    concept. Each map set has three ``SAB`` values associated with it: the
    ``SAB`` of the map set itself (``MAPSETVSAB``), the ``SAB`` of the source
    being mapped (``FROMVSAB``) and the ``SAB`` of the source being mapped to
    (``TOVSAB``). Thus, a single map set asserts mappings from only one source
    to only one other source.  A subset of the mappings is redundantly
    represented as ``mapped_to`` and ``mapped_from`` relationships in
    ``MRREL``. These are one-to-one mappings between two vocabularies which are
    both present in the UMLS. These general relationships are not as precise as
    the mapping files, since any differences between versions of the
    vocabularies in the map set and the versions of those vocabularies in the
    rest of the Metathesaurus files are ignored. Such differences may affect
    the validity of the relationships in ``MRREL`` in a small number of cases.
    There are three map sets that contain mappings from Metathesaurus concepts
    (represented by a ``CUI``) to expressions formed by one or more concept
    names. These were formerly called associated expressions, and all have
    ``MAPTYPE=ATX``. This data is derived from earlier mapping efforts and is
    represented in the ``MRATX`` file in original release format.
    """

    __tablename__ = "MRMAP"

    MRMAP_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    MAPSETCUI = Column(
        String(8),
        nullable=False,
        index=True,
        doc="Unique identifier for the UMLS concept which represents the"
        " whole map set.",
    )
    MAPSETSAB = Column(
        String(40),
        nullable=False,
        doc="Source abbreviation for the provider of the map set.",
    )
    MAPSUBSETID = Column(
        String(10),
        doc="Map subset identifier used to identify a subset of related"
        " mappings within a map set. This is used for cases where the"
        "``FROMEXPR`` may have more than one potential mapping (optional).",
    )
    MAPRANK = Column(
        Integer,
        doc="Order in which mappings in a subset should be applied. Used"
        " only where ``MAPSUBSETID`` is used. (optional)",
    )
    MAPID = Column(
        String(50),
        nullable=False,
        doc="Unique identifier for this individual mapping. Primary key of"
        " this table to identify a particular row.",
    )
    MAPSID = Column(
        String(50),
        doc="Source asserted identifier for this mapping (optional).",
    )
    FROMID = Column(
        String(50),
        nullable=False,
        doc="Identifier for the entity being mapped from. This is an internal"
        " UMLS identifier used to point to an external entity in a source"
        " vocabulary (represented by the ``FROMEXPR``). When the source "
        " provides such an identifier, it is reused here. Otherwise, it is "
        "generated by NLM. The ``FROMID`` is only unique within a map set. "
        "It is not a pointer to UMLS entities like atoms or concepts. There is"
        " a one-to-one correlation between ``FROMID`` and a unique set of "
        "values in ``FROMSID``, ``FROMEXPR``, ``FROMTYPE``, ``FROMRULE``, and"
        "``FROMRES`` within a map set.",
    )
    FROMSID = Column(
        String(50),
        doc="Source asserted identifier for the entity being mapped from"
        " (optional).",
    )
    FROMEXPR = Column(
        Text,
        nullable=False,
        doc="Entity being mapped from - can be a single code/identifier/"
        "concept name or a complex expression involving multiple codes/"
        "identifiers/concept names, Boolean operators and/or punctuation",
    )
    FROMTYPE = Column(
        String(50), nullable=False, doc="Type of entity being mapped from."
    )
    FROMRULE = Column(
        Text,
        doc="Machine processable rule applicable to the entity being mapped"
        " from (optional)",
    )
    FROMRES = Column(
        Text,
        doc="Restriction applicable to the entity being mapped from"
        " (optional).",
    )
    REL = Column(
        String(4),
        nullable=False,
        doc="Relationship of the entity being mapped from to the entity being"
        " mapped to.",
    )
    RELA = Column(String(100), doc="Additional relationship label (optional).")
    TOID = Column(
        String(50),
        doc="Identifier for the entity being mapped to. This is an internal"
        " identifier used to point to an external entity in a source "
        "vocabulary (represented by the ``TOEXPR``). When the source provides "
        "such an identifier, it is reused here. Otherwise, it is generated "
        "by NLM. The ``TOID`` is only unique within a map set. It is not a"
        " pointer to UMLS entities like atoms or concepts. There is a "
        "one-to-one correlation between ``TOID`` and a unique set of values in"
        " ``TOSID``, ``TOEXPR``, ``TOTYPE``, ``TORULE``, ``TORES`` within a"
        " map set.",
    )
    TOSID = Column(
        String(50),
        doc="Source asserted identifier for the entity being mapped to"
        " (optional).",
    )
    TOEXPR = Column(
        Text,
        doc="Entity being mapped to - can be a single code/identifier/concept"
        "name or a complex expression involving multiple codes/identifiers/"
        "concept names, Boolean operators and/or punctuation.",
    )
    TOTYPE = Column(String(50), doc="Type of entity being mapped to.")
    TORULE = Column(
        Text,
        doc="Machine processable rule applicable to the entity being mapped to"
        " (optional).",
    )
    TORES = Column(
        Text,
        doc="Restriction applicable to the entity being mapped to (optional).",
    )
    MAPRULE = Column(
        Text,
        doc="Machine processable rule applicable to this mapping (optional).",
    )
    MAPRES = Column(
        Text, doc="Restriction applicable to this mapping (optional)."
    )
    MAPTYPE = Column(String(50), doc="Type of mapping (optional).")
    MAPATN = Column(
        String(100),
        doc="The name of the attribute associated with this mapping"
        " (not yet in use)",
    )
    MAPATV = Column(
        Text,
        doc="The value of the attribute associated with this mapping"
        " (not yet in use)",
    )
    CVF = Column(
        Integer,
        doc="Content View Flag. Bit field used to flag rows included in"
        "Content View. I am not 100% sure of the purpose of this.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrRank(Base):
    """A representation of the ``MRRANK`` table, this ranks concept names.

    Parameters
    ----------
    MRRANK_IDX : `int`
        The auto increment primary key.
    MRRANK_RANK : `int`, optional, default: `NoneType`
        Numeric order of precedence, higher value wins.
    SAB : `str`
        Abbreviated source name (``SAB``). Two source abbreviations are
        assigned: Root Source Abbreviation (``RSAB``) — short form, no version
        information, for example, ``AI/RHEUM, 1993``, has an ``RSAB`` of
        ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes version
        information, for example, ``AI/RHEUM, 1993``, has an ``VSAB`` of
        ``AIR93``. Official source names, ``RSAB``s, and ``VSAB`` s are
        included on the UMLS Source Vocabulary Documentation `page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.
        This is indexed (length 40).
    TTY : `str`
        Abbreviation for term type in source vocabulary, for example ``PN``
        (Metathesaurus Preferred Name) or ``CD`` (Clinical Drug). Possible
        values are listed in Abbreviations Used in Data Elements `page <http://
        www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/release/a
        bbreviations.html>`__. This is indexed (length 40).
    SUPPRESS : `str`
        NLM-recommended source and term type (``SAB``/``TTY``) suppressible
        flag . Values = ``Y`` or ``N``. Indicates the suppressible status of
        all atoms (names) with this source and term type (``SAB``/``TTY``).
        Note that changes made in MetamorphoSys at the suppressible tab are
        recorded in your configuration file. Status ``E`` does not occur here,
        as it is assigned only to individual cases such as the names (atoms) in
        ``MRCONSO``. See also ``SUPPRESS`` in ``MRCONSO``, ``MRDEF``, and
        ``MRREL`` (length 1).

    Notes
    -----
    There is exactly one row for each concept name type from each Metathesaurus
    source vocabulary (each ``SAB``-``TTY`` combination). The ``RANK`` and
    ``SUPPRESS`` values in the distributed file are those used in Metathesaurus
    production.
    """

    __tablename__ = "MRRANK"

    MRRANK_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    MRRANK_RANK = Column(
        Integer, doc="Numeric order of precedence, higher value wins"
    )
    SAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviated source name (``SAB``). Two source abbreviations are "
        "assigned: Root Source Abbreviation (``RSAB``) — short form, no "
        "version information, for example, ``AI/RHEUM, 1993``, has an ``RSAB``"
        " of ``AIR`` and versioned Source Abbreviation (``VSAB``) — includes"
        " version information, for example, ``AI/RHEUM, 1993``, has an "
        "``VSAB`` of ``AIR93``. Official source names, ``RSAB``s, and "
        "``VSAB`` s are included on the UMLS Source Vocabulary Documentation"
        " `page <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    TTY = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviation for term type in source vocabulary, for example"
        " ``PN`` (Metathesaurus Preferred Name) or ``CD`` (Clinical Drug)."
        " Possible values are listed in Abbreviations Used in Data Elements"
        " `page <http://www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/release/abbreviations.html>`__",
    )
    SUPPRESS = Column(
        String(1),
        nullable=False,
        doc="NLM-recommended source and term type (``SAB``/``TTY``) "
        "suppressible flag . Values = ``Y`` or ``N``. Indicates the "
        "suppressible status of all atoms (names) with this source and term"
        " type (``SAB``/``TTY``). Note that changes made in MetamorphoSys"
        " at the suppressible tab are recorded in your configuration file."
        " Status ``E`` does not occur here, as it is assigned only to "
        "individual cases such as the names (atoms) in ``MRCONSO``. See also"
        " ``SUPPRESS`` in ``MRCONSO``, ``MRDEF``, and ``MRREL``.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrRel(Base):
    """A representation of the ``MRREL`` table. This details the relationships
    between concepts. Also see:
    `the UMLS <https://www.ncbi.nlm.nih.gov/books/NBK9685/table/ch03.T.related_concepts_file_mrrel_rrf/>`__

    Parameters
    ----------
    MRREL_IDX : `int`
        The auto increment primary key.
    CUI1 : `str`
        Unique identifier of first concept. This is indexed (length 8).
    AUI1 : `str`, optional, default: `NoneType`
        Unique identifier of first atom. This is indexed (length 9).
    STYPE1 : `str`
        The name of the column in ``MRCONSO`` that contains the identifier used
        for the first element in the relationship, i.e. ``AUI``, ``CODE``,
        ``CUI``, ``SCUI``, ``SDUI`` (length 50).
    REL : `str`
        Relationship of second concept or atom to first concept or atom (length
        4).
    CUI2 : `str`
        Unique identifier of second concept. This is indexed (length 8).
    AUI2 : `str`, optional, default: `NoneType`
        Unique identifier of second atom. This is indexed (length 9).
    STYPE2 : `str`
        The name of the column in ``MRCONSO`` that contains the  identifier
        used for the second element in the relationship, i.e. ``AUI``,
        ``CODE``, ``CUI``, ``SCUI``, ``SDUI`` (length 50).
    RELA : `str`, optional, default: `NoneType`
        Additional (more specific) relationship label (optional) (length 100).
    RUI : `str`
        Unique identifier of relationship (length 10).
    SRUI : `str`, optional, default: `NoneType`
        Source asserted relationship identifier, if present (length 50).
    SAB : `str`
        Abbreviated source name (``SAB``). Two source abbreviations are
        assigned: Root Source Abbreviation (``RSAB``) — short form, no version
        information, for example, AI/RHEUM, 1993, has an RSAB of 'AIR' and
        versioned Source Abbreviation (``VSAB``) — includes version
        information, for example, ``AI/RHEUM, 1993``, has an ``VSAB`` of
        ``AIR93``. Official source names, ``RSAB``s, and ``VSAB`` s are
        included on the `UMLS Source Vocabulary Documentation page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.
        This is indexed (length 40).
    SL : `str`
        Source of relationship labels (length 40).
    RG : `str`, optional, default: `NoneType`
        Relationship group. Used to indicate that a set of relationships should
        be looked at in conjunction (length 10).
    DIR : `str`, optional, default: `NoneType`
        Source asserted directionality flag. ``Y`` indicates that this is the
        direction of the relationship in its source; ``N`` indicates that it is
        not; a blank indicates that it is not important or has not yet been
        determined (length 1).
    SUPPRESS : `str`
        Suppressible flag. Reflects the suppressible status of the
        relationship. See also ``SUPPRESS`` in ``MRCONSO``, ``MRDEF``, and
        ``MRSAT`` (length 1).
    CVF : `int`, optional, default: `NoneType`
        Content view flag. Bit field used to flag rows included inContent View.
        I am not 100% sure of the purpose of this.

    Notes
    -----
    There is one row in this table for each relationship between concepts or
    atoms known to the Metathesaurus, with the following exceptions found in
    other files: pair-wise mapping relationships between two source
    vocabularies found in ``MRMAP`` and ``MRSMAP``.  For asymmetrical
    relationships there is one row for each direction of the relationship. Note
    also the direction of ``REL`` - the relationship which the SECOND concept
    or atom (with Concept Unique Identifier ``CUI2`` and atom unique identifier
    ``AUI2``) has to the ``FIRST`` concept or atom (with concept unique
    identifier ``CUI1`` and atom unique identifier ``AUI1``).
    """

    __tablename__ = "MRREL"

    MRREL_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI1 = Column(
        String(8),
        nullable=False,
        index=True,
        doc="Unique identifier of first concept.",
    )
    AUI1 = Column(String(9), index=True, doc="Unique identifier of first atom.")
    STYPE1 = Column(
        String(50),
        nullable=False,
        doc="The name of the column in ``MRCONSO`` that contains the "
        "identifier used for the first element in the relationship,"
        " i.e. ``AUI``, ``CODE``, ``CUI``, ``SCUI``, ``SDUI``.",
    )
    REL = Column(
        String(4),
        nullable=False,
        doc="Relationship of second concept or atom to first concept or atom.",
    )
    CUI2 = Column(
        String(8),
        nullable=False,
        index=True,
        doc="Unique identifier of second concept.",
    )
    AUI2 = Column(
        String(9), index=True, doc="Unique identifier of second atom."
    )
    STYPE2 = Column(
        String(50),
        nullable=False,
        doc="The name of the column in ``MRCONSO`` that contains the "
        " identifier used for the second element in the relationship, i.e."
        " ``AUI``, ``CODE``, ``CUI``, ``SCUI``, ``SDUI``.",
    )
    RELA = Column(
        String(100),
        doc="Additional (more specific) relationship label (optional)",
    )
    RUI = Column(
        String(10), nullable=False, doc="Unique identifier of relationship."
    )
    SRUI = Column(
        String(50), doc="Source asserted relationship identifier, if present."
    )
    SAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviated source name (``SAB``). Two source abbreviations are "
        "assigned: Root Source Abbreviation (``RSAB``) — short form, no version"
        " information, for example, AI/RHEUM, 1993, has an RSAB of 'AIR' "
        "and versioned Source Abbreviation (``VSAB``) — includes version "
        "information, for example, ``AI/RHEUM, 1993``, has an ``VSAB`` of"
        " ``AIR93``. Official source names, ``RSAB``s, and ``VSAB`` s are "
        "included on the `UMLS Source Vocabulary Documentation page"
        " <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    SL = Column(String(40), nullable=False, doc="Source of relationship labels")
    RG = Column(
        String(10),
        doc="Relationship group. Used to indicate that a set of relationships"
        " should be looked at in conjunction.",
    )
    DIR = Column(
        String(1),
        doc="Source asserted directionality flag. ``Y`` indicates that this"
        " is the direction of the relationship in its source; ``N`` indicates"
        " that it is not; a blank indicates that it is not important or has"
        " not yet been determined.",
    )
    SUPPRESS = Column(
        String(1),
        nullable=False,
        doc="Suppressible flag. Reflects the suppressible status of the"
        " relationship. See also ``SUPPRESS`` in ``MRCONSO``, ``MRDEF``, and"
        " ``MRSAT``.",
    )
    CVF = Column(
        Integer,
        doc="Content view flag. Bit field used to flag rows included in"
        "Content View. I am not 100% sure of the purpose of this.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrSab(Base):
    """A representation of the MRSAB (source abbreviations) table.

    Parameters
    ----------
    MRSAB_IDX : `int`
        The auto increment primary key.
    VCUI : `str`, optional, default: `NoneType`
        ``CUI`` of the versioned ``SRC`` concept for a source (length 8).
    RCUI : `str`, optional, default: `NoneType`
        ``CUI`` of the root ``SRC`` concept for a source (length 8).
    VSAB : `str`
        The versioned source abbreviation for a source, e.g.,
        ``MSH2003_2002_10_24`` (length 40).
    RSAB : `str`
        The root source abbreviation for a source e.g., ``MSH``. This is
        indexed (length 40).
    SON : `str`
        The official name for a source (length text).
    SF : `str`
        The source family for a source (length 40).
    SVER : `str`, optional, default: `NoneType`
        Version The source version, e.g., ``2001`` (length 40).
    VSTART : `str`, optional, default: `NoneType`
        The date a source became active, e.g., ``2001_04_03`` (length 8).
    VEND : `str`, optional, default: `NoneType`
        The date a source ceased to be active, e.g., ``2001_05_10`` (length 8).
    IMETA : `str`
        The version of the Metathesaurus in which a source first appeared
        (inserted), e.g., ``2001AB`` (length 10).
    RMETA : `str`, optional, default: `NoneType`
        The version of the Metathesaurus in which the source last appeared
        (removed), e.g., ``2001AC`` (length 10).
    SLC : `str`, optional, default: `NoneType`
        The source license contact field contains the following semi-colon-
        separated subfields: Name, Title, Organization, Address 1, Address 2,
        City, State/Prov., Country, Zip, Telephone, Fax, Email, URL (length
        text).
    SCC : `str`, optional, default: `NoneType`
        The source content contact field contains the following semi-colon-
        separated subfields: Name, Title, Organization, Address 1, Address 2,
        City, State/Prov., Country, Zip, Telephone, Fax, Email, URL (length
        text).
    SRL : `int`
        Source Restriction Level        0, 1, 2, 3, 4, 9 - explained in the
        license agreement.
    TFR : `int`, optional, default: `NoneType`
        The number of terms for this source in MRCONSO, e.g., ``12343``.
    CFR : `int`, optional, default: `NoneType`
        The number of ``CUI`` s associated with this source, e.g., ``10234``.
    CXTY : `str`, optional, default: `NoneType`
        The type of contexts for this source. Values are ``FULL``, ``FULL-
        MULTIPLE``, ``null`` (length 50).
    TTYL : `str`, optional, default: `NoneType`
        Term type list from source, e.g., ``MH``, ``EN``, ``PM``, ``TQ``
        (length 400).
    ATNL : `str`, optional, default: `NoneType`
        The attribute name list (from ``MRSAT``), e.g., ``MUI``, ``RN``, ``TH``
        (length text).
    LAT : `str`, optional, default: `NoneType`
        The language of the terms in the source (length 3).
    CENC : `str`
        Character encoding, all UMLS content is provided in Unicode, encoded in
        ``UTF-8``. MetamorphoSys will allow exclusion of extended characters
        with some loss of information. Transliteration to other character
        encodings is possible but not supported buy NLM; for further
        information, see the `unicode docs <http://www​.unicode.org>`__ (length
        40).
    CURVER : `str`
        Current version. A ``Y`` or ``N`` flag indicating whether or not this
        row corresponds to the current version of the named source (length 1).
    SABIN : `str`
        Source in subset. A ``Y`` or ``N`` flag indicating whether or not this
        row is represented in the current MetamorphoSys subset. Initially
        always ``Y`` where CURVER is ``Y``, but later is recomputed by
        MetamorphoSys (length 1).
    SSN : `str`
        The short name of a source as used by the UMLS Terminology Services
        (length text).
    SCIT : `str`
        Source citation, for sources released in ``2014AA`` and later, the
        citation field contains the following semi-colon-separated subfields:
        Author name(s), Personal author address, Organization author(s).
        Editor(s), Title, Content Designator, Medium Designator, Edition, Place
        of Pub., Publisher, Date of pub. or copyright, Date of revision,
        Location, Extent Series, Avail. Statement (URL), Language, Notes, Empty
        Subfield, Empty Subfield, The citation field for sources released prior
        to ``2014AA`` will be updated as resources permit (length text).

    Notes
    -----
    The Metathesaurus has `versionless` or `root` source abbreviations
    (``SAB``s) in the data files. ``MRSAB`` connects the root ``SAB`` to fully
    specified version information for the current release. For example, the
    released ``SAB`` for ``MeSH`` is now simply ``MSH``. In ``MRSAB``, you will
    see a current versioned ``SAB``, e.g., ``MSH2003_2002_10_24``. ``MRSAB``
    allows all other Metathesaurus files to use versionless source
    abbreviations, so that all rows with no data change between versions remain
    unchanged. MetamorphoSys can produce files with either the root or
    versioned ``SAB`` s so that either form can be available in custom subsets
    of the Metathesaurus.  There is one row in this file for every version of
    every source in the current Metathesaurus; eventually there will also be
    historical information with a row for each version of each source that has
    appeared in any Metathesaurus release. Note that the field ``CURVER`` has
    the value ``Y`` to identify the version in this Metathesaurus release.
    Future releases of ``MRSAB`` will also contain historical version
    information in rows with CURVER value ``N``.  Sources with contexts have
    `full` contexts, i.e., all levels of terms may have Ancestors, Parents, and
    Children. A full context may also be further designated as multiple.
    Multiple indicates that a single concept in this source may have multiple
    hierarchical positions.  The UMLS Source Vocabulary Documentation `page
    <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__ of
    the current release documentation lists each source in the Metathesaurus
    and includes information about the type of context, if any, for each
    source.
    """

    __tablename__ = "MRSAB"

    MRSAB_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    VCUI = Column(
        String(8), doc="``CUI`` of the versioned ``SRC`` concept for a source"
    )
    RCUI = Column(
        String(8), doc="``CUI`` of the root ``SRC`` concept for a source"
    )
    VSAB = Column(
        String(40),
        nullable=False,
        unique=True,
        doc="The versioned source abbreviation for a source, e.g., "
        "``MSH2003_2002_10_24``",
    )
    RSAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="The root source abbreviation for a source e.g., ``MSH``",
    )
    SON = Column(Text, nullable=False, doc="The official name for a source")
    SF = Column(
        String(40), nullable=False, doc="The source family for a source"
    )
    SVER = Column(
        String(40), doc="Version	The source version, e.g., ``2001``"
    )
    VSTART = Column(
        String(8), doc="The date a source became active, e.g., ``2001_04_03``"
    )
    VEND = Column(
        String(8),
        doc="The date a source ceased to be active, e.g., ``2001_05_10``",
    )
    IMETA = Column(
        String(10),
        nullable=False,
        doc="The version of the Metathesaurus in which a source first appeared"
        " (inserted), e.g., ``2001AB``",
    )
    RMETA = Column(
        String(10),
        doc="The version of the Metathesaurus in which the source last appeared"
        " (removed), e.g., ``2001AC``",
    )
    SLC = Column(
        Text,
        doc="The source license contact field contains the following "
        "semi-colon-separated subfields: Name, Title, Organization, Address 1,"
        " Address 2, City, State/Prov., Country, Zip, Telephone, Fax, Email,"
        " URL",
    )
    SCC = Column(
        Text,
        doc="The source content contact field contains the following "
        "semi-colon-separated subfields: Name, Title, Organization, Address 1,"
        " Address 2, City, State/Prov., Country, Zip, Telephone, Fax, "
        "Email, URL",
    )
    SRL = Column(
        Integer,
        nullable=False,
        doc="Source Restriction Level	0, 1, 2, 3, 4, 9 - explained in the"
        " license agreement",
    )
    TFR = Column(
        Integer,
        doc="The number of terms for this source in MRCONSO, e.g., ``12343``",
    )
    CFR = Column(
        Integer,
        doc="The number of ``CUI`` s associated with this source, e.g., "
        "``10234``",
    )
    CXTY = Column(
        String(50),
        doc="The type of contexts for this source. Values are ``FULL``, "
        "``FULL-MULTIPLE``, ``null``.",
    )
    TTYL = Column(
        String(400),
        doc="Term type list from source, e.g., ``MH``, ``EN``, ``PM``, ``TQ``",
    )
    ATNL = Column(
        Text,
        doc="The attribute name list (from ``MRSAT``), e.g., ``MUI``,"
        " ``RN``, ``TH``",
    )
    LAT = Column(String(3), doc="The language of the terms in the source")
    CENC = Column(
        String(40),
        nullable=False,
        doc="Character encoding, all UMLS content is provided in Unicode,"
        " encoded in ``UTF-8``. MetamorphoSys will allow exclusion of "
        "extended characters with some loss of information. "
        "Transliteration to other character encodings is possible but not"
        " supported buy NLM; for further information, see the `unicode docs"
        " <http://www​.unicode.org>`__",
    )
    CURVER = Column(
        String(1),
        nullable=False,
        doc="Current version. A ``Y`` or ``N`` flag indicating whether or"
        " not this row corresponds to the current version of the named source",
    )
    SABIN = Column(
        String(1),
        nullable=False,
        doc="Source in subset. A ``Y`` or ``N`` flag indicating whether or"
        " not this row is represented in the current MetamorphoSys subset."
        " Initially always ``Y`` where CURVER is ``Y``, but later is "
        "recomputed by MetamorphoSys.",
    )
    SSN = Column(
        Text,
        nullable=False,
        doc="The short name of a source as used by the UMLS Terminology"
        " Services",
    )
    SCIT = Column(
        Text,
        nullable=False,
        doc="Source citation, for sources released in ``2014AA`` and later,"
        " the citation field contains the following semi-colon-separated"
        " subfields: Author name(s), Personal author address, "
        "Organization author(s). Editor(s), Title, Content Designator,"
        " Medium Designator, Edition, Place of Pub., Publisher, Date of pub."
        " or copyright, Date of revision, Location, Extent Series, Avail."
        " Statement (URL), Language, Notes, Empty Subfield, Empty Subfield,"
        " The citation field for sources released prior to ``2014AA`` will"
        " be updated as resources permit.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrSat(Base):
    """A representation of the MRSAT table, simple concept and atom attributes.

    Parameters
    ----------
    MRSAT_IDX : `int`
        The auto increment primary key.
    CUI : `str`
        Unique identifier for concept (if METAUI is a relationship identifier,
        this will be CUI1 for that relationship). This is indexed (length 8).
    LUI : `str`, optional, default: `NoneType`
        Unique identifier for term (optional - present for atom attributes, but
        not for relationship attributes) (length 10).
    SUI : `str`, optional, default: `NoneType`
        Unique identifier for string (optional - present for atom attributes,
        but not for relationship attributes) (length 10).
    METAUI : `str`, optional, default: `NoneType`
        Metathesaurus atom identifier (will have a leading A) or Metathesaurus
        relationship identifier (will have a leading R) or blank if it is a
        concept attribute. This is indexed (length 100).
    STYPE : `str`
        The name of the column in MRCONSO or MRREL that contains the identifier
        to which the attribute is attached, i.e. AUI, CODE, CUI, RUI, SCUI,
        SDUI (length 50).
    CODE : `str`, optional, default: `NoneType`
        Most useful source asserted identifier (if the source vocabulary
        contains more than one) or a Metathesaurus-generated source entry
        identifier (if the source vocabulary has none). Optional - present if
        METAUI is an AUI (length 100).
    ATUI : `str`
        Unique identifier for attribute (length 11).
    SATUI : `str`, optional, default: `NoneType`
        Source asserted attribute identifier (optional - present if it exists)
        (length 50).
    ATN : `str`
        Attribute name. Possible values appear in MRDOC and are described on
        the `attribute Names page <https://www.nlm.nih.gov/research/umls/knowle
        dge_sources/metathesaurus/release/attribute_names.html>`__. This is
        indexed (length 100).
    SAB : `str`
        Abbreviated source name of the source of relationship. Maximum field
        length is 20 alphanumeric characters. Two source abbreviations are
        assigned: Root Source Abbreviation (RSAB) — short form, no version
        information, for example, AI/RHEUM, 1993, has an RSAB of 'AIR'
        Versioned Source Abbreviation (VSAB) — includes version information,
        for example, AI/RHEUM, 1993, has an VSAB of 'AIR93'. Official source
        names, RSABs, and VSABs are included on the UMLS`source Vocabulary
        Documentation page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.
        This is indexed (length 40).
    ATV : `str`, optional, default: `NoneType`
        Attribute value described under specific attribute name on the
        Attributes Names page. A few attribute values exceed 1,000 characters.
        Many of the abbreviations used in attribute values are explained in
        MRDOC.RRF and included on the Abbreviations Used in `data elements page
        <http://www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/r
        elease/abbreviations.html>`__ (length text).
    SUPPRESS : `str`
        Suppressible flag. Values = O, E, Y, or N. Reflects the suppressible
        status of the attribute. See also SUPPRESS in MRCONSO.RRF, MRDEF.RRF,
        and MRREL.RRF (length 1).
    CVF : `int`, optional, default: `NoneType`
        Content View Flag. Bit field used to flag rows included inContent View.
        I am not 100% sure of the purpose of this.

    Notes
    -----
    There is exactly one row in this table for each concept, atom, or
    relationship attribute that does not have a sub-element structure. All
    Metathesaurus concepts and a minority of Metathesaurus relationships have
    entries in this file. This file includes all source vocabulary attributes
    that do not fit into other categories.
    """

    __tablename__ = "MRSAT"

    MRSAT_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI = Column(
        String(8),
        nullable=False,
        index=True,
        doc="Unique identifier for concept (if METAUI is a relationship "
        "identifier, this will be CUI1 for that relationship)",
    )
    LUI = Column(
        String(10),
        doc="Unique identifier for term (optional - present for atom"
        " attributes, but not for relationship attributes)",
    )
    SUI = Column(
        String(10),
        doc="Unique identifier for string (optional - present for atom "
        "attributes, but not for relationship attributes)",
    )
    METAUI = Column(
        String(100),
        index=True,
        doc="Metathesaurus atom identifier (will have a leading A) or"
        " Metathesaurus relationship identifier (will have a leading R)"
        " or blank if it is a concept attribute.",
    )
    STYPE = Column(
        String(50),
        nullable=False,
        doc="The name of the column in MRCONSO or MRREL that contains"
        " the identifier to which the attribute is attached, i.e. AUI, CODE,"
        " CUI, RUI, SCUI, SDUI.",
    )
    CODE = Column(
        String(100),
        doc="Most useful source asserted identifier (if the source vocabulary"
        " contains more than one) or a Metathesaurus-generated source entry"
        " identifier (if the source vocabulary has none). Optional - present"
        " if METAUI is an AUI.",
    )
    ATUI = Column(
        String(11),
        nullable=False,
        unique=True,
        doc="Unique identifier for attribute",
    )
    SATUI = Column(
        String(50),
        doc="Source asserted attribute identifier (optional - present if it "
        "exists)",
    )
    ATN = Column(
        String(100),
        nullable=False,
        index=True,
        doc="Attribute name. Possible values appear in MRDOC and are "
        "described on the `attribute Names page <https://www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/release/attribute_names.html>`__.",
    )
    SAB = Column(
        String(40),
        nullable=False,
        index=True,
        doc="Abbreviated source name of the source of relationship. Maximum "
        "field length is 20 alphanumeric characters. Two source abbreviations"
        " are assigned: Root Source Abbreviation (RSAB) — short form, no "
        "version information, for example, AI/RHEUM, 1993, has an RSAB "
        "of 'AIR' Versioned Source Abbreviation (VSAB) — includes version "
        "information, for example, AI/RHEUM, 1993, has an VSAB of 'AIR93'. "
        "Official source names, RSABs, and VSABs are included on the UMLS"
        "`source Vocabulary Documentation page <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    ATV = Column(
        Text,
        doc="Attribute value described under specific attribute name on the"
        " Attributes Names page. A few attribute values exceed 1,000 "
        "characters. Many of the abbreviations used in attribute values are"
        " explained in MRDOC.RRF and included on the Abbreviations Used in"
        " `data elements page <http://www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/release/abbreviations.html>`__.",
    )
    SUPPRESS = Column(
        String(1),
        nullable=False,
        doc="Suppressible flag. Values = O, E, Y, or N. Reflects the "
        "suppressible status of the attribute. See also SUPPRESS in"
        " MRCONSO.RRF, MRDEF.RRF, and MRREL.RRF.",
    )
    CVF = Column(
        Integer,
        doc="Content View Flag. Bit field used to flag rows included in"
        "Content View. I am not 100% sure of the purpose of this.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrSmap(Base):
    """A representation of the ``MRSMAP`` table. This file provides a simpler
    representation of most of the mappings in ``MRMAP``.

    Parameters
    ----------
    MRSMAP_IDX : `int`
        The auto increment primary key.
    MAPSETCUI : `str`
        Unique identifier for the UMLS concept which represents the whole map
        set (length 8).
    MAPSETSAB : `str`
        Source abbreviation for the map set (length 40).
    MAPID : `str`
        Unique identifier for this individual mapping. Primary key of this
        table to identify a particular row (length 50).
    MAPSID : `str`, optional, default: `NoneType`
        Source asserted identifier for this mapping (optional) (length 50).
    FROMEXPR : `str`
        Entity being mapped from - can be a single code/identifier/concept name
        or a complex expression involving multiple codes/identifiers/concept
        names, Boolean operators and/or punctuation (length text).
    FROMTYPE : `str`
        Type of entity being mapped from (length 50).
    REL : `str`
        Relationship of the entity being mapped from to the entity being mapped
        to (length 4).
    RELA : `str`, optional, default: `NoneType`
        Additional relationship label (optional) (length 100).
    TOEXPR : `str`, optional, default: `NoneType`
        Entity being mapped to - can be a single code/identifier /concept name
        or a complex expression involving multiple codes/identifiers/concept
        names, Boolean operators and/or punctuation (length text).
    TOTYPE : `str`, optional, default: `NoneType`
        Type of entity being mapped to (length 50).
    CVF : `int`, optional, default: `NoneType`
        Content View Flag. Bit field used to flag rows included inContent View.
        I am not 100% sure of the purpose of this.

    Notes
    -----
    This is to serve applications which do not require the full richness of the
    MRMAP data structure. Generally, mappings that support rule-based
    processing need the additional fields of ``MRMAP`` (e.g. ``MAPRANK``,
    ``MAPRULE``, ``MAPRES``) and will not be represented in MRSMAP. More
    specifically, all mappings with non-null values for ``MAPSUBSETID`` and
    ``MAPRANK`` are excluded from ``MRSMAP``.
    """

    __tablename__ = "MRSMAP"

    MRSMAP_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    MAPSETCUI = Column(
        String(8),
        nullable=False,
        doc="Unique identifier for the UMLS concept which represents the whole"
        " map set.",
    )
    MAPSETSAB = Column(
        String(40), nullable=False, doc="Source abbreviation for the map set."
    )
    MAPID = Column(
        String(50),
        nullable=False,
        doc="Unique identifier for this individual mapping. Primary key of "
        "this table to identify a particular row.",
    )
    MAPSID = Column(
        String(50),
        doc="Source asserted identifier for this mapping (optional).",
    )
    FROMEXPR = Column(
        Text,
        nullable=False,
        doc="Entity being mapped from - can be a single code/identifier/"
        "concept name or a complex expression involving multiple codes/"
        "identifiers/concept names, Boolean operators and/or punctuation.",
    )
    FROMTYPE = Column(
        String(50), nullable=False, doc="Type of entity being mapped from."
    )
    REL = Column(
        String(4),
        nullable=False,
        doc="Relationship of the entity being mapped from to the entity"
        " being mapped to.",
    )
    RELA = Column(String(100), doc="Additional relationship label (optional).")
    TOEXPR = Column(
        Text,
        doc="Entity being mapped to - can be a single code/identifier"
        " /concept name or a complex expression involving multiple"
        " codes/identifiers/concept names, Boolean operators and/or"
        " punctuation.",
    )
    TOTYPE = Column(String(50), doc="Type of entity being mapped to.")
    CVF = Column(
        Integer,
        doc="Content View Flag. Bit field used to flag rows included in"
        "Content View. I am not 100% sure of the purpose of this.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrSty(Base):
    """A representation of the ``MRSTY`` table. This is the mappings between
    UMLS concepts and their semantic types.

    Parameters
    ----------
    MRSTY_IDX : `int`
        The auto increment primary key.
    CUI : `str`
        Concept identifier. This is indexed. Foreign key to ``MRCONSO.CUI``
        (length 8).
    TUI : `str`
        Semantic type identifier (length 4).
    STN : `str`
        Semantic Type tree number (length 100).
    STY : `str`
        Semantic type name. The valid values are defined in the semantic
        network. This is indexed (length 50).
    ATUI : `str`
        Unique identifier for attribute (length 11).
    CVF : `int`, optional, default: `NoneType`
        Content view flag. Bit field used to flag rows included inContent View.
        I am not 100% sure of the purpose of this.
    """

    __tablename__ = "MRSTY"

    MRSTY_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    CUI = Column(
        String(8),
        ForeignKey("MRCONSO.CUI"),
        nullable=False,
        index=True,
        doc="Concept identifier.",
    )
    TUI = Column(String(4), nullable=False, doc="Semantic type identifier.")
    STN = Column(String(100), nullable=False, doc="Semantic Type tree number.")
    STY = Column(
        String(50),
        nullable=False,
        index=True,
        doc="Semantic type name. The valid values are defined in the semantic "
        "network.",
    )
    ATUI = Column(
        String(11),
        nullable=False,
        unique=True,
        doc="Unique identifier for attribute",
    )
    CVF = Column(
        Integer,
        doc="Content view flag. Bit field used to flag rows included in"
        "Content View. I am not 100% sure of the purpose of this.",
    )

    CUIS = relationship("MrConso", primaryjoin="MrConso.CUI == MrSty.CUI")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrXnsEng(Base):
    """A representation of the ``MRXNS_ENG`` table.

    Parameters
    ----------
    MRXNSENG_IDX : `int`
        The auto increment primary key.
    LAT : `str`
        Abbreviation of language of the string (always ``ENG`` in this edition
        of the Metathesaurus) (length 3).
    NSTR : `str`
        Normalized string in lowercase (described in Section 2.7.3.1) (length
        text).
    CUI : `str`
        Concept identifier (length 8).
    LUI : `str`
        Term identifier (length 10).
    SUI : `str`
        String identifier (length 10).

    Notes
    -----
    There is one row in this table for each normalized string found in each
    unique English-language Metathesaurus string (ignoring upper-lower case).
    All English-language Metathesaurus entries have entries in the normalized
    string index. There are no normalized word indexes for other languages in
    this edition of the Metathesaurus.
    """

    __tablename__ = "MRXNS_ENG"
    __table_args__ = (Index("NSTR_IDX", "NSTR", mysql_length={"NSTR": 500}),)

    MRXNSENG_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    LAT = Column(
        String(3),
        nullable=False,
        doc="Abbreviation of language of the string (always ``ENG`` in this"
        " edition of the Metathesaurus)",
    )
    NSTR = Column(
        Text,
        nullable=False,
        doc="Normalized string in lowercase (described in Section 2.7.3.1)",
    )
    CUI = Column(String(8), nullable=False, doc="Concept identifier")
    LUI = Column(String(10), nullable=False, doc="Term identifier")
    SUI = Column(String(10), nullable=False, doc="String identifier")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrXnwEng(Base):
    """A representation of the ``MRXNW_ENG`` table.

    Parameters
    ----------
    MRXNWENG_IDX : `int`
        .
    LAT : `str`
        Abbreviation of language of the string in which the word appears
        (always ``ENG`` in this edition of the Metathesaurus) (length 3).
    NWD : `str`
        Normalized word in lowercase (described in Section 2.7.2.1). This is
        indexed (length 100).
    CUI : `str`
        Concept identifier (length 8).
    LUI : `str`
        Term identifier (length 10).
    SUI : `str`
        String identifier (length 10).

    Notes
    -----
    There is one row in this table for each normalized word found in each
    unique English-language Metathesaurus string. All English-language
    Metathesaurus entries have entries in the normalized word index. There are
    no normalized string indexes for other languages in the Metathesaurus.
    """

    __tablename__ = "MRXNW_ENG"

    MRXNWENG_IDX = Column(Integer, primary_key=True, autoincrement=True, doc="")
    LAT = Column(
        String(3),
        nullable=False,
        doc="Abbreviation of language of the string in which the word appears"
        " (always ``ENG`` in this edition of the Metathesaurus)",
    )
    NWD = Column(
        String(100),
        nullable=False,
        index=True,
        doc="Normalized word in lowercase (described in Section 2.7.2.1)",
    )
    CUI = Column(String(8), nullable=False, doc="Concept identifier")
    LUI = Column(String(10), nullable=False, doc="Term identifier")
    SUI = Column(String(10), nullable=False, doc="String identifier")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrAui(Base):
    """A representation of the ``MRAUI`` table.

    Parameters
    ----------
    MRAUI_IDX : `int`
        The auto increment primary key.
    AUI1 : `str`
        Atom unique identifier (length 9).
    CUI1 : `str`
        Concept unique identifier (length 8).
    VER : `str`
        Version in which this change to the AUI first occurred (length 10).
    REL : `str`, optional, default: `NoneType`
        Relationship (length 4).
    RELA : `str`, optional, default: `NoneType`
        Relationship attribute (length 100).
    MAPREASON : `str`
        Reason for mapping (length text).
    AUI2 : `str`
        Unique identifier for second atom (length 9).
    CUI2 : `str`
        Unique identifier for second concept - the current ``CUI`` that
        ``CUI1`` most closely maps to. This is indexed (length 8).
    MAPIN : `str`
        Mapping in current subset: is ``AUI2`` in current subset? Values of
        ``Y``, ``N``, or ``null`` (length 1).

    Notes
    -----
    This table records the movement of atom unique identifiers (``AUI``s) from
    a concept (``CUI``1) in one version of the Metathesaurus to a concept
    (``CUI``2) in the next version (``VER``) of the Metathesaurus. The file is
    historical.
    """

    __tablename__ = "MRAUI"

    MRAUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    AUI1 = Column(String(9), nullable=False, doc="Atom unique identifier")
    CUI1 = Column(String(8), nullable=False, doc="Concept unique identifier")
    VER = Column(
        String(10),
        nullable=False,
        doc="Version in which this change to the AUI first occurred",
    )
    REL = Column(String(4), doc="Relationship")
    RELA = Column(String(100), doc="Relationship attribute")
    MAPREASON = Column(Text, nullable=False, doc="Reason for mapping")
    AUI2 = Column(
        String(9), nullable=False, doc="Unique identifier for second atom"
    )
    CUI2 = Column(
        String(8),
        nullable=False,
        index=True,
        doc="Unique identifier for second concept - the current ``CUI`` that"
        " ``CUI1`` most closely maps to",
    )
    MAPIN = Column(
        String(1),
        nullable=False,
        doc="Mapping in current subset: is ``AUI2`` in current subset? "
        "Values of ``Y``, ``N``, or ``null``.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MrXwEng(Base):
    """A representation of the ``MRXW_ENG`` table.

    Parameters
    ----------
    MRXWENG_IDX : `int`
        The auto increment primary key.
    LAT : `str`
        Abbreviation of language of the string in which the word appears
        (length 3).
    WD : `str`
        Word in lowercase (length 200).
    CUI : `str`
        Concept identifier (length 8).
    LUI : `str`
        Term identifier (length 10).
    SUI : `str`
        String identifier (length 10).

    Notes
    -----
    There is one row in these tables for each word found in each unique
    Metathesaurus string (ignoring upper-lower case). All Metathesaurus entries
    have entries in the word index. The entries are sorted in ASCII order.
    """

    __tablename__ = "MRXW_ENG"

    MRXWENG_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    LAT = Column(
        String(3),
        nullable=False,
        doc="Abbreviation of language of the string in which the word appears",
    )
    WD = Column(String(200), nullable=False, doc="Word in lowercase")
    CUI = Column(String(8), nullable=False, doc="Concept identifier")
    LUI = Column(String(10), nullable=False, doc="Term identifier")
    SUI = Column(String(10), nullable=False, doc="String identifier")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class AmbigSui(Base):
    """A representation of the ``AMBIGSUI`` table.

    Parameters
    ----------
    AMBIGSUI_IDX : `int`
        The auto increment primary key.
    SUI : `str`
        String unique identifier. This is indexed (length 10).
    CUI : `str`
        Concept unique identifier (length 8).

    Notes
    -----
    In the instance that a string unique identifier (``SUI``) is linked to
    multiple Concept Unique Identifiers (``CUI``s), there is one row in this
    table for each ``SUI``-``CUI`` s pair.  This table is derived from the
    ``META`` directory. In the Metathesaurus, there is only one ``SUI`` for
    each unique string within each language, even if the string has multiple
    meanings. This table is only of interest to system developers who use the
    ``SUI`` in their applications or in local data files.
    """

    __tablename__ = "AMBIGSUI"

    AMBIGSUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    SUI = Column(
        String(10), nullable=False, index=True, doc="String unique identifier"
    )
    CUI = Column(String(8), nullable=False, doc="Concept unique identifier")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class AmbigLui(Base):
    """A representation of the ``AMBIGLUI`` table.

    Parameters
    ----------
    AMBIGLUI_IDX : `int`
        The auto increment primary key.
    LUI : `str`
        Lexical unique identifier. This is indexed (length 10).
    CUI : `str`
        Concept unique identifier (length 8).

    Notes
    -----
    In the instance that a lexical unique identifier (LUI) is linked to
    multiple concept unique identifiers (``CUI``s), there is one row in this
    table for each ``LUI``-``CUI`` s pair. This file identifies those lexical
    variant classes which have multiple meanings in the Metathesaurus.  In the
    Metathesaurus, the ``LUI`` links all strings within the English language
    that are identified as lexical variants of each other by the luinorm
    program found in the UMLS SPECIALIST Lexicon and Tools. ``LUI`` s are
    assigned irrespective of the meaning of each string. This table may be
    useful to system developers who wish to use the lexical programs in their
    applications to identify and disambiguate ambiguous terms.
    """

    __tablename__ = "AMBIGLUI"

    AMBIGLUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    LUI = Column(
        String(10), nullable=False, index=True, doc="Lexical unique identifier"
    )
    CUI = Column(String(8), nullable=False, doc="Concept unique identifier")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class DeletedCui(Base):
    """A representation of the ``DELETEDCUI`` table.

    Parameters
    ----------
    DELETEDCUI_IDX : `int`
        The auto increment primary key.
    PCUI : `str`
        Concept unique identifier in the previous Metathesaurus (length 8).
    PSTR : `str`
        Preferred name of this concept in the previous Metathesaurus (length
        text).

    Notes
    -----
    Concepts whose meaning is no longer present in the Metathesaurus are
    reported in this file. There is a row for each concept that existed in the
    previous release and is not present in the current release. If the meaning
    exists in the current release, i.e., the missing concept was merged with
    another current concept, it is reported in the ``MERGEDCUI`` table and not
    in this table.
    """

    __tablename__ = "DELETEDCUI"

    DELETEDCUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    PCUI = Column(
        String(8),
        nullable=False,
        doc="Concept unique identifier in the previous Metathesaurus",
    )
    PSTR = Column(
        Text,
        nullable=False,
        doc="Preferred name of this concept in the previous Metathesaurus",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class DeletedLui(Base):
    """A representation of the ``DELETEDLUI`` table.

    Parameters
    ----------
    DELETEDLUI_IDX : `int`
        The auto increment primary key.
    PLUI : `str`
        Lexical unique identifier in the previous Metathesaurus (length 10).
    PSTR : `str`
        Preferred name of term in the previous Metathesaurus (length text).

    Notes
    -----
    There is exactly one row in this table for each lexical unique identifier
    (``LUI``) that appeared in the previous Metathesaurus, but does not appear
    in this Metathesaurus.  ``LUI`` s are assigned by the luinorm program, part
    of the lvg program in the UMLS SPECIALIST Lexicon and Tools.  These entries
    represent the cases where ``LUI`` s identified by the previous release's
    luinorm program, when used to identify lexical variants in the previous
    Metathesaurus, are no longer found with this release's luinorm on this
    release's Metathesaurus. This does not necessarily imply the deletion of a
    string or a concept from the Metathesaurus.
    """

    __tablename__ = "DELETEDLUI"

    DELETEDLUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    PLUI = Column(
        String(10),
        nullable=False,
        doc="Lexical unique identifier in the previous Metathesaurus",
    )
    PSTR = Column(
        Text,
        nullable=False,
        doc="Preferred name of term in the previous Metathesaurus",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class DeletedSui(Base):
    """A representation of the ``DELETEDSUI`` table.

    Parameters
    ----------
    DELETEDSUI_IDX : `int`
        The auto increment primary key.
    PSUI : `str`
        String unique identifier in the previous Metathesaurus that is not
        present in this Metathesaurus (length 10).
    LAT : `str`
         (length 3).
    PSTR : `str`
        Preferred Name of Term in the previous Metathesaurus that is not
        present in this Metathesaurus (length text).

    Notes
    -----
    There is exactly one row in this file for each string in each language that
    was present in an entry in the previous Metathesaurus and does not appear
    in this Metathesaurus.  Note that this does not necessarily imply the
    deletion of a term (``LUI``) or a concept (``CUI``) from the Metathesaurus.
    A string deleted in one language may still appear in the Metathesaurus in
    another language.
    """

    __tablename__ = "DELETEDSUI"

    DELETEDSUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    PSUI = Column(
        String(10),
        nullable=False,
        doc="String unique identifier in the previous Metathesaurus that is"
        " not present in this Metathesaurus",
    )
    # TODO: Delete column?
    LAT = Column(String(3), nullable=False, doc="")
    PSTR = Column(
        Text,
        nullable=False,
        doc="Preferred Name of Term in the previous Metathesaurus that is "
        "not present in this Metathesaurus",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MergedCui(Base):
    """A representation of the ``MERGEDCUI`` table,  merged concepts table.

    Parameters
    ----------
    MERGEDCUI_IDX : `int`
        The auto increment primary key.
    PCUI : `str`
        Concept Unique Identifier in the previous Metathesaurus (length 8).
    CUI : `str`
        Concept Unique Identifier in this Metathesaurus (length 8).

    Notes
    -----
    There is exactly one row in this table for each released concept in the
    previous Metathesaurus (``CUI1``) that was merged into another released
    concept from the previous Metathesaurus (``CUI2``). When this merge occurs,
    the first ``CUI`` (``CUI1``) was retired; this table shows the ``CUI``
    (``CUI2``) for the merged concept in this Metathesaurus.  Entries in this
    file represent concepts pairs that were considered to have different
    meanings in the previous edition, but which are now identified as synonyms.
    """

    __tablename__ = "MERGEDCUI"

    MERGEDCUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    # TODO: Check column name (PCUI1?)
    PCUI = Column(
        String(8),
        nullable=False,
        doc="Concept Unique Identifier in the previous Metathesaurus",
    )
    CUI = Column(
        String(8),
        nullable=False,
        doc="Concept Unique Identifier in this Metathesaurus.",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class MergedLui(Base):
    """A representation of the ``MERGEDLUI`` table, the merged terms table.

    Parameters
    ----------
    MERGEDLUI_IDX : `int`
        The auto increment primary key.
    PLUI : `str`, optional, default: `NoneType`
        Lexical unique identifier in the previous Metathesaurus but not present
        in this Metathesaurus (length 10).
    LUI : `str`, optional, default: `NoneType`
        Lexical unique identifier into which it was merged in this
        Metathesaurus (length 10).

    Notes
    -----
    There is exactly one row in this file for each case in which strings had
    different Lexical Unique Identifiers (``LUI``s) in the previous
    Metathesaurus yet share the same LUI in this Metathesaurus; a ``LUI``
    present in the previous Metathesaurus is therefore absent from this
    Metathesaurus.  ``LUI`` s are assigned by the luinorm program, part of the
    lvg program in the UMLS SPECIALIST Lexicon and Tools.  These entries
    represent the cases where separate lexical variants as identified by the
    previous release's luinorm program version are a single lexical variant as
    identified by this release's luinorm.
    """

    __tablename__ = "MERGEDLUI"

    MERGEDLUI_IDX = Column(
        Integer,
        primary_key=True,
        autoincrement=True,
        doc="The auto increment primary key.",
    )
    PLUI = Column(
        String(10),
        doc="Lexical unique identifier in the previous Metathesaurus but not"
        " present in this Metathesaurus",
    )
    LUI = Column(
        String(10),
        doc="Lexical unique identifier into which it was merged in this"
        " Metathesaurus",
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self)


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class UniqueUmlsCui(Base):
    """A representation of the unique_umls_cui table. This table is built after
    the UMLS has been downloaded and imported

    Parameters
    ----------
    CUI_IDX : `int`
        The primary key column, will auto-increment if not provided.
    AUI : `str`
        The UMLS atom identifier. This is indexed. Foreign key to
        ``MRCONSO.AUI`` (length 8).
    CUI : `str`
        The UMLS concept identifier. This is indexed. Foreign key to
        ``MRCONSO.CUI`` (length 8).
    STR : `str`, optional, default: `NoneType`
        The UMLS term string (length text).
    LAT : `str`
         (length 3).
    SAB : `str`
        Abbreviated source name (SAB). Two source abbreviations are assigned:
        Root Source Abbreviation (RSAB) — short form, no version information,
        for example, AI/RHEUM, 1993, has an RSAB of 'AIR' and versioned Source
        Abbreviation (VSAB) — includes version information, for example,
        AI/RHEUM, 1993, has an VSAB of 'AIR93'. Official source names, RSABs,
        and VSABs are included on the `UMLS Source Vocabulary Documentation
        page
        <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__
        (length 40).
    TTY : `str`
         The term type (length 40).
    CODE : `str`
         The term code in the source (length 100).
    RANK : `int`
        The NLM defined top rank for the ``TTY``/``SAB``.
    NAUI : `int`, optional, default: `NoneType`
        The number of atoms that are in the CUIs.
    PROB_CUI : `float`, optional, default: `NoneType`
        The probability of randomly selecting this CUI from the MRCONSO able.
    SEMANTIC_TYPES : `str`, optional, default: `NoneType`
        A pipe separated list of the semantic types associated with the concept
        (length text).
    """

    __tablename__ = "UNIQUE_CUI"

    CUI_IDX = Column(
        Integer,
        primary_key=True,
        nullable=False,
        doc="The primary key column, will auto-increment if not provided",
    )
    AUI = Column(
        String(9),
        ForeignKey("MRCONSO.AUI"),
        index=True,
        nullable=False,
        doc="The UMLS atom identifier",
    )
    CUI = Column(
        String(8),
        ForeignKey("MRCONSO.CUI"),
        index=True,
        nullable=False,
        doc="The UMLS concept identifier",
    )
    STR = Column(Text, doc="The UMLS term string")
    LAT = Column(String(3), nullable=False, doc="")
    SAB = Column(
        String(40),
        nullable=False,
        doc="Abbreviated source name (SAB). Two source abbreviations are "
        "assigned: Root Source Abbreviation (RSAB) — short form, no version"
        " information, for example, AI/RHEUM, 1993, has an RSAB of 'AIR' "
        "and versioned Source Abbreviation (VSAB) — includes version "
        "information, for example, AI/RHEUM, 1993, has an VSAB of 'AIR93'."
        " Official source names, RSABs, and VSABs are included on the"
        " `UMLS Source Vocabulary Documentation page"
        " <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__.",
    )
    TTY = Column(String(40), nullable=False, doc="The term type.")
    CODE = Column(
        String(100), nullable=False, doc="The term code in the source"
    )
    RANK = Column(
        Integer,
        nullable=False,
        doc="The NLM defined top rank for the ``TTY``/``SAB``",
    )
    NAUI = Column(Integer, doc="The number of atoms that are in the CUIs")
    PROB_CUI = Column(
        Float,
        doc="The probability of randomly selecting this CUI from the MRCONSO"
        " able",
    )
    SEMANTIC_TYPES = Column(
        Text,
        doc="A pipe separated list of the semantic types associated "
        "with the concept",
    )

    ALL_AUIS = relationship(
        MrConso, primaryjoin="MrConso.CUI==UniqueUmlsCui.CUI"
    )

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self, exclude=["all_terms"])


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class TermIndexLookup(Base, orm_mixin.TermIndexLookupMixin):
    """A representation for the ``term_index_lookup`` table.

    Parameters
    ----------
    token_id : `int`
        Auto-incremented primary key.
    token_str : `str`
        The actual lookup string of the token.
    token_count `int`
        The total count of the token in the dataset.
    token_prob : `int`
        The prbability that the token is encountered in the dataset.
    token_index_map : `umls_tools.orm.TermIndexMap`
        The relationship back to the ``token_index_map`` table.
    """

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self, exclude=["all_terms"])


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class TermIndexMap(Base, orm_mixin.TermIndexMapMixinStr):
    """A representation of the ``term_index_mapping`` table.

    Parameters
    ----------
    mapping_id : `int`
        Auto-incremented primary key.
    token_id : `int`
        A mapping back to a specific token.
    start_pos : `int`
        The start position of the word represented by the token in the term
        string.
    end_pos : `int`
        The end position of the word represented by the token in the term
        string.
    rank_order : `int`
        The rank order position of the word represented by the token in the
        term string.
    term_len : `int`
        The length of the unprocessed term.
    term_id : `str`
        The ID for the term identifier.
    token_index_lookup : `umls_tools.orm.TermIndexLookup`
        The relationship back to the ``token_index_lookup`` table.
    """

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return print_orm_obj(self, exclude=["all_terms"])


# # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# class SrDef(Base):
#     """A representation of the SRDEF table.
#     """
#     __tablename__ = 'SRDEF'

#     SRDEF_IDX = Column(
#         Integer, primary_key=True, autoincrement=True,
#         doc="The auto increment primary key."
#     )
#     STYPE = Column(
#         String(3), nullable=False,
#         doc="The type of the code, semantic type (STY) or relationship (RL)"
#     )
#     TUI = Column(String(4), doc="")
#     STN = Column(String(50), doc="")
#     STN = Column(String(100), doc="")
#     DESC = Column(Text, doc="")

#     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#     def __repr__(self):
#         return print_orm_obj(self)


# # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# class MrCxt(Base):
#     """A representation of the MRCXI table, this is the contexts table.
#     """
#     __tablename__ = 'MRCXT'

#     MRCXT_IDX = Column(
#         Integer, primary_key=True, autoincrement=True,
#         doc="The auto increment primary key."
#     )
#     CUI = Column(String(8), doc="Concept identifier.")
#     SUI = Column(String(10), doc="Identifier of string used in this context")
#     AUI = Column(String(9), doc="Atom identifier.")
#     SAB = Column(
#         String(40), nullable=False,
#         doc="Abbreviated source name (SAB). Two source abbreviations are "
#         "assigned: Root Source Abbreviation (RSAB) — short form, no version"
#         " information, for example, AI/RHEUM, 1993, has an RSAB of 'AIR' "
#         "and versioned Source Abbreviation (VSAB) — includes version "
#         "information, for example, AI/RHEUM, 1993, has an VSAB of 'AIR93'."
#         " Official source names, RSABs, and VSABs are included on the"
#         " `UMLS Source Vocabulary Documentation page"
#         " <https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html>`__."
#     )
#     CODE = Column(String(100),
#                   doc="Unique identifier or code for string in that source")
#     CXN = Column(
#         Integer,
#         doc="The context number (if the atom has multiple contexts)"
#     )
#     CXL = Column(
#         String(3),
#         doc="Context member label, i.e., ANC for ancestor of this atom, CCP"
#         " for the atom itself, SIB for sibling of this atom, CHD for child of"
#         " this atom RNK	for rows with a CXL value of ANC, the rank of the"
#         " ancestors (e.g., a value of 1 denotes the most remote ancestor"
#         " in the hierarchy)"
#     )
#     MRCXTRANK = Column(Integer, doc="")
#     CXS = Column(Text, doc="String or concept name for context member")
#     CUI2 = Column(
#         String(8),
#         doc="Concept identifier of context member (may be empty if context"
#         " member is not yet in the Metathesaurus)"
#     )
#     AUI2 = Column(String(9), doc="Atom identifier of context member")
#     HCD = Column(
#         String(100),
#         doc="Source hierarchical number or code of context member (if present)"
#     )
#     RELA = Column(
#         String(100),
#         doc="Additional relationship label providing further "
#         "categorization of the CXL, if applicable and known. Valid values"
#         " listed on the Abbreviations Used in Data Elements"
#         " `page <http://www.nlm.nih.gov/research/umls/knowledge_sources/metathesaurus/release/abbreviations.html>`_")
#     XC = Column(
#         String(1),
#         doc="A plus (+) sign indicates that the CUI2 for this row has"
#         " children in this context. If this field is empty, the CUI2 does"
#         " not have children in this context."
#     )
#     CVF = Column(
#         Integer,
#         doc="Content View Flag. Bit field used to flag rows included in "
#         "content view."
#     )

#     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#     def __repr__(self):
#         return print_orm_obj(self)


CLASS_MAP = {
    "MRCOLS.RRF": (MrCols, True),
    "MRCONSO.RRF": (MrConso, True),
    "MRCUI.RRF": (MrCui, True),
    # 'MRCXT.RRF': (MrCxt, False),
    "MRDEF.RRF": (MrDef, True),
    "MRDOC.RRF": (MrDoc, True),
    "MRFILES.RRF": (MrFiles, True),
    "MRHIER.RRF": (MrHier, True),
    "MRHIST.RRF": (MrHist, True),
    "MRMAP.RRF": (MrMap, True),
    "MRRANK.RRF": (MrRank, True),
    "MRREL.RRF": (MrRel, True),
    "MRSAB.RRF": (MrSab, True),
    "MRSAT.RRF": (MrSat, True),
    "MRSMAP.RRF": (MrSmap, True),
    "MRSTY.RRF": (MrSty, True),
    "MRXNS_ENG.RRF": (MrXnsEng, True),
    "MRXNW_ENG.RRF": (MrXnwEng, True),
    "AMBIGSUI.RRF": (AmbigSui, True),
    "AMBIGLUI.RRF": (AmbigLui, True),
    "DELETEDCUI.RRF": (DeletedCui, False),
    "DELETEDLUI.RRF": (DeletedLui, False),
    "DELETEDSUI.RRF": (DeletedSui, False),
    "MERGEDCUI.RRF": (MergedCui, False),
    "MERGEDLUI.RRF": (MergedLui, False),
}
"""Mappings from table flat files names (keys to tuples of orm classes,
and is required) (`dict`)
"""
