Source code for clld.db.models.language

from sqlalchemy import (
    Column,
    Float,
    Integer,
    String,
    Unicode,
    CheckConstraint,
    UniqueConstraint,
    ForeignKey,
)
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.associationproxy import association_proxy

from zope.interface import implementer

from clld.db.meta import Base, PolymorphicBaseMixin
from clld import interfaces
from clld.util import DeclEnum

from . import (
    IdNameDescriptionMixin,
    DataMixin, HasDataMixin, FilesMixin, HasFilesMixin)

__all__ = (
    'Language', 'LanguageSource',
    'IdentifierType', 'Identifier', 'LanguageIdentifier',
)


class Language_data(Base, DataMixin):

    """Associated data mapper."""


class Language_files(Base, FilesMixin):

    """Associated files mapper."""


[docs]@implementer(interfaces.ILanguage) class Language(Base, PolymorphicBaseMixin, IdNameDescriptionMixin, HasDataMixin, HasFilesMixin): """Languages are the main objects of discourse. We attach a geo-coordinate to them to be able to put them on maps. """ latitude = Column( Float(), CheckConstraint('-90 <= latitude and latitude <= 90'), doc='geographical latitude in WGS84') longitude = Column( Float(), CheckConstraint('-180 <= longitude and longitude <= 180 '), doc='geographical longitude in WGS84') identifiers = association_proxy('languageidentifier', 'identifier') def get_identifier_objs(self, type_): return [i for i in self.identifiers if i.type == getattr(type_, 'value', type_)] def get_identifier(self, type_): objs = self.get_identifier_objs(type_) if objs: return objs[0].name @property def iso_code(self): return self.get_identifier(IdentifierType.iso) @property def glottocode(self): return self.get_identifier(IdentifierType.glottolog)
class LanguageSource(Base): """Association table.""" __table_args__ = (UniqueConstraint('language_pk', 'source_pk'),) language_pk = Column(Integer, ForeignKey('language.pk'), nullable=False) source_pk = Column(Integer, ForeignKey('source.pk'), nullable=False) class IdentifierType(DeclEnum): """Known language identifiers.""" iso = 'iso639-3', 'ISO 639-3', 'https://iso639-3.sil.org/code/{0.name}' wals = 'wals', 'WALS Code', 'http://wals.info/languoid/lect/wals_code_{0.name}' glottolog = 'glottolog', 'Glottocode', \ 'http://glottolog.org/resource/languoid/id/{0.name}' ethnologue = 'ethnologue', 'Ethnologue', 'http://www.ethnologue.com/language/{0.name}' class Identifier(Base, IdNameDescriptionMixin): """A language identifier. We want to be able to link languages to languages in other systems. Thus, we store identifiers of various types like 'wals', 'iso639-3', 'glottolog'. But we might as well just store alternative names for languages. """ __table_args__ = (UniqueConstraint('name', 'type', 'description', 'lang'),) id = Column(String) type = Column(String) lang = Column(String(3), default='en') def url(self): try: return IdentifierType.from_string(self.type).args[0].format(self) except ValueError: return class LanguageIdentifier(Base): """Association table. Languages are linked to identifiers with an optional description of this linkage, e.g. 'is dialect of'. """ __table_args__ = (UniqueConstraint('language_pk', 'identifier_pk'),) language_pk = Column(Integer, ForeignKey('language.pk'), nullable=False) identifier_pk = Column(Integer, ForeignKey('identifier.pk'), nullable=False) description = Column(Unicode) identifier = relationship(Identifier, innerjoin=True) language = relationship( Language, innerjoin=True, backref=backref("languageidentifier", cascade="all, delete-orphan"))