-"""
-This module provides a base selector for SQLAlchemy
-"""
-
-fromtypingimportType,Iterable,Any
-
-fromsqlalchemyimportselect,Select
-fromsqlalchemy.ext.asyncioimportAsyncSession
-fromsqlalchemy.ormimportSession,InstrumentedAttribute,joinedload
-fromsqlalchemy.typesimportString,Integer
-fromtyping_extensionsimportSelf
-
-from..baseimportBaseModel
-
-
-
-[docs]
-classBaseSelector:# pylint: disable=too-many-ancestors
-"""
- A custom base selector that inherits from SQLAlchemy's Select class.
- This class provides methods to execute a session and fetch results
- in different ways. It also provides a way to fetch many results.
-
- Methods:
- --------
- execute(session: Session) -> ResultProxy:
- Executes the session and returns the result.
-
- all(session: Session) -> List[ResultRow]:
- Executes the session and returns all the results.
-
- scalar(session: Session) -> Any:
- Executes the session and returns a scalar result.
-
- fetchmany(session: Session, size: int | None = None) -> List[ResultRow]:
- Executes the session and fetches a specified number of results.
-
- """
-
- def__init__(
- self,
- model:Type[BaseModel],
- is_sqlite:bool=False,
- case_sensitive:bool=False,
- disable_model_check:bool=False,
- ):
-"""Initializes the Selector.
-
- Args:
- model (Type): The SQLAlchemy model class to select from.
- is_sqlite (bool): Flag indicating if the database is SQLite.
- case_sensitive (bool): Flag indicating if the queries should be case-sensitive.
- disable_model_check (bool): Flag indicating if the model check should be disabled.
- """
- self.disable_model_check=disable_model_check
- ifnotself.disable_model_check:
- self._is_model_accepted(model,BaseModel)
-
- self.model=model
- self._statement=select(self.model)
- self._selected_columns=[self.model]
-
- self.is_sqlite=is_sqlite
- self.case_sensitive=case_sensitive
-
-
-[docs]
- defselect_columns(self,*columns:type[BaseModel])->Self:
-"""Specify which columns to select without resetting the filters.
-
- Args:
- *columns: The columns to select.
-
- Returns:
- Self: The current instance for method chaining.
- """
- self._selected_columns=list(columns)
- existing_conditions=self._statement.whereclause
-
- ifexisting_conditionsisNone:
- self._statement=select(*self._selected_columns)
- else:
- self._statement=select(*self._selected_columns).where(existing_conditions)
- returnself
-
-
-
-[docs]
- deflimit(self,limit:int)->Self:
-"""Limit the number of results returned.
-
- Args:
- limit (int): The maximum number of results to return.
-
- Returns:
- Self: The current instance for method chaining.
- """
- self._statement=self._statement.limit(limit)
- returnself
-
-
-
-[docs]
- defoffset(self,offset:int)->Self:
-"""Set the offset for the results returned.
-
- Args:
- offset (int): The number of results to skip before starting to return results.
-
- Returns:
- Self: The current instance for method chaining.
- """
- self._statement=self._statement.offset(offset)
- returnself
-
-
-
-[docs]
- deforder_by(self,*columns)->Self:
-"""Specify the order in which results should be returned.
-
- Args:
- *columns: The columns to order by.
-
- Returns:
- Self: The current instance for method chaining.
- """
- self._statement=self._statement.order_by(*columns)
- returnself
-
-
-
-[docs]
- deffilter(self,*args)->Self:
-"""Filter results based on arbitrary keyword arguments.
-
- Args:
- *args: Column-value pairs to filter by.
-
- Returns:
- Self: The current instance for method chaining.
- """
-
- self._statement=self._statement.filter(*args)
-
- returnself
-
-
-
-[docs]
- deffilter_by(self,**kwargs)->Self:
-"""Filter results based on arbitrary keyword arguments.
-
- Args:
- *kwargs: Column-value pairs to filter by.
-
- Returns:
- Self: The current instance for method chaining.
- """
-
- self._statement=self._statement.filter_by(**kwargs)
-
- returnself
-
-
-
-[docs]
- defwhere(self,*args)->Self:
-"""Filter results based on arbitrary keyword arguments.
-
- Args:
- *args: Column-value pairs to filter by.
-
- Returns:
- Self: The current instance for method chaining.
- """
- self._statement=self._statement.where(*args)
- returnself
-
-
-
-[docs]
- defwhere_like(self,**kwargs)->Self:
-"""Filter results based on arbitrary keyword arguments.
- Use internal method `_generate_column_condition` to generate
- the condition based on settings provided by Selector instance
- like (is_sqlite, case_sensitive).
-
- Args:
- **kwargs: Column-value pairs to filter by.
-
- Returns:
- Self: The current instance for method chaining.
- """
- forkey,valueinkwargs.items():
- self._statement=self._statement.where(self.get_like_condition(key,value))
- returnself
-
-
-
-[docs]
- defget_like_condition(self,key:str|InstrumentedAttribute,value:Any):
-"""Generate the condition based on settings provided by Selector instance
- like (is_sqlite, case_sensitive).
-
- Args:
- key (str | InstrumentedAttribute): The key of the column to filter by.
- value (Any): The value to filter by.
-
- Returns:
- Condition: The SQLAlchemy condition to filter by.
- """
- column=self._get_column(key)
-
- ifnotisinstance(column.type,(String,Integer)):
- returncolumn==value
-
- ifisinstance(column.type,Integer):
- returncolumn==int(value)
-
- value=value.replace("*","%")
-
- ifnotself.case_sensitive:
- returncolumn.ilike(value)
-
- ifself.is_sqlite:
- returncolumn.op("GLOB")(value)
-
- returncolumn.like(value)
-
-
-
-[docs]
- defget_statement(self)->Select:
-"""Get the current SQLAlchemy _statement.
-
- Returns:
- Select: The current SQLAlchemy _statement.
- """
- returnself._statement
-
-
-
-[docs]
- defwith_relationships(self,selected:Iterable[str]|None=None)->Self:
-"""Adds relationships to the query.
-
- Args:
- selected (set[str]): A set of relationship names to include.
- Defaults to None if all relationships should be included.
-
- Returns:
- Self: A query with the relationships added.
- """
- available_relationships={
- attr:getattr(self.model,attr)forattrinself.model.relationships()
- }
- relationships={
- joinedload(v)
- fork,vinavailable_relationships.items()
- ifnotselectedorkinselected
- }
- self._statement=self._statement.options(*relationships)
- returnself
-
-
- @staticmethod
- def_is_model_accepted(model,parent:type[BaseModel]=BaseModel):
-"""Checks if the model is an instance of BaseModel or its child.
-
- Raises:
- ValueError: If the model is not an instance of BaseModel or its child.
- """
- ifnotissubclass(model,parent):
- raiseValueError(f"Provided model={model} is not a inherited from {parent}")
-
- def_get_column(self,key:str|InstrumentedAttribute)->InstrumentedAttribute:
-"""Get the column from the model.
-
- Args:
- key (str | InstrumentedAttribute): The key of the column to filter by.
-
- Raises:
- AttributeError: If the model has no attribute with the given key.
-
- Returns:
- InstrumentedAttribute: The SQLAlchemy column to filter by.
- """
- column=getattr(self.model,key,None)ifisinstance(key,str)elsekey
- ifcolumnisNone:
- raiseAttributeError(f"Model {self.model} has no attribute {key}")
- returncolumn
-
-
-[docs]
- defexecute(self,session:Session,unique:bool=False)->Any:
-"""Executes the given session and returns the result.
-
- Args:
- session (Session): SQLAlchemy Session object.
- unique (bool, optional): Flag indicating if the result should be unique.
- Defaults to False.
- Returns:
- ResultProxy: The result of the executed session.
- """
- result=session.execute(self._statement)
- returnresult.unique()ifuniqueelseresult
-
-
-
-[docs]
- defall(self,session:Session,unique:bool=False):
-"""Executes the given session and returns all the results as a list.
-
- Args:
- session (Session): SQLAlchemy Session object.
- unique (bool, optional): Flag indicating if the result should contain unique items.
- Defaults to False.
- Returns:
- List[ResultRow]: All the results of the executed session.
- """
- returnself.execute(session,unique).scalars().all()
-
-
-
-[docs]
- defscalar(self,session:Session):
-"""Executes the given session and returns a scalar result.
-
- Args:
- session (Session): SQLAlchemy Session object.
-
- Returns:
- Any: The scalar result of the executed session.
- """
- returnself.execute(session).scalar()
-
-
-
-[docs]
- deffetchmany(
- self,session:Session,size:int|None=None,unique:bool=False
- ):
-"""Executes the given session and fetches a specified number of results.
-
- Args:
- session (Session): SQLAlchemy Session object.
- size (int, optional): Number of results to fetch. If None, fetches all results.
- unique (bool, optional): Flag indicating if the result should contain unique items.
- Defaults to False.
- Returns:
- List[ResultRow]: The fetched results.
- """
- returnself.execute(session,unique).scalars().fetchmany(size)
-
-
-
-[docs]
- asyncdefexecute_async(self,session:AsyncSession,unique:bool=False):
-"""Executes the given session and returns the result.
-
- Args:
- session (AsyncSession): SQLAlchemy Session object.
- unique (bool, optional): Flag indicating if the result should be unique.
- Defaults to False.
- Returns:
- ResultProxy: The result of the executed session.
- """
- result=awaitsession.execute(self._statement)
- returnresult.unique()ifuniqueelseresult
-
-
-
-[docs]
- asyncdefall_async(self,session:AsyncSession,unique:bool=False):
-"""Executes the given session and returns all the results as a list.
-
- Args:
- session (AsyncSession): SQLAlchemy Session object.
- unique (bool, optional): Flag indicating if the result should contain unique items.
- Defaults to False.
- Returns:
- List[ResultRow]: All the results of the executed session.
- """
- result=awaitself.execute_async(session,unique)
- returnresult.scalars().all()
-
-
-
-[docs]
- asyncdefscalar_async(self,session:AsyncSession):
-"""Executes the given session and returns a scalar result.
-
- Args:
- session (AsyncSession): SQLAlchemy Session object.
-
- Returns:
- Any: The scalar result of the executed session.
- """
- result=awaitself.execute_async(session)
- returnresult.scalar()
-
-
-
-[docs]
- asyncdeffetchmany_async(
- self,session:AsyncSession,size:int|None=None,unique:bool=False
- ):
-"""Executes the given session and fetches a specified number of results.
-
- Args:
- session (AsyncSession): SQLAlchemy Session object.
- size (int, optional): Number of results to fetch. If None, fetches all results.
- unique (bool, optional): Flag indicating if the result should contain unique items.
- Defaults to False.
- Returns:
- List[ResultRow]: The fetched results.
- """
- result=awaitself.execute_async(session,unique)
- returnresult.scalars().fetchmany(size)
Source code for loglan_core.addons.definition_selector
-"""
-This module provides the DefinitionSelector class which is a Selector for the BaseDefinition object.
-
-The DefinitionSelector class allows for querying and filtering of BaseDefinition objects based on
-various parameters such as event, key, and language. It is a subclass of the Select class.
-
-Classes:
- DefinitionSelector: A selector model for the BaseDefinition object, it allows for querying and
- filtering of BaseDefinition objects.
-"""
-
-from__future__importannotations
-
-fromtypingimportType
-
-fromsqlalchemyimportselect,true
-fromtyping_extensionsimportSelf
-
-from.base_selectorimportBaseSelector
-from.utilsimport(
- filter_word_by_event_id,
- filter_key_by_word_cs,
- filter_key_by_language,
-)
-from..connect_tablesimportt_connect_keys
-from..definitionimportBaseDefinition
-from..keyimportBaseKey
-from..wordimportBaseWord
-
-
-
-[docs]
-classDefinitionSelector(BaseSelector):# pylint: disable=too-many-ancestors
-"""
- This class is a selector model for the BaseDefinition object. It allows for
- querying and filtering of BaseDefinition objects based on various parameters
- such as event, key, and language. It is a subclass of the Select class.
-
- Methods:
- __init__: Initializes the DefinitionSelector object.
- inherit_cache: Property that always returns True.
- by_event: Returns a new DefinitionSelector object filtered by a specific event.
- by_key: Returns a BaseQuery object filtered by a specific key.
- by_language: Returns a new DefinitionSelector object filtered by a specific language.
-
- Raises:
- ValueError: If the provided class_ is not a subclass of BaseDefinition.
-
- Attributes:
- model: The class to be used as the returned object.
- is_sqlite: Boolean specifying if the object is being used with SQLite or not.
- """
-
- def__init__(
- self,
- model:Type[BaseDefinition]=BaseDefinition,
- is_sqlite:bool=False,
- case_sensitive:bool=False,
- disable_model_check:bool=False,
- ):
-"""
- Initializes the DefinitionSelector object with the provided parameters.
-
- Args:
- model (Type[BaseDefinition]): The class to be used as the base key.
- Must be a subclass of BaseDefinition.
- is_sqlite (bool): If SQLite is being used. Defaults to False.
- case_sensitive (bool): If the queries should be case-sensitive.
- disable_model_check (bool): If the model check is disabled during initialization.
-
- Raises:
- ValueError: If the provided model is not a subclass of BaseDefinition.
- """
-
- super().__init__(model,is_sqlite,case_sensitive,disable_model_check)
- ifnotdisable_model_check:
- self._is_model_accepted(model,BaseDefinition)
-
- self.model=model
-
-
-[docs]
- defby_event(self,event_id:int|None=None)->DefinitionSelector:
-"""
- This method filters the definitions by the given event id.
-
- Parameters:
- event_id (int | None): The id of the event to filter by. If None,
- no event filtering is applied.
-
- Returns:
- DefinitionSelector: The filtered DefinitionSelector instance.
- """
- subquery=(
- select(self.model.id)
- .join(t_connect_keys)
- .join(BaseWord)
- .where(filter_word_by_event_id(event_id))
- .scalar_subquery()
- )
- self._statement=self._statement.where(self.model.id.in_(subquery))
- returnself
-
-
-
-[docs]
- defby_key(
- self,
- key:BaseKey|str,
- language:str|None=None,
- distinct:bool=False,
- )->Self:
-"""
- This method filters the definitions by the provided key, language and case sensitivity.
-
- Parameters:
- key (BaseKey | str): The key to filter by. Can be an instance of BaseKey or a string.
- language (str | None): The language to filter by.
- If None, no language filtering is applied.
- distinct (bool): If True, only distinct keys will be returned.
-
- Returns:
- Self: The filtered DefinitionSelector instance with distinct keys.
- """
-
- search_key=key.wordifisinstance(key,BaseKey)elsestr(key)
- filter_key=filter_key_by_word_cs(
- search_key,self.case_sensitive,self.is_sqlite
- )
- filter_language=filter_key_by_language(
- key.languageifisinstance(key,BaseKey)elselanguage
- )
-
- ifnothasattr(self.model,"keys"):
- raiseAttributeError(
- f"{self.model.__name__} does not have a 'keys' attribute"
- )
-
- self._statement=self._statement.join(self.model.keys).where(
- filter_key,filter_language
- )
-
- ifdistinct:
- self._statement=self._statement.distinct()
-
- returnself
-
-
-
-[docs]
- defby_language(self,language:str|None=None)->Self:
-"""
- This method filters the definitions by the given language.
-
- Parameters:
- language (str | None): The language to filter by. If None,
- no language filtering is applied.
-
- Returns:
- Self: The filtered DefinitionSelector instance.
- """
- ifhasattr(self.model,"language"):
- filter_language=self.model.language==languageiflanguageelsetrue()
- else:
- raiseAttributeError(
- f"{self.model.__name__} does not have a 'language' attribute"
- )
- self._statement=self._statement.where(filter_language)
-
- returnself
Source code for loglan_core.addons.export_word_converter
-"""
-This module contains ExportWordConverter for Word model of LOD.
-"""
-
-from..wordimportBaseWord
-
-
-
-[docs]
-classExportWordConverter:
-"""
- A class that provides conversion methods for exporting Word data.
-
- Args:
- word (BaseWord): The word to be converted.
-
- Properties:
- - e_source (str): Returns the source of the word.
- - e_year (str): Returns the year of the word, along with any additional notes.
- - e_usedin (str): Returns the names of the complexes in which the word is used.
- - e_affixes (str): Returns the affixes (djifoa) created from the word.
- - e_djifoa (str): Alias for the property `e_affixes`.
- - e_rank (str): Returns the rank of the word and any additional notes.
-
- Methods:
- - stringer(value) -> str: Convert a variable to a string.
-
- """
-
- def__init__(self,word:BaseWord):
- self.word=word
-
- @property
- defe_source(self)->str:
-"""
- Returns:
- """
- source="/".join(sorted([author.abbreviationforauthorinself.word.authors]))
- notes:dict[str,str]=self.word.notesor{}
-
- returnf"{source}{notes.get('author',str())}".strip()
-
- @property
- defe_year(self)->str:
-"""
- Returns the year of the word, along with any additional notes related to the year.
-
- Returns:
- str: The year of the word, along with any additional notes.
- If no year is available, an empty string is returned.
- """
- notes:dict[str,str]=self.word.notesor{}
- ifself.word.year:
- returnf"{self.word.year.year}{notes.get('year',str())}".strip()
- return""
-
- @property
- defe_usedin(self)->str:
-"""
- Returns a string that represents the names of the complexes in which the word is used.
-
- Returns:
- str: A string with the names of the complexes separated by a vertical bar.
- """
- return" | ".join(
- cpx.nameforcpxinself.word.derivativesifcpx.type.group=="Cpx"
- )
-
- @property
- defe_affixes(self)->str:
-"""
- Returns a string representation of the affixes (djifoa) created from the word.
-
- Returns:
- str: A string containing all affixes of the word with hyphens removed.
- """
- return" ".join(
- afx.name.replace("-","")
- forafxinself.word.derivatives
- ifafx.type.type_x=="Affix"
- ).strip()
-
- @property
- defe_djifoa(self)->str:
-"""
- Alias for the property `e_affixes`.
-
- Returns:
- str: The value of the property `e_affixes`.
- """
- returnself.e_affixes
-
- @property
- defe_rank(self)->str:
-"""
- Return the rank of the word and any additional notes about the rank.
-
- Returns:
- str: The rank of the word and any additional notes about the rank.
- """
- notes:dict[str,str]=self.word.notesor{}
- returnf"{self.word.rank}{notes.get('rank',str())}".strip()
-
-
-"""
-This module contains an "Export extensions" for LOD dictionary SQL model.
-Add export() function to db object for returning its text string presentation.
-"""
-
-fromtypingimportIterable,Callable,Type
-
-from..addons.export_word_converterimportExportWordConverter
-from..authorimportBaseAuthor
-from..definitionimportBaseDefinition
-from..eventimportBaseEvent
-from..settingimportBaseSetting
-from..syllableimportBaseSyllable
-from..typeimportBaseType
-from..wordimportBaseWord
-from..word_spellimportBaseWordSpell
-
-DEFAULT_SEPARATOR="@"
-
-
-
-[docs]
-classExporter:
-"""
- This class serves as a general exporter for various types of objects. The types of objects
- that can be exported include: BaseAuthor, BaseDefinition, BaseEvent, BaseSetting,
- BaseSyllable, BaseType, BaseWord, and BaseWordSpell. For each of these types of objects,
- there's an associated method that takes the object as an input and returns a formatted
- string suitable for export.
-
- Methods:
- export: The main method that uses a dictionary to map the type of the input object
- to the respective export method.
- export_author: Converts a BaseAuthor object to a tuple of items.
- export_definition: Converts a BaseDefinition object to a tuple of items.
- export_event: Converts a BaseEvent object to a tuple of items.
- export_setting: Converts a BaseSetting object to a tuple of items.
- export_syllable: Converts a BaseSyllable object to a tuple of items.
- export_type: Converts a BaseType object to a tuple of items.
- export_word: Converts a BaseWord object to a tuple of items.
- export_word_spell: Converts a BaseWordSpell object to a tuple of items.
-
- Raises:
- ValueError: If the object type is not supported for export.
- """
-
- FORMAT_DATE_EVENT="%m/%d/%Y"
- FORMAT_DATE_SETTING="%d.%m.%Y %H:%M:%S"
-
-
-[docs]
- @classmethod
- defexport(cls,obj,separator:str=DEFAULT_SEPARATOR)->str:
-"""
- Export the given object using the appropriate exporter function.
- Args:
- obj: The object to be exported.
- separator: The separator to be used in the exported string.
- Returns:
- The exported object.
- Raises:
- ValueError: If the object type is not supported.
- """
-
- exporters:dict[Type,Callable]={
- BaseAuthor:cls.export_author,
- BaseEvent:cls.export_event,
- BaseType:cls.export_type,
- BaseWordSpell:cls.export_word_spell,
- BaseWord:cls.export_word,
- BaseDefinition:cls.export_definition,
- BaseSetting:cls.export_setting,
- BaseSyllable:cls.export_syllable,
- }
-
- exporter_func=None
- forbase_class,funcinexporters.items():
- ifisinstance(obj,base_class):
- exporter_func=func
- break
-
- ifnotexporter_func:
- raiseValueError(f"Unsupported object type: {obj.__class__}")
-
- items=exporter_func(obj)
- returncls.merge_by(items,separator)
-
-
-
-[docs]
- @staticmethod
- defmerge_by(items:Iterable,separator:str=DEFAULT_SEPARATOR)->str:
-"""
- Merges a list of items into a single string, separated by the
- specified separator.
- Parameters:
- items (list): The list of items to merge.
- separator (str): The string to use as a separator, with a default
- value.
- Returns:
- str: The resulting string after joining the items.
- """
- returnseparator.join([str(ior"")foriinitems])
-
-
-
-[docs]
- @staticmethod
- defexport_author(obj:BaseAuthor)->tuple:
-"""
- Prepare Author data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- returnobj.abbreviation,obj.full_name,obj.notes
-
-
-
-[docs]
- @classmethod
- defexport_event(cls,obj:BaseEvent)->tuple:
-"""
- Prepare Event data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- return(
- obj.event_id,
- obj.name,
- obj.date.strftime(cls.FORMAT_DATE_EVENT),
- obj.definition,
- obj.annotation,
- obj.suffix,
- )
-
-
-
-[docs]
- @staticmethod
- defexport_syllable(obj:BaseSyllable)->tuple:
-"""
- Prepare Syllable data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- returnobj.name,obj.type_,str(obj.allowed)
-
-
-
-[docs]
- @classmethod
- defexport_setting(cls,obj:BaseSetting)->tuple:
-"""
- Prepare Setting data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- return(
- obj.date.strftime(cls.FORMAT_DATE_SETTING),
- obj.db_version,
- obj.last_word_id,
- obj.db_release,
- )
-
-
-
-[docs]
- @staticmethod
- defexport_type(obj:BaseType)->tuple:
-"""
- Prepare Type data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- return(
- obj.type_,
- obj.type_x,
- obj.group,
- str(obj.parentable),
- obj.description,
- )
-
-
-
-[docs]
- @staticmethod
- defexport_word(obj:BaseWord)->tuple:
-"""
- Prepare Word data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- ewc=ExportWordConverter(obj)
- match=ewc.stringer(obj.match)
- tid_old=ewc.stringer(obj.tid_old)
- origin_x=ewc.stringer(obj.origin_x)
- origin=ewc.stringer(obj.origin)
- return(
- obj.id_old,
- obj.type.type_,
- obj.type.type_x,
- ewc.e_affixes,
- match,
- ewc.e_source,
- ewc.e_year,
- ewc.e_rank,
- origin,
- origin_x,
- ewc.e_usedin,
- tid_old,
- )
-
-
-
-[docs]
- @staticmethod
- defexport_definition(obj:BaseDefinition)->tuple:
-"""
- Prepare Definition data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- e_grammar=f"{obj.slotsor''}{obj.grammar_codeor''}"
- return(
- obj.source_word.id_old,
- obj.position,
- obj.usage,
- e_grammar,
- obj.body,
- "",
- obj.case_tags,
- )
-
-
-
-[docs]
- @staticmethod
- defexport_word_spell(obj:BaseWordSpell)->tuple:
-"""
- Prepare WordSpell data for exporting to text file
-
- Returns:
- tuple: elements for export
- """
- code_name="".join(
- "0"ifsymbol.isupper()else"5"forsymbolinstr(obj.name)
- )
- return(
- obj.id_old,
- obj.name,
- obj.name.lower(),
- code_name,
- obj.event_start_id,
- obj.event_end_idifobj.event_endelse9999,
- "",
- )
-"""
-This module provides the `KeySelector` class, which inherits from `Select`
-and provides methods for filtering keys based on certain criteria.
-
-The KeySelector class has methods to filter keys by event ID, key, and language.
-Each method returns a new instance of KeySelector with the applied filters.
-
-The KeySelector class is initialized with a class object and a boolean
-indicating if it is being used with SQLite. The class object must be
-a subclass of BaseKey.
-
-Classes:
- KeySelector: A class used to select keys meeting certain criteria.
-
-Example:
- key_selector = KeySelector(MyKeyClass)
- filtered_by_event = key_selector.by_event(1)
- filtered_by_key = key_selector.by_key('mykey')
- filtered_by_language = key_selector.by_language('English')
-
-This allows for flexible and powerful querying of keys in a codebase.
-"""
-
-from__future__importannotations
-
-fromtypingimportType
-
-fromsqlalchemyimportselect
-
-from.base_selectorimportBaseSelector
-from.utilsimport(
- filter_word_by_event_id,
- filter_key_by_word_cs,
- filter_key_by_language,
-)
-from..connect_tablesimportt_connect_keys
-from..definitionimportBaseDefinition
-from..keyimportBaseKey
-from..wordimportBaseWord
-
-
-
-[docs]
-classKeySelector(BaseSelector):# pylint: disable=too-many-ancestors
-"""
- A class used to select keys meeting certain criteria.
-
- Attributes:
- model (Type[BaseKey]): The class to be used as the base key.
- Must be a subclass of BaseKey.
- is_sqlite (bool): If SQLite is being used. Defaults to False.
- case_sensitive (bool): If the queries should be case-sensitive.
- disable_model_check (bool): If the model check is disabled during initialization.
- """
-
- def__init__(
- self,
- model:Type[BaseKey]=BaseKey,
- is_sqlite:bool=False,
- case_sensitive:bool=False,
- disable_model_check:bool=False,
- )->None:
-"""
- Initializes the KeySelector object with the provided parameters.
-
- Args:
- model (Type[BaseKey]): The class to be used as the base key.
- Must be a subclass of BaseKey.
- is_sqlite (bool): If SQLite is being used. Defaults to False.
- case_sensitive (bool): If the queries should be case-sensitive.
- disable_model_check (bool): If the model check is disabled during initialization.
-
- Raises:
- ValueError: If the provided model is not a subclass of BaseKey.
- """
-
- super().__init__(model,is_sqlite,case_sensitive,disable_model_check)
-
- ifnotself.disable_model_check:
- self._is_model_accepted(model,BaseKey)
-
- self.model=model
-
-
-[docs]
- defby_event(self,event_id:int|None=None)->KeySelector:
-"""
- Filters the keys by the given event ID.
-
- Args:
- event_id (int | None): The identifier of the event to filter by.
- If None, no event filtering is applied.
-
- Returns:
- KeySelector: The filtered KeySelector instance.
- """
-
- subquery=(
- select(self.model.id)
- .join(t_connect_keys)
- .join(BaseDefinition)
- .join(BaseWord)
- .where(filter_word_by_event_id(event_id))
- .scalar_subquery()
- )
- self._statement=self._statement.where(self.model.id.in_(subquery))
- returnself
-
-
-
-[docs]
- defby_key(self,key:str)->KeySelector:
-"""
- Filters the keys by the given key.
-
- Args:
- key (str): The key to filter by.
-
- Returns:
- KeySelector: The filtered KeySelector instance.
- """
- self._statement=self._statement.where(
- filter_key_by_word_cs(key,self.case_sensitive,self.is_sqlite)
- )
- returnself
-
-
-
-[docs]
- defby_language(self,language:str|None=None)->KeySelector:
-"""
- Filters the keys by the given language.
-
- Args:
- language (str | None): The language to filter by.
- If None, no language filtering is applied.
-
- Returns:
- KeySelector: The filtered KeySelector instance.
- """
- self._statement=self._statement.where(filter_key_by_language(language))
- returnself
-
-
-
-[docs]
- defby_word_id(self,word_id:int,distinct:bool=False)->KeySelector:
-"""
- Filters the keys by the given word ID.
-
- Args:
- word_id (int): The identifier of the word to filter by.
- distinct (bool): If the query should be distinct. Defaults to False.
-
- Returns:
- KeySelector: The filtered KeySelector instance.
-
- Keep in mind that duplicated keys from related definitions
- will be counted with ```.count()``` but excluded from ```.all()``` request
-
- """
- self._statement=(
- self._statement.join(t_connect_keys)
- .join(BaseDefinition,BaseDefinition.id==t_connect_keys.c.DID)
- .join(BaseWord,BaseWord.id==BaseDefinition.word_id)
- .filter(BaseWord.id==word_id)
- .order_by(BaseKey.word.asc())
- )
-
- ifdistinct:
- self._statement=self._statement.distinct()
-
- returnself
-[docs]
-deffilter_word_by_event_id(event_id:int|None)->BooleanClauseList:
-"""
- Returns a filter condition to select words associated with a specific event.
-
- Args:
- event_id: The id of the event to filter by. Defaults to None.
-
- Returns:
- BooleanClauseList: A filter condition to select words associated with a specific event.
- """
- latest_id=select(func.max(BaseEvent.event_id)).scalar_subquery()
- event_id_filter=event_idorlatest_id
- start_id_condition=BaseWord.event_start_id<=event_id_filter
- end_id_condition=(
- BaseWord.event_end_id>event_id_filter
- )|BaseWord.event_end_id.is_(None)
- returnstart_id_condition&end_id_condition
-[docs]
-deffilter_key_by_language(language:str|None=None)->ColumnElement[bool]:
-"""
- Filter the language of the base key.
-
- Args:
- language (str or None): The language to filter by.
- If None, no language filter will be applied.
-
- Returns:
- ColumnElement[bool]: A filter condition for the base key's language.
- """
- return(BaseKey.language==language)iflanguageelsetrue()
-"""
-This module offers the ability to establish relationships
-between BaseWord instances and BaseAuthor instances.
-This is done via the WordLinker class which provides methods to check and add
-parent-child relationships between words and associate authors with words.
-"""
-
-from..authorimportBaseAuthor
-from..wordimportBaseWord
-
-
-
-[docs]
-classWordLinker:
-"""
- This class provides methods to manage parent-child
- relationships between words and to associate authors with words.
- """
-
-
-[docs]
- @classmethod
- defadd_child(cls,parent:BaseWord,child:BaseWord)->str:
-"""
- Associates a 'child' word with a 'parent' word,
- indicating that the child is derived from the parent.
-
- Args:
- parent (BaseWord): The original word.
- child (BaseWord): The word derived from the parent.
-
- Returns:
- str: The name of the child word.
-
- Raises:
- TypeError: If the child word is not parentable.
- """
-
- ifnotchild.type.parentable:
- raiseTypeError(f"{child} is not parentable")
-
- ifchildnotinparent.derivatives:
- parent.derivatives.append(child)
- returnchild.name
-
-
- # mark_as_parent_for
-
-[docs]
- @staticmethod
- defadd_children(parent:BaseWord,children:list[BaseWord]):
-"""
- Associates multiple 'children' words with a 'parent' word,
- indicating that those children are derived from the parent.
-
- Args:
- parent (BaseWord): The original word.
- children (list[BaseWord]): The words derived from the parent.
-
- Raises:
- TypeError: If any of the children words are not parentable.
- """
- new_children=list(set(children)-set(parent.derivatives))
-
- ifnotall(child.type.parentableforchildinnew_children):
- raiseTypeError(f"At least some of {new_children} are not parentable")
-
- ifnew_children:
- parent.derivatives.extend(new_children)
-
-
-
-[docs]
- @staticmethod
- defadd_author(word:BaseWord,author:BaseAuthor)->str:
-"""
- Associates an 'author' with a 'word', indicating
- that the author has contributed to the word.
-
- Args:
- word (BaseWord): The word to be associated with the author.
- author (BaseAuthor): The author to be associated with the word.
-
- Returns:
- str: The abbreviation of the author's name.
- """
- ifauthornotinword.authors:
- word.authors.append(author)
- returnauthor.abbreviation
-
-
-
-[docs]
- @staticmethod
- defadd_authors(word:BaseWord,authors:list[BaseAuthor]):
-"""
- Associates multiple 'authors' with a 'word',
- indicating that these authors have contributed to the word.
-
- Args:
- word (BaseWord): The word to be associated with the authors.
- authors (list[BaseAuthor]): The authors to be associated with the word.
- """
- new_authors=list(set(authors)-set(word.authors))
- ifnew_authors:
- word.authors.extend(new_authors)
-"""
-This module provides a mechanism to extract words
-from a database based on various criteria such as
-event, key, type, and name through the WordSelector class.
-"""
-
-from__future__importannotations
-
-fromtypingimportType
-
-fromsqlalchemyimportand_,select
-fromtyping_extensionsimportSelf
-
-from.base_selectorimportBaseSelector
-from.definition_selectorimportDefinitionSelector
-from.utilsimportfilter_word_by_event_id
-from..connect_tablesimportt_connect_words
-from..keyimportBaseKey
-from..typeimportBaseType
-from..wordimportBaseWord
-
-
-
-[docs]
-classWordSelector(BaseSelector):# pylint: disable=too-many-ancestors
-"""
- Class to extract words from a database based on various criteria.
-
- Extends the SQLAlchemy Select class to provide additional functionality.
- """
-
- def__init__(
- self,
- model:Type[BaseWord]=BaseWord,
- is_sqlite:bool=False,
- case_sensitive:bool=False,
- disable_model_check:bool=False,
- ):
-"""
- Initializes the WordSelector object with the provided parameters.
-
- Args:
- model (Type[BaseWord]): The class to be used as the base key.
- Must be a subclass of BaseWord.
- is_sqlite (bool): If SQLite is being used. Defaults to False.
- case_sensitive (bool): If the queries should be case-sensitive.
- disable_model_check (bool): If the model check is disabled during initialization.
-
- Raises:
- ValueError: If the provided model is not a subclass of BaseWord.
- """
-
- super().__init__(
- model=model,
- is_sqlite=is_sqlite,
- case_sensitive=case_sensitive,
- disable_model_check=disable_model_check,
- )
-
- ifnotself.disable_model_check:
- self._is_model_accepted(model,BaseWord)
-
- self.model=model
-
-
-[docs]
- defby_event(self,event_id:int|None=None)->Self:
-"""
- Applies a filter to select words associated with a specific event.
-
- Args:
- event_id (int | None): The id of the event to filter by. Defaults to None.
-
- Returns:
- Self: A query with the filter applied.
- """
- self._statement=self._statement.where(filter_word_by_event_id(event_id))
- returnself
-
-
-
-[docs]
- defby_name(
- self,
- name:str,
- )->Self:
-"""
- Applies a filter to select words by a specific name.
-
- Args:
- name (str): The name to filter by.
- Defaults to False.
- Returns:
- Self: A query with the filter applied.
- """
- ifhasattr(self.model,"name"):
- condition=self.get_like_condition(self.model.name,name)
- else:
- raiseAttributeError(
- f"{self.model.__name__} does not have a 'name' attribute"
- )
-
- self._statement=self._statement.where(condition)
- returnself
-
-
-
-[docs]
- defby_key(
- self,
- key:BaseKey|str,
- language:str|None=None,
- )->Self:
-"""
- Applies a filter to select words by a specific key.
-
- Args:
- key (BaseKey | str): The key to filter by.
- It can either be an instance of BaseKey or a string.
- language (str | None): The language of the key. Defaults to None.
- Defaults to False.
-
- Returns:
- Self: A query with the filter applied.
- """
-
- definition_query=DefinitionSelector(
- is_sqlite=self.is_sqlite,
- case_sensitive=self.case_sensitive,
- ).by_key(
- key=key,
- language=language,
- )
- subquery=select(definition_query.get_statement().subquery().c.word_id)
- self._statement=self._statement.where(self.model.id.in_(subquery))
- returnself
-
-
-
-[docs]
- defby_type(
- self,
- type_:BaseType|str|None=None,
- type_x:str|None=None,
- group:str|None=None,
- )->Self:
-"""
- Applies a filter to select words by a specific type.
-
- Args:
- type_ (BaseType | str | None): The type to filter by.
- It can either be an instance of BaseType, a string, or None.
- E.g. "2-Cpx", "C-Prim", "LW"
-
- type_x (str | None): The extended type to filter by. Defaults to None.
- E.g. "Predicate", "Name", "Affix"
-
- group (str | None): The group to filter by. Defaults to None.
- E.g. "Cpx", "Prim", "Little"
-
- Returns:
- Self: A query with the filter applied.
- """
- ifisinstance(type_,BaseType):
- self._statement=self._statement.join(BaseType).where(
- BaseType.id==type_.id
- )
- returnself
-
- type_values=(
- (BaseType.type_,type_),
- (BaseType.type_x,type_x),
- (BaseType.group,group),
- )
-
- type_filters=[
- i[0].ilike(str(i[1]).replace("*","%"))foriintype_valuesifi[1]
- ]
-
- ifnottype_filters:
- self._statement=self._statement
- returnself
-
- self._statement=self._statement.join(BaseType).where(and_(*type_filters))
- returnself
-
-
-
-[docs]
- defget_derivatives_of(self,word_id:int)->Self:
-"""
- Selects all words that are derived from the given word.
-
- Args:
- word_id (int): The id of the word to filter by.
-
- Returns:
- Self: A query with the filter applied.
- """
-
- derivative_ids_subquery=select(t_connect_words.c.child_id).where(
- t_connect_words.c.parent_id==word_id
- )
-
- self._statement=self._statement.where(
- self.model.id.in_(derivative_ids_subquery)
- )
- returnself
-
-
-
-[docs]
- defget_affixes_of(self,word_id:int)->Self:
-"""
- Selects all affixes that are derived from the given word.
-
- Args:
- word_id (int): The id of the word to filter by.
-
- Returns:
- Self: A query with the filter applied.
- """
- returnself.get_derivatives_of(word_id).by_type(type_x="Affix")
-
-
-
-[docs]
- defget_complexes_of(self,word_id:int)->Self:
-"""
- Selects all complexes that are derived from the given word.
-
- Args:
- word_id (int): The id of the word to filter by.
-
- Returns:
- Self: A query with the filter applied.
- """
- returnself.get_derivatives_of(word_id).by_type(group="Cpx")
-"""
-This module contains an addon for basic Word Model,
-which makes it possible to work with word's sources
-"""
-
-from__future__importannotations
-
-importre
-fromtypingimportIterable
-
-fromsqlalchemyimportselect,or_
-fromsqlalchemy.sql.selectableimportSelect
-
-from..typeimportBaseType
-from..wordimportBaseWord
-
-
-
-[docs]
- @classmethod
- defget_sources_cpx(
- cls,word:BaseWord,as_str:bool=False
- )->Select[tuple[BaseWord]]|list[str]:
-"""Extract source words from self.origin field accordingly
- Args:
- word (Word):
- as_str (bool): return Word objects if False else as simple str
- (Default value = False)
- Example:
- 'foldjacea' > ['forli', 'djano', 'cenja']
- Returns:
- List of words from which the self.name was created
-
- """
-
- ifnotword.type.group=="Cpx":
- return[]
-
- sources=cls._prepare_sources_cpx(word)
- returnsourcesifas_strelsecls.words_from_source_cpx(sources)
-[docs]
- @classmethod
- defget_sources_cpd(
- cls,word:BaseWord,as_str:bool=False
- )->Select[tuple[BaseWord]]|list[str]:
-"""Extract source words from self.origin field accordingly
-
- Args:
- word: Word:
- as_str: bool: return Word objects if False else as simple str
- (Default value = False)
-
- Returns:
- List of words from which the self.name was created
- """
-
- ifnotword.type.type_=="Cpd":
- return[]
-
- sources=cls._prepare_sources_cpd(word)
- returnsourcesifas_strelsecls.words_from_source_cpd(sources)
-[docs]
-classBaseAuthor(BaseModel):
-"""Base Author's DB Model
-
- Describes a table structure for storing information about word authors.
-
- This class connects with words using a "many-to-many" relationship using `t_connect_authors`.
-
- Examples:
- .. code-block:: python
-
- {
- 'id': 13, 'full_name': 'James Cooke Brown',
- 'abbreviation': 'JCB', 'notes': ''
- },
- {
- 'id': 29, 'full_name': 'Loglan 4&5', 'abbreviation': 'L4',
- 'notes': 'The printed-on-paper book, 1975 version of the dictionary.'
- }
-
- """
-
- __tablename__=T_NAME_AUTHORS
-
- def__init__(
- self,
- abbreviation:Mapped[str_064],
- full_name:Mapped[str_064|None],
- notes:Mapped[str_128|None],
- ):
-"""Initializes a BaseAuthor instance.
-
- Args:
- abbreviation (str): Author's abbreviation (used in the LOD dictionary).
- full_name (str, optional): Author's full name if it exists.
- notes (str, optional): Any additional information about the author.
- """
- super().__init__()
- self.abbreviation=abbreviation
- self.full_name=full_name
- self.notes=notes
-
- def__str__(self):
-"""Returns a string representation of the BaseAuthor instance.
-
- Returns:
- str: A string representing the instance with class name,
- author's ID (if available), and abbreviation.
- """
- return(
- f"<{self.__class__.__name__}"
- f"{' ID '+str(self.id)+' 'ifself.idelse' '}"
- f"{self.abbreviation}>"
- )
-
- abbreviation:Mapped[str_064]=mapped_column(nullable=False,unique=True)
-"""Author's abbreviation (used in the LOD dictionary).
-
- :type: :class:`~loglan_core.base.str_064` with max_length=64, nullable=False, unique=True
-
- Examples:
- ``JCB``, ``L4``
- """
-
- full_name:Mapped[str_064|None]
-"""Author's full name if it exists.
-
- :type: :class:`~loglan_core.base.str_064` with max_length=64, nullable=True, unique=False
-
- Examples:
- ``James Cooke Brown``, ``Loglan 4&5``
- """
-
- notes:Mapped[str_128|None]
-"""Additional information (notes) if it exists.
-
- :type: :class:`~loglan_core.base.str_128` with max_length=128, nullable=True, unique=False
- """
-
- contribution:Mapped[list[BaseWord]]=relationship(
- back_populates="authors",
- secondary=t_connect_authors,
- )
-"""
- This is a relationship that establishes a 'many-to-many'
- connection between the Author and his Words.
- It is done via the :class:`~loglan_core.connect_tables.t_connect_authors`
- secondary table and does not enable typechecks.
-
- Returns:
- Mapped[list[BaseWord]]: A list of BaseWord instances associated with the current instance.
- """
-# pylint: disable=invalid-name
-"""
-Initial common functions for LOD Model Classes
-"""
-from__future__importannotations
-
-fromdatetimeimportdatetime
-
-fromsqlalchemyimportString,inspect,func,select
-fromsqlalchemy.ext.asyncioimportAsyncAttrs
-fromsqlalchemy.ext.hybridimporthybrid_property
-fromsqlalchemy.ormimportDeclarativeBase,Mapped,mapped_column
-fromsqlalchemy.ormimportSession,registryasrg
-fromtyping_extensionsimportAnnotated
-
-str_008=Annotated[str,8]
-"""
-A custom type annotation that annotates a string with a metadata value
-of 8. It can be used to associate a string with the number 8 in certain
-contexts, such as specifying the length for a string field in a database.
-"""
-
-str_016=Annotated[str,16]
-"""
-A custom type annotation that annotates a string with a metadata value
-of 16. It can be used to associate a string with the number 16 in certain
-contexts, such as specifying the length for a string field in a database.
-"""
-
-str_032=Annotated[str,32]
-"""
-A custom type annotation that annotates a string with a metadata value
-of 32. It can be used to associate a string with the number 32 in certain
-contexts, such as specifying the length for a string field in a database.
-"""
-
-str_064=Annotated[str,64]
-"""
-A custom type annotation that annotates a string with a metadata value
-of 64. It can be used to associate a string with the number 64 in certain
-contexts, such as specifying the length for a string field in a database.
-"""
-
-str_128=Annotated[str,128]
-"""
-A custom type annotation that annotates a string with a metadata value
-of 128. It can be used to associate a string with the number 128 in certain
-contexts, such as specifying the length for a string field in a database.
-"""
-
-str_255=Annotated[str,255]
-"""
-A custom type annotation that annotates a string with a metadata value
-of 255. It can be used to associate a string with the number 255 in certain
-contexts, such as specifying the length for a string field in a database.
-"""
-
-
-
-[docs]
-classBaseModel(AsyncAttrs,DeclarativeBase):
-"""
- BaseModel is a subclass of DeclarativeBase. It serves as the parent class
- for other database models, providing common attributes and methods to its
- child classes. It doesn't contain any class-specific attributes/methods.
- """
-
- registry=rg(
- type_annotation_map={
- str_008:String(8),
- str_016:String(16),
- str_032:String(32),
- str_064:String(64),
- str_128:String(128),
- str_255:String(255),
- }
- )
-"""
- This code creates a registry that maps custom type annotations to
- SQLAlchemy String types with specified lengths. The keys are custom
- type annotation names and the values are SQLAlchemy String types with
- the specified lengths.
- """
-
- __abstract__=True
-"""
- A class attribute that indicates that this class is an abstract base
- class. When set to True, this class won't be mapped to any database
- table. Instead, it serves as a base for other classes which will be
- mapped to tables.
- """
-
- id:Mapped[int]=mapped_column(primary_key=True)
-"""
- A class attribute mapped to a column in the database table. It serves as
- the primary key for the table.
-
- :type: int
- """
-
- created:Mapped[datetime]=mapped_column(default=datetime.now(),nullable=False)
-"""
- A class attribute mapped to a column in the database table. It represents
- the timestamp when a row is created. The default value is the current
- timestamp, and it can't be null.
-
- :type: datetime
- """
-
- updated:Mapped[datetime|None]=mapped_column(
- onupdate=func.now()# pylint: disable=E1102
- )
-"""
- A class attribute mapped to a column in the database table. It represents
- the timestamp when a row is last updated. Whenever the row is updated,
- this timestamp is automatically set to the current time. It can be ``null``
- if the row has never been updated.
-
- :type: datetime
- """
-
- def__repr__(self):
-"""
- Special method that returns a string representation of the object.
- It forms the string by joining key-value pairs of the object's attributes,
- excluding keys that start with "_" and keys that are "created" or "updated".
- The key-value pairs are sorted before joining.
-
- Returns:
- str: A string representation of the object in the format:
- "ClassName(key1=value1, key2=value2, ...)".
- """
- obj_str=", ".join(
- sorted(
- [
- f"{k}={v!r}"
- fork,vinself.__dict__.items()
- ifself._filter_add_to_repr(k,v)
- ]
- )
- )
- returnf"{self.__class__.__name__}({obj_str})"
-
- @classmethod
- def_filter_add_to_repr(cls,k,v):
-"""
- Static method that filters out keys that start with "_" and keys
- that are "created" or "updated" and keys without values from the
- object's attributes. The method is used to generate a string
- representation of the object. It is used internally by the __repr__.
- """
- return(
- notk.startswith("_")
- andknotin["created","updated",*cls.relationships()]
- andv
- )
-
-
-[docs]
- @classmethod
- defget_by_id(cls,session:Session,cid:int):
-"""
- Class method that retrieves an instance of the class from the
- database using the provided session and id.
-
- Parameters:
- session (Session): The session to use for the database query.
- cid (int): The id of the instance to retrieve.
-
- Returns:
- Object of class type or None: The instance of the class with
- the given id, or None if no such instance exists.
- """
- returnsession.get(cls,cid)
-
-
-
-[docs]
- @classmethod
- defget_all(cls,session:Session):
-"""
- Class method that retrieves all instances of the class from the
- database using the provided session.
-
- Parameters:
- session (Session): The session to use for the database query.
-
- Returns:
- list: A list of all instances of the class.
- """
- returnsession.scalars(select(cls)).all()
-
-
-
-[docs]
- defexport(self):
-"""
- Class method that exports the object's attributes into a dictionary.
- It filters out keys that start with "_" and keys that are
- "created" or "updated", then sorts the remaining keys.
-
- Returns:
- dict: A dictionary with sorted keys and corresponding
- values of the object's attributes.
- """
- return{
- k:v
- fork,vinsorted(self.__dict__.items())
- ifnotstr(k).startswith("_")
- andknotin["created","updated",*self.relationships()]
- }
-
-
-
-[docs]
- @classmethod
- defattributes_all(cls)->set[str]:
-"""
- Class method that computes the all attribute keys from the class
- mapper and returns their names as a set.
-
- It doesn't require any parameters as it operates on the class itself.
-
- Returns:
- set[str]: A set of strings with names of all attribute keys.
- """
- returnset(cls.__mapper__.attrs.keys())|cls.hybrid_properties()
-
-
-
-[docs]
- @classmethod
- defattributes_basic(cls)->set[str]:
-"""
- Class method that computes the set of basic attributes for the class.
- It subtracts any relationships from all attributes.
-
- It doesn’t require any parameters as it operates on the class itself.
-
- Returns:
- set[str]: A set of strings with names of basic attributes.
- """
- returnset(cls.attributes_all()-cls.relationships()-cls.hybrid_properties())
-
-
-
-[docs]
- @classmethod
- defattributes_extended(cls)->set[str]:
-"""
- Class method that computes the extended attributes of the class.
- It does this by subtracting foreign keys from all attributes.
-
- It doesn’t require any parameters as it operates on the class itself.
-
- Returns:
- set[str]: A set of strings with names of the extended attributes.
- """
- returnset(cls.attributes_all()-cls.foreign_keys())
-
-
-
-[docs]
- @classmethod
- defrelationships(cls)->set[str]:
-"""
- Class method that computes the relationship names from the
- class mapper and returns them as a set.
-
- It doesn't require any parameters as it operates on the class itself.
-
- Returns:
- set[str]: A set of strings with names of the relationships.
- """
- returnset(cls.__mapper__.relationships.keys())
-
-
-
-[docs]
- @classmethod
- defforeign_keys(cls)->set[str]:
-"""
- Class method that computes the names of foreign keys of the class.
- It does this by subtracting relationship keys and non-foreign keys
- from all attributes.
-
- It doesn’t require any parameters as it operates on the class itself.
-
- Returns:
- set[str]: A set of strings with names of the foreign keys.
- """
- returnset(
- cls.attributes_all()
- -cls.relationships()
- -cls.non_foreign_keys()
- -cls.hybrid_properties()
- )
-
-
-
-[docs]
- @classmethod
- defnon_foreign_keys(cls)->set[str]:
-"""
- Class method that computes the non-foreign keys of the class.
- It does this by inspecting the class columns and selecting those
- without foreign keys.
-
- It doesn’t require any parameters as it operates on the class itself.
-
- Returns:
- set[str]: A set of strings with names of the non-foreign keys.
- """
- inspector=inspect(cls)
- columns=inspector.columns
- non_foreign_keys={
- column.nameforcolumnincolumnsifnotcolumn.foreign_keys
- }
- returnnon_foreign_keys
-
-
-
-[docs]
- @classmethod
- defhybrid_properties(cls)->set[str]:
-"""
- Class method that computes the hybrid properties of the class.
-
- It doesn’t require any parameters as it operates on the class itself.
-
- Returns:
- set[str]: A set of strings with names of the hybrid properties.
- """
- inspector=inspect(cls).all_orm_descriptors
- return{i.__name__foriininspectorifisinstance(i,hybrid_property)}
-[docs]
-classBaseDefinition(BaseModel):
-"""
- The BaseDefinition model.
-
- Attributes:
- word_id (Mapped[int]): The ID of the word.
- position (Mapped[int]): The position of the word.
- body (Mapped[str]): The body of the word.
- usage (Mapped[str_064] | None): The usage of the word.
- grammar_code (Mapped[str_008] | None): The grammar code of the word.
- slots (Mapped[int] | None): The slots of the word.
- case_tags (Mapped[str_016] | None): The case tags of the word.
- language (Mapped[str_016] | None): The language of the word.
- notes (Mapped[str_255] | None): The notes of the word.
- APPROVED_CASE_TAGS (tuple): A tuple of approved case tags.
- KEY_PATTERN (str): The pattern for the key.
- keys (Mapped[list[BaseKey]]): The relationship of keys.
- source_word (Mapped["BaseWord"]): The relationship of source word.
-
- """
-
- __tablename__=T_NAME_DEFINITIONS
-
- def__init__(# pylint: disable=too-many-positional-arguments
- self,
- word_id:Mapped[int],
- position:Mapped[int],
- body:Mapped[str],
- usage:Mapped[str_064]|None=None,
- grammar_code:Mapped[str_008]|None=None,
- slots:Mapped[int]|None=None,
- case_tags:Mapped[str_016]|None=None,
- language:Mapped[str_016]|None=None,
- notes:Mapped[str_255]|None=None,
- ):
- super().__init__()
- self.word_id=word_id
- self.position=position
- self.usage=usage
- self.grammar_code=grammar_code
- self.slots=slots
- self.case_tags=case_tags
- self.body=body
- self.language=language
- self.notes=notes
-
- def__str__(self):
-"""
- String representation of the BaseDefinition object.
-
- Returns:
- str: A string representation of the object.
- """
- return(
- f"<{self.__class__.__name__}"
- f" ID {str(self.id)}/{self.word_id}{self.body[:20]}…>"
- )
-
- word_id:Mapped[int]=mapped_column(
- ForeignKey(f"{T_NAME_WORDS}.id"),nullable=False
- )
- position:Mapped[int]=mapped_column(nullable=False)
- body:Mapped[str]=mapped_column(Text,nullable=False)
- usage:Mapped[str_064|None]
- grammar_code:Mapped[str_008|None]
- slots:Mapped[int|None]
- case_tags:Mapped[str_016|None]
- language:Mapped[str_016|None]
- notes:Mapped[str_255|None]
-
- APPROVED_CASE_TAGS=("B","C","D","F","G","J","K","N","P","S","V")
- KEY_PATTERN=r"(?<=\«)(.+?)(?=\»)"
-
- keys:Mapped[list[BaseKey]]=relationship(
- BaseKey,
- secondary=t_connect_keys,
- back_populates="definitions",
- )
-
- source_word:Mapped[BaseWord]=relationship(
- "BaseWord",
- back_populates="definitions",
- )
-
- @property
- defgrammar(self)->str:
-"""
- Combine definition's 'slots' and 'grammar_code' attributes.
-
- Returns:
- String with grammar data like (3v) or (2n), or an empty string if both are None.
- """
- sl_str=self.slotsor""
- gr_str=self.grammar_codeor""
- returnf"({sl_str}{gr_str})"ifsl_strorgr_strelse""
-"""
-This module contains a basic Key Model
-"""
-
-from__future__importannotations
-
-fromtypingimportTYPE_CHECKING
-
-fromsqlalchemyimportUniqueConstraint
-fromsqlalchemy.ormimportmapped_column,Mapped
-fromsqlalchemy.ormimportrelationship
-
-from.baseimportBaseModel,str_016,str_064
-from.connect_tablesimportt_connect_keys
-from.table_namesimportT_NAME_KEYS
-
-ifTYPE_CHECKING:
- from.definitionimportBaseDefinition
-
-__pdoc__={
- "BaseKey.definitions":"""
- *Relationship query for getting a list of definitions related to this key*
-
- **query** : Optional[List[BaseDefinition]]""",
- "BaseKey.created":False,
- "BaseKey.updated":False,
-}
-
-
-
-[docs]
-classBaseKey(BaseModel):
-"""Base Key's DB Model
-
- Describes a table structure for storing information
- about keywords of the word's definitions.
- Some keywords could belong to many definitions
- and some definitions could have many keywords.
- That's why the relationship between Key
- and Definition should be many-to-many. See `t_connect_keys`.
-
- There is additional `word_language` UniqueConstraint here.
-
- <details><summary>Show Examples</summary><p>
- ```python
- {'language': 'en', 'word': 'aura', 'id': 1234}
-
- {'language': 'en', 'word': 'emotionality', 'id': 4321}
- ```
- </p></details>
- """
-
- __tablename__=T_NAME_KEYS
- __table_args__=(UniqueConstraint("word","language",name="_word_language_uc"),)
-
- def__init__(self,word,language):
- super().__init__()
- self.word=word
- self.language=language
-
- def__str__(self):
- returnf"<{self.__class__.__name__}{self.id} '{self.word}' ({self.language})>"
-
- word:Mapped[str_064]=mapped_column(nullable=False)
-"""*Key's vernacular word*
- **str** : max_length=64, nullable=False, unique=False
- It is non-unique, as words can be the same in spelling in different languages"""
- language:Mapped[str_016]=mapped_column(nullable=False)
-"""*Key's language*
- **str** : max_length=16, nullable=False, unique=False"""
-
- definitions:Mapped[list[BaseDefinition]]=relationship(
- secondary=t_connect_keys,
- back_populates="keys",
- )
A custom base selector that inherits from SQLAlchemy’s Select class.
-This class provides methods to execute a session and fetch results
-in different ways. It also provides a way to fetch many results.
Executes the given session and returns all the results as a list.
-
-
Args:
session (AsyncSession): SQLAlchemy Session object.
-unique (bool, optional): Flag indicating if the result should contain unique items.
-Defaults to False.
-
-
Returns:
List[ResultRow]: All the results of the executed session.
Executes the given session and fetches a specified number of results.
-
-
Args:
session (Session): SQLAlchemy Session object.
-size (int, optional): Number of results to fetch. If None, fetches all results.
-unique (bool, optional): Flag indicating if the result should contain unique items.
-Defaults to False.
Executes the given session and fetches a specified number of results.
-
-
Args:
session (AsyncSession): SQLAlchemy Session object.
-size (int, optional): Number of results to fetch. If None, fetches all results.
-unique (bool, optional): Flag indicating if the result should contain unique items.
-Defaults to False.
Filter results based on arbitrary keyword arguments.
Use internal method _generate_column_condition to generate
-the condition based on settings provided by Selector instance
-like (is_sqlite, case_sensitive).
This module provides the DefinitionSelector class which is a Selector for the BaseDefinition object.
-
The DefinitionSelector class allows for querying and filtering of BaseDefinition objects based on
-various parameters such as event, key, and language. It is a subclass of the Select class.
-
-
Classes:
DefinitionSelector: A selector model for the BaseDefinition object, it allows for querying and
-filtering of BaseDefinition objects.
This class is a selector model for the BaseDefinition object. It allows for
-querying and filtering of BaseDefinition objects based on various parameters
-such as event, key, and language. It is a subclass of the Select class.
-
-
Methods:
__init__: Initializes the DefinitionSelector object.
-inherit_cache: Property that always returns True.
-by_event: Returns a new DefinitionSelector object filtered by a specific event.
-by_key: Returns a BaseQuery object filtered by a specific key.
-by_language: Returns a new DefinitionSelector object filtered by a specific language.
-
-
Raises:
ValueError: If the provided class_ is not a subclass of BaseDefinition.
-
-
Attributes:
model: The class to be used as the returned object.
-is_sqlite: Boolean specifying if the object is being used with SQLite or not.
This method filters the definitions by the provided key, language and case sensitivity.
-
-
Parameters:
key (BaseKey | str): The key to filter by. Can be an instance of BaseKey or a string.
-language (str | None): The language to filter by.
-If None, no language filtering is applied.
-distinct (bool): If True, only distinct keys will be returned.
-
-
Returns:
Self: The filtered DefinitionSelector instance with distinct keys.
This module contains an “Export extensions” for LOD dictionary SQL model.
-Add export() function to db object for returning its text string presentation.
This class serves as a general exporter for various types of objects. The types of objects
-that can be exported include: BaseAuthor, BaseDefinition, BaseEvent, BaseSetting,
-BaseSyllable, BaseType, BaseWord, and BaseWordSpell. For each of these types of objects,
-there’s an associated method that takes the object as an input and returns a formatted
-string suitable for export.
-
-
Methods:
-
export: The main method that uses a dictionary to map the type of the input object
to the respective export method.
-
-
-
export_author: Converts a BaseAuthor object to a tuple of items.
-export_definition: Converts a BaseDefinition object to a tuple of items.
-export_event: Converts a BaseEvent object to a tuple of items.
-export_setting: Converts a BaseSetting object to a tuple of items.
-export_syllable: Converts a BaseSyllable object to a tuple of items.
-export_type: Converts a BaseType object to a tuple of items.
-export_word: Converts a BaseWord object to a tuple of items.
-export_word_spell: Converts a BaseWordSpell object to a tuple of items.
-
-
Raises:
ValueError: If the object type is not supported for export.
This module provides the KeySelector class, which inherits from Select
-and provides methods for filtering keys based on certain criteria.
-
The KeySelector class has methods to filter keys by event ID, key, and language.
-Each method returns a new instance of KeySelector with the applied filters.
-
The KeySelector class is initialized with a class object and a boolean
-indicating if it is being used with SQLite. The class object must be
-a subclass of BaseKey.
-
-
Classes:
KeySelector: A class used to select keys meeting certain criteria.
A class used to select keys meeting certain criteria.
-
-
Attributes:
-
model (Type[BaseKey]): The class to be used as the base key.
Must be a subclass of BaseKey.
-
-
-
is_sqlite (bool): If SQLite is being used. Defaults to False.
-case_sensitive (bool): If the queries should be case-sensitive.
-disable_model_check (bool): If the model check is disabled during initialization.
This module offers the ability to establish relationships
-between BaseWord instances and BaseAuthor instances.
-This is done via the WordLinker class which provides methods to check and add
-parent-child relationships between words and associate authors with words.
This module provides a mechanism to extract words
-from a database based on various criteria such as
-event, key, type, and name through the WordSelector class.
Applies a filter to select words by a specific key.
-
-
Args:
key (BaseKey | str): The key to filter by.
-It can either be an instance of BaseKey or a string.
-language (str | None): The language of the key. Defaults to None.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
BaseModel is a subclass of DeclarativeBase. It serves as the parent class
-for other database models, providing common attributes and methods to its
-child classes. It doesn’t contain any class-specific attributes/methods.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
Class method that exports the object’s attributes into a dictionary.
-It filters out keys that start with “_” and keys that are
-“created” or “updated”, then sorts the remaining keys.
-
-
Returns:
dict: A dictionary with sorted keys and corresponding
-values of the object’s attributes.
Class method that computes the names of foreign keys of the class.
-It does this by subtracting relationship keys and non-foreign keys
-from all attributes.
-
It doesn’t require any parameters as it operates on the class itself.
-
-
Returns:
set[str]: A set of strings with names of the foreign keys.
This code creates a registry that maps custom type annotations to
-SQLAlchemy String types with specified lengths. The keys are custom
-type annotation names and the values are SQLAlchemy String types with
-the specified lengths.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
A custom type annotation that annotates a string with a metadata value
-of 8. It can be used to associate a string with the number 8 in certain
-contexts, such as specifying the length for a string field in a database.
A custom type annotation that annotates a string with a metadata value
-of 16. It can be used to associate a string with the number 16 in certain
-contexts, such as specifying the length for a string field in a database.
A custom type annotation that annotates a string with a metadata value
-of 32. It can be used to associate a string with the number 32 in certain
-contexts, such as specifying the length for a string field in a database.
A custom type annotation that annotates a string with a metadata value
-of 64. It can be used to associate a string with the number 64 in certain
-contexts, such as specifying the length for a string field in a database.
A custom type annotation that annotates a string with a metadata value
-of 128. It can be used to associate a string with the number 128 in certain
-contexts, such as specifying the length for a string field in a database.
A custom type annotation that annotates a string with a metadata value
-of 255. It can be used to associate a string with the number 255 in certain
-contexts, such as specifying the length for a string field in a database.
sqlalchemy.sql.schema.Table: Maps authors to their words in the database.
-
This table creates a many-to-many relationship between authors and their words.
-Each row represents a word that is associated with an author.
-
-
Variables:
T_NAME_CONNECT_AUTHORS (str): The name of the table.
-Column(“AID”, ForeignKey(f”{T_NAME_AUTHORS}.id”), primary_key=True):
-The ID column for the author.
-Column(“WID”, ForeignKey(f”{T_NAME_WORDS}.id”), primary_key=True): The ID column for the word.
-Index(“index_AID”, “AID”): An index on the “AID” column to enhance query performance.
-Index(“index_WID”, “WID”): An index on the “WID” column to enhance query performance.
sqlalchemy.sql.schema.Table: Maps definitions to their keys in the database.
-
This table creates a many-to-many relationship between definitions and their keys.
-Each row represents a definition that is associated with a key.
-
-
Variables:
T_NAME_CONNECT_KEYS (str): The name of the table.
-Column(“KID”, ForeignKey(f”{T_NAME_KEYS}.id”), primary_key=True):
-The ID column for the key.
-Column(“DID”, ForeignKey(f”{T_NAME_DEFINITIONS}.id”), primary_key=True):
-The ID column for the definition.
-Index(“index_KID”, “KID”): An index on the “KID” column to enhance query performance.
-Index(“index_DID”, “DID”): An index on the “DID” column to enhance query performance.
sqlalchemy.sql.schema.Table: Maps parent words to their child words in the database.
-
This table creates a many-to-many relationship between parent words and child words.
-Each row represents a child word that is associated with a parent word.
-
-
Variables:
T_NAME_CONNECT_WORDS (str): The name of the table.
-Column(“parent_id”, ForeignKey(f”{T_NAME_WORDS}.id”), primary_key=True):
-The ID column for the parent word.
-Column(“child_id”, ForeignKey(f”{T_NAME_WORDS}.id”), primary_key=True):
-The ID column for the child word.
-Index(“index_parent_id”, “parent_id”): An index on the “parent_id”
-column to enhance query performance.
-Index(“index_child_id”, “child_id”): An index on the “child_id”
-column to enhance query performance.
word_id (Mapped[int]): The ID of the word.
-position (Mapped[int]): The position of the word.
-body (Mapped[str]): The body of the word.
-usage (Mapped[str_064] | None): The usage of the word.
-grammar_code (Mapped[str_008] | None): The grammar code of the word.
-slots (Mapped[int] | None): The slots of the word.
-case_tags (Mapped[str_016] | None): The case tags of the word.
-language (Mapped[str_016] | None): The language of the word.
-notes (Mapped[str_255] | None): The notes of the word.
-APPROVED_CASE_TAGS (tuple): A tuple of approved case tags.
-KEY_PATTERN (str): The pattern for the key.
-keys (Mapped[list[BaseKey]]): The relationship of keys.
-source_word (Mapped[“BaseWord”]): The relationship of source word.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
{‘suffix’: ‘RDC’, ‘definition’: ‘parsed all the words in the dictionary,
-identified ones that the parser did not recognize as words’,
-‘date’: datetime.date(2016, 1, 15), ‘annotation’: ‘Randall Cleanup’,
-‘name’: ‘Randall Dictionary Cleanup’, ‘id’: 5}
-```
-</p></details>
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
Describes a table structure for storing information
-about keywords of the word’s definitions.
-Some keywords could belong to many definitions
-and some definitions could have many keywords.
-That’s why the relationship between Key
-and Definition should be many-to-many. See t_connect_keys.
-
There is additional word_language UniqueConstraint here.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
Hybrid property that returns a list of affixes that are derived from the word.
-
This property is a hybrid of a Python property and a SQLAlchemy expression.
-It can be used as a property in Python code or as a column in a SQLAlchemy query.
-
-
Returns:
list[BaseWord]: A list of affixes that are derived from the word.
Hybrid property that returns a list of complexes derived from the word.
-
This property is a hybrid of a Python property and a SQLAlchemy expression.
-It can be used as a property in Python code or as a column in a SQLAlchemy query.
-
-
Returns:
list[BaseWord]: A list of complexes derived from the word.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is created. The default value is the current
-timestamp, and it can’t be null.
A class attribute mapped to a column in the database table. It represents
-the timestamp when a row is last updated. Whenever the row is updated,
-this timestamp is automatically set to the current time. It can be null
-if the row has never been updated.