unihan-db

SQLAlchemy models for the UNIHAN CJK character database. unihan-db provides the schema and ORM layer. For the ETL pipeline, see unihan-etl. For end-user character lookups, see cihai.

Most projects use unihan_db.bootstrap.get_session() or their own SQLAlchemy engine, load the data once with unihan_db.bootstrap.bootstrap_unihan(), and then query unihan_db.tables.Unhn and the tables that hang off it.

Quickstart

Install and load UNIHAN data in 5 minutes.

Quickstart
How-to Guides

Common tasks: custom databases, offline bootstraps, and ORM queries.

How-to Guides
Models & Bootstrap

Table models, bootstrap helpers, and importer internals.

API Reference
Explanation

How the ETL pipeline, bootstrap step, and ORM schema fit together.

Explanation
Contributing

Development setup, code style, release process.

Project

Install

$ pip install unihan-db
$ uv add unihan-db

At a glance

The same bootstrap example appears in the quickstart and is executed by the test suite.

#!/usr/bin/env python
"""Example for bootstrapping UNIHAN DB."""

from __future__ import annotations

import logging
import pprint

from sqlalchemy.sql.expression import func

from unihan_db import bootstrap
from unihan_db.tables import Unhn

log = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO, format="%(message)s")


def run(unihan_options: dict[str, object] | None = None) -> None:
    """Initialize Unihan DB via ``bootstrap_unihan()``."""
    session = bootstrap.get_session()

    bootstrap.bootstrap_unihan(session, unihan_options)

    random_row_query = session.query(Unhn).order_by(func.random()).limit(1)

    assert random_row_query is not None

    random_row = random_row_query.first()

    log.info(pprint.pformat(bootstrap.to_dict(random_row)))

    assert random_row is not None

    log.info(pprint.pformat(random_row.to_dict()))  # type:ignore


if __name__ == "__main__":
    run()

See Quickstart for the full setup, including bootstrapping data from the Unicode consortium.