From 36fc451124e3c866d86c0656a865357c4e944c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Mon, 15 Aug 2016 21:39:12 +0200 Subject: Initial model and sqlalchemy setup --- archivist/__init__.py | 3 ++ archivist/__main__.py | 0 archivist/model.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 archivist/__init__.py create mode 100644 archivist/__main__.py create mode 100644 archivist/model.py diff --git a/archivist/__init__.py b/archivist/__init__.py new file mode 100644 index 0000000..517b168 --- /dev/null +++ b/archivist/__init__.py @@ -0,0 +1,3 @@ +from sqlalchemy.orm import sessionmaker, scoped_session + +Session = scoped_session(sessionmaker()) diff --git a/archivist/__main__.py b/archivist/__main__.py new file mode 100644 index 0000000..e69de29 diff --git a/archivist/model.py b/archivist/model.py new file mode 100644 index 0000000..ce360f3 --- /dev/null +++ b/archivist/model.py @@ -0,0 +1,101 @@ +from sqlalchemy import create_engine +from sqlalchemy import MetaData, Table, Column, ForeignKey, UniqueConstraint +from sqlalchemy import types as ty + +from sqlalchemy.orm import relationship +from sqlalchemy.ext.declarative import as_declarative, declared_attr + +from functools import partial + +from . import Session + +engine = create_engine('sqlite:///:memory:', echo=True) +Session.configure(bind=engine) + +ReqColumn = partial(Column, nullable = False) + +convention = { + 'ix': "ix_%(column_0_label)s", + 'uq': "uq_%(table_name)s_%(column_0_name)s", + 'ck': "ck_%(table_name)s_%(column_0_name)s", + 'fk': "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", + 'pk': "pk_%(table_name)s" +} +metadata = MetaData(naming_convention = convention) + +try: + from sqlalchemy_repr import RepresentableBase as Base +except ImportError: + Base = object + +class _QueryProperty(object): + def __get__(self, obj, type): + return Session().query(type) + +@as_declarative(metadata = metadata) +class Model(Base): + id = Column(ty.Integer, primary_key=True) + + @declared_attr + def __tablename__ (cls): + return cls.__name__.lower() + + query = _QueryProperty() + + @classmethod + def get_by(cls, *args, **kwargs): + return cls.query.filter_by(*args, **kwargs).first() + + @classmethod + def get(cls, *args, **kwargs): + return cls.query.get(*args, **kwargs) + + +class Prefix(Model): + prefix = Column(ty.Unicode, index = True, unique = True) + builtin = ReqColumn(ty.Boolean, default = False) + pseudo = ReqColumn(ty.Boolean, default = False) + + def __init__(self, name): + self.name = name + +class Tag(Model): + name = ReqColumn(ty.Unicode) + prefix_id = Column(ty.Integer, ForeignKey(Prefix.id)) + prefix = relationship('Prefix', backref='tag') + + implications = relationship('Tag', + secondary = 'tag_x_tag', + primaryjoin = 'Tag.id == tag_x_tag.c.tag_id', + secondaryjoin = 'Tag.id == tag_x_tag.c.implies_tag_id', + backref='implied_by') + + def __init__(self, name, prefix = None): + self.name = name + self.prefix = prefix + + def implies(self, other): + self.implications.append(other) + + def remove_implication(self, other): + self.implications.remove(other) + +class Document(Model): + description = Column(ty.Unicode) + created = ReqColumn(ty.DateTime) + content = ReqColumn(ty.LargeBinary) + original_path = Column(ty.Unicode) + direction = Column(ty.Boolean) + tags = relationship('Tag', secondary = 'document_x_tag') + +Table('document_x_tag', Model.metadata, + Column('document_id', ty.Integer, ForeignKey(Document.id)), + Column('tag_id', ty.Integer, ForeignKey(Tag.id)), + UniqueConstraint('document_id', 'tag_id', name = 'uq_document_x_tag') + ) + +Table('tag_x_tag', Model.metadata, + Column('tag_id', ty.Integer, ForeignKey(Tag.id)), + Column('implies_tag_id', ty.Integer, ForeignKey(Tag.id)), + UniqueConstraint('tag_id', 'implies_tag_id', name = 'uq_tag_x_tag') + ) -- cgit v1.2.3