Source code for loglan_core.word

"""
This module contains a basic Word Model.
"""

from __future__ import annotations

import datetime

from sqlalchemy import ForeignKey, JSON
from sqlalchemy.orm import mapped_column, Mapped
from sqlalchemy.orm import relationship

from .author import BaseAuthor
from .base import BaseModel
from .definition import BaseDefinition
from .event import BaseEvent
from .relationships import (
    t_connect_authors,
    t_connect_words,
)
from .service.annotated_types import str_008, str_064, str_128
from .service.table_names import T_NAME_EVENTS, T_NAME_TYPES, T_NAME_WORDS
from .type import BaseType


[docs] class BaseWord(BaseModel): """BaseWord model representing a word in the database. This class encapsulates the attributes and relationships associated with a word in the linguistic database. It serves as a foundational model for managing word data, including its origins, types, associated authors, definitions, and relationships with other words. The `BaseWord` class supports various attributes that provide detailed information about each word, including its name, origin, matching criteria, and associated events. It also establishes relationships with authors and definitions, allowing for efficient querying and management of linguistic data. Key Features: - Supports unique identification of words with an internal ID. - Allows for detailed information about the word's origin and matching criteria. - Facilitates relationships with authors, definitions, and other words (derivatives and parents). - Provides hybrid properties for easy access to specific types of derivatives (affixes and complexes). Examples: To create a new word instance: .. code-block:: python word_example = BaseWord( origin='3/3E word | 3/7S palabra | 2/5F parole', event_start_id=1, id=7418, id_old=7291, match='34%', name='purda', origin='3/3E word | 3/7S palabra | 2/5F parole', rank='1.0', type_id=9, year=datetime.date(1975, 1, 1) ) Attributes: id (int): Word's internal ID number. name (str_064): The name of the word. origin (str_128 | None): The origin of the word. origin_x (str_064 | None): Additional origin information. match (str_008 | None): Matching criteria for the word. rank (str_008 | None): Rank of the word. year (datetime.date | None): Year associated with the word. notes (dict[str, str] | None): Additional notes about the word. id_old (int): Legacy ID for compatibility with older databases. tid_old (int | None): Legacy TID for compatibility. type_id (int): Foreign key referencing the type of the word. event_start_id (int): Foreign key referencing the start event. event_end_id (int | None): Foreign key referencing the end event. authors (list[BaseAuthor]): List of authors associated with the word. definitions (list[BaseDefinition]): List of definitions for the word. derivatives (list[BaseWord]): List of words derived from this word. parents (list[BaseWord]): List of parent words of this word. """ __tablename__ = T_NAME_WORDS def __init__( # pylint: disable=too-many-positional-arguments self, id_old: Mapped[int], name: Mapped[str_064], type_id: Mapped[int], event_start_id: Mapped[int], event_end_id: Mapped[int] | None = None, tid_old: Mapped[int] | None = None, origin: Mapped[str_128] | None = None, origin_x: Mapped[str_064] | None = None, match: Mapped[str_008] | None = None, rank: Mapped[str_008] | None = None, year: Mapped[datetime.date] | None = None, notes: Mapped[dict] | None = None, ): """ Initializes a BaseWord instance. This constructor sets up a new word with the provided attributes. It is essential for creating instances of the `BaseWord` class, allowing for the storage of detailed information about each word in the database. Args: id_old (int): Legacy ID for compatibility with older databases. This field is required and cannot be null. name (str_064): The name of the word. This field is required and must be unique within the database. type_id (int): Foreign key referencing the type of the word. This field is required and establishes the relationship with the `BaseType` model. event_start_id (int): Foreign key referencing the start event associated with the word. This field is required. event_end_id (int | None, optional): Foreign key referencing the end event associated with the word. This field is optional and can be set to None if there is no end event. tid_old (int | None, optional): Legacy TID for compatibility with older databases. This field is optional and can be set to None. origin (str_128 | None, optional): The origin of the word. This field is optional and can be set to None if the origin is not known. origin_x (str_064 | None, optional): Additional origin information. This field is optional and can be set to None if no additional information is available. match (str_008 | None, optional): Matching criteria for the word. This field is optional and can be set to None if no specific matching criteria are defined. rank (str_008 | None, optional): Rank of the word. This field is optional and can be set to None if no rank is assigned. year (datetime.date | None, optional): Year associated with the word. This field is optional and can be set to None if the year is not specified. notes (dict | None, optional): Additional notes about the word, stored as a JSON-encoded dictionary. This field is optional and can be set to None if no notes are provided. """ super().__init__() self.id_old = id_old self.name = name self.type_id = type_id self.event_start_id = event_start_id self.event_end_id = event_end_id self.tid_old = tid_old self.origin = origin self.origin_x = origin_x self.match = match self.rank = rank self.year = year self.notes = notes
[docs] def __str__(self): """Returns a string representation of the BaseWord instance. Returns: str: A string representation of the BaseWord instance. """ return ( f"<{self.__class__.__name__}" f"{' ID ' + str(self.id) + ' ' if self.id else ' '}" f"{self.name}>" )
id: Mapped[int] = mapped_column(primary_key=True) """Word's internal ID number. This attribute serves as the primary key for the word in the database. It is an integer that uniquely identifies each word entry. - **Type**: int - **Nullable**: False """ name: Mapped[str_064] = mapped_column(nullable=False) """The name of the word. This attribute holds the actual word as a string. It is required and must be unique within the database. - **Type**: str_064 - **Max Length**: 64 characters - **Nullable**: False """ origin: Mapped[str_128 | None] """The origin of the word. This attribute provides information about the etymology or source of the word. It is optional and can be set to None if the origin is not known. - **Type**: str_128 | None - **Max Length**: 128 characters - **Nullable**: True """ origin_x: Mapped[str_064 | None] """Additional origin information. This attribute allows for any supplementary details regarding the word's origin. It is optional and can be set to None if no additional information is available. - **Type**: str_064 | None - **Max Length**: 64 characters - **Nullable**: True """ match: Mapped[str_008 | None] """Matching criteria for the word. This attribute defines any specific criteria used to match the word in queries or searches. It is optional and can be set to None if no matching criteria are defined. - **Type**: str_008 | None - **Max Length**: 8 characters - **Nullable**: True """ rank: Mapped[str_008 | None] """Rank of the word. This attribute indicates the importance or classification of the word within a specific context. It is optional and can be set to None if no rank is assigned. - **Type**: str_008 | None - **Max Length**: 8 characters - **Nullable**: True """ year: Mapped[datetime.date | None] """Year associated with the word. This attribute represents the year that is relevant to the word, such as the year it was coined or first recorded. It is optional and can be set to None if the year is not specified. - **Type**: datetime.date | None - **Nullable**: True """ notes: Mapped[dict[str, str] | None] = mapped_column(JSON) """Additional notes about the word. This attribute allows for the storage of any extra information or comments regarding the word, encoded as a JSON dictionary. It is optional and can be set to None if no notes are provided. - **Type**: dict[str, str] | None - **Nullable**: True """ # Field for legacy database compatibility id_old: Mapped[int] = mapped_column(nullable=False) """Legacy ID for compatibility with older databases. This attribute is used to maintain compatibility with previous versions of the database. It is required and cannot be null. - **Type**: int - **Nullable**: False """ tid_old: Mapped[int | None] = mapped_column("TID_old") """Legacy TID for compatibility. This attribute serves as a legacy identifier for compatibility with older database systems. It is optional and can be set to None. - **Type**: int | None - **Nullable**: True """ # Relationships type_id: Mapped[int] = mapped_column( "type", ForeignKey(f"{T_NAME_TYPES}.id"), nullable=False, ) """Foreign key referencing the type of the word. This attribute links the word to its type in the database, establishing a relationship with the `BaseType` model. It is required and cannot be null. - **Type**: int - **Nullable**: False """ type: Mapped[BaseType] = relationship( foreign_keys=[type_id], back_populates="words", lazy="joined", # required for proper loading affixes and complexes ) """Relationship to the BaseType model. This attribute establishes a relationship with the `BaseType` model, allowing access to the type associated with the word. It is populated based on the `type_id` foreign key, which links to the primary key of the `BaseType` table. - **Type**: BaseType - **Nullable**: False - **Back Population**: This relationship is bidirectional, allowing access to all words associated with a given type through the `words` attribute in the `BaseType` model. - **Loading Strategy**: The relationship uses a "joined" loading strategy, which means that the related `BaseType` instance is loaded in the same query as the `BaseWord` instance for efficiency. """ event_start_id: Mapped[int] = mapped_column( "event_start", ForeignKey(f"{T_NAME_EVENTS}.event_id"), nullable=False, ) """Foreign key referencing the start event. This attribute links the word to the event during which it was first recorded or used. It is required and cannot be null. - **Type**: int - **Nullable**: False """ event_start: Mapped[BaseEvent] = relationship( foreign_keys=[event_start_id], back_populates="appeared_words", ) """Relationship to the BaseEvent model for the start event. This attribute establishes a relationship with the `BaseEvent` model, allowing access to the event during which the word first appeared. It is automatically populated based on the `event_start_id`. - **Type**: BaseEvent - **Nullable**: False """ event_end_id: Mapped[int | None] = mapped_column( "event_end", ForeignKey( f"{T_NAME_EVENTS}.event_id", ), ) """Foreign key referencing the end event. This attribute links the word to the event during which it was deprecated or no longer in use. It is optional and can be set to None if there is no end event. - **Type**: int | None - **Nullable**: True """ event_end: Mapped[BaseEvent | None] = relationship( foreign_keys=[event_end_id], back_populates="deprecated_words", ) """Relationship to the BaseEvent model for the end event. This attribute establishes a relationship with the `BaseEvent` model, allowing access to the event during which the word was deprecated. It is automatically populated based on the `event_end_id`. - **Type**: BaseEvent | None - **Nullable**: True """ authors: Mapped[list[BaseAuthor]] = relationship( secondary=t_connect_authors, back_populates="contribution", ) """List of authors associated with the word. This attribute establishes a many-to-many relationship with the `BaseAuthor` model, allowing for the retrieval of all authors who have contributed to the word. It is populated based on the association table `t_connect_authors`. - **Type**: list[BaseAuthor] - **Nullable**: True """ definitions: Mapped[list[BaseDefinition]] = relationship( back_populates="source_word", cascade="all, delete-orphan", ) """List of definitions for the word. This attribute establishes a one-to-many relationship with the `BaseDefinition` model, allowing for the retrieval of all definitions associated with the word. It is populated based on the relationship defined in the `BaseDefinition` model. - **Type**: list[BaseDefinition] - **Nullable**: True """ # Word's derivatives derivatives: Mapped[list[BaseWord]] = relationship( secondary=t_connect_words, primaryjoin=(t_connect_words.c.parent_id == id), secondaryjoin=(t_connect_words.c.child_id == id), back_populates="parents", ) """List of words derived from this word. This attribute establishes a many-to-many relationship with other `BaseWord` instances, allowing for the retrieval of all words that are derived from the current word. It is populated based on the association table `t_connect_words`. - **Type**: list[BaseWord] - **Nullable**: True """ # Word's parents parents: Mapped[list[BaseWord]] = relationship( secondary=t_connect_words, primaryjoin=(t_connect_words.c.child_id == id), secondaryjoin=(t_connect_words.c.parent_id == id), back_populates="derivatives", ) """List of parent words of this word. This attribute establishes a many-to-many relationship with other `BaseWord` instances, allowing for the retrieval of all parent words from which the current word is derived. It is populated based on the association table `t_connect_words`. - **Type**: list[BaseWord] - **Nullable**: True """ @property def djifoa(self) -> list[BaseWord]: """List of djifoa (deprecated name 'affixes') derived from the word. This property filters the derivatives to return only those that are classified as djifoa. Returns: list[BaseWord]: A list of djifoa that are derived from the word. """ return list( filter(lambda child: child.type.type_x == "Affix", self.derivatives) ) affixes = djifoa """ List of djifoa derived from the word. Alias for `djifoa`, for backwards compatibility. """ @property def complexes(self) -> list[BaseWord]: """List of complexes derived from the word. This property filters the derivatives to return only those that are classified as complexes. Returns: list[BaseWord]: A list of complexes that are derived from the word. """ return list(filter(lambda child: child.type.group == "Cpx", self.derivatives))