from sqlalchemy.ext.declarative import declarative_base from .database import session, now_utc from sqlalchemy.schema import Column, ForeignKey from sqlalchemy.types import Integer, String, DateTime from sqlalchemy.orm import column_property, relationship, synonym from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.sql.expression import cast from sqlalchemy.dialects import postgresql from urllib.parse import quote Base = declarative_base() Base.query = session.query_property() class DepictsItem(Base): __tablename__ = 'depicts' item_id = Column(Integer, primary_key=True, autoincrement=False) label = Column(String) description = Column(String) commons = Column(String) count = Column(Integer) qid = column_property('Q' + cast(item_id, String)) db_alt_labels = relationship('DepictsItemAltLabel', collection_class=set, cascade='save-update, merge, delete, delete-orphan', backref='item') alt_labels = association_proxy('db_alt_labels', 'alt_label') class DepictsItemAltLabel(Base): __tablename__ = 'depicts_alt_label' item_id = Column(Integer, ForeignKey('depicts.item_id'), primary_key=True, autoincrement=False) alt_label = Column(String, primary_key=True) def __init__(self, alt_label): self.alt_label = alt_label class PaintingItem(Base): __tablename__ = 'painting' item_id = Column(Integer, primary_key=True, autoincrement=False) label = Column(String) entity = Column(postgresql.JSON) qid = column_property('Q' + cast(item_id, String)) class HumanItem(Base): __tablename__ = 'human' item_id = Column(Integer, primary_key=True, autoincrement=False) year_of_birth = Column(Integer, nullable=False) year_of_death = Column(Integer, nullable=False) age_at_death = column_property(year_of_death - year_of_birth) qid = column_property('Q' + cast(item_id, String)) yob = synonym('year_of_birth') yod = synonym('year_of_death') class Language(Base): __tablename__ = 'language' item_id = Column(Integer, primary_key=True, autoincrement=False) wikimedia_language_code = Column(String, index=True, unique=True) en_label = Column(String, nullable=False) code = synonym('wikimedia_language_code') label = synonym('en_label') @classmethod def get_by_code(cls, code): return cls.query.filter_by(wikimedia_language_code=code).one() class Edit(Base): __tablename__ = 'edit' username = Column(String, primary_key=True) painting_id = Column(Integer, ForeignKey('painting.item_id'), primary_key=True) depicts_id = Column(Integer, ForeignKey('depicts.item_id'), primary_key=True) timestamp = Column(DateTime, default=now_utc()) lastrevid = Column(Integer, nullable=True) painting_qid = column_property('Q' + cast(painting_id, String)) depicts_qid = column_property('Q' + cast(depicts_id, String)) painting = relationship('PaintingItem') depicts = relationship('DepictsItem') @property def url_norm_username(self): return quote(self.username.replace(' ', '_')) @property def user_wikidata_url(self): return 'https://www.wikidata.org/wiki/User:' + self.url_norm_username