From 2148929f3f4157a4bfda318c670290b4391a2739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sat, 25 Feb 2017 18:27:07 +0100 Subject: Use Peewee instead of SQLAlchemy --- archivist/__init__.py | 3 - archivist/cli.py | 38 ++++++++++-- archivist/model.py | 165 ++++++++++++++++++-------------------------------- requirements.txt | 3 +- setup.py | 8 +-- 5 files changed, 96 insertions(+), 121 deletions(-) diff --git a/archivist/__init__.py b/archivist/__init__.py index 517b168..e69de29 100644 --- a/archivist/__init__.py +++ b/archivist/__init__.py @@ -1,3 +0,0 @@ -from sqlalchemy.orm import sessionmaker, scoped_session - -Session = scoped_session(sessionmaker()) diff --git a/archivist/cli.py b/archivist/cli.py index 01c0b57..4316705 100644 --- a/archivist/cli.py +++ b/archivist/cli.py @@ -3,8 +3,13 @@ import click CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) @click.group(context_settings = CONTEXT_SETTINGS) -def cli(): - pass +@click.option('--debug', '-d', is_flag=True, default=False) +def cli(debug): + if debug: + import logging + logger = logging.getLogger('peewee') + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler()) @cli.group() def db(): @@ -14,12 +19,33 @@ def db(): @db.command() def init(): """Initialize the database, if not done already.""" - from .model import create_all - create_all() + from .model import create_tables, Prefix, db + create_tables() + with db.atomic(): + Prefix.create(name='year', builtin=True) + Prefix.create(name='month', builtin=True) + Prefix.create(name='day', builtin=True) + Prefix.create(name='date', builtin=True, pseudo=True) + Prefix.create(name='direction', builtin=True, pseudo=True) @db.command() @click.confirmation_option(prompt="Are you sure you want to drop the database?") def drop(): """Completely drop all tables.""" - from .model import drop_all - drop_all() + from .model import drop_tables + drop_tables() + +@cli.group() +def list(): + pass + +@list.command("prefixes") +def list_prefixes(): + from .model import Prefix, db + + print("Prefixes") + print("========") + print() + + for p in Prefix.select(): + print(" * %s (builtin: %s; pseudo: %s)" % (p.name, p.builtin, p.pseudo)) diff --git a/archivist/model.py b/archivist/model.py index 69765f3..b281edc 100644 --- a/archivist/model.py +++ b/archivist/model.py @@ -1,106 +1,59 @@ -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) - -def create_all(): - Model.metadata.create_all(engine) - -def drop_all(): - Model.metadata.drop_all(engine) - -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') - ) +from peewee import * +from playhouse.fields import CompressedField + +import datetime + +db = SqliteDatabase('test.db', pragmas=[('foreign_keys', 'ON')]) + +__tables__ = [] +__all__ = ['create_tables', 'drop_tables'] + +def table(cls): + __tables__.append(cls) + __all__.append(cls.__name__) + return cls + +def create_tables(): + db.create_tables(__tables__, True) + +def drop_tables(): + db.drop_tables(__tables__, True) + +class BaseModel(Model): + class Meta: + database = db + +@table +class Document(BaseModel): + content = CompressedField() + created = DateTimeField(default=datetime.datetime.now) + description = CharField(null=True) + direction = BooleanField(null=True) + original_path = CharField(null=True) + +@table +class Prefix(BaseModel): + name = CharField(null=True, unique=True) + builtin = BooleanField(default = False) + pseudo = BooleanField(default = False) + +@table +class Tag(BaseModel): + name = CharField() + prefix = ForeignKeyField(Prefix, null=True, related_name = 'tag') + +@table +class DocumentTag(BaseModel): + document = ForeignKeyField(Document, related_name = 'tags') + tag = ForeignKeyField(Tag) + + class Meta: + primary_key = CompositeKey('document', 'tag') + +@table +class TagImplications(BaseModel): + tag = ForeignKeyField(Tag) + implies_tag = ForeignKeyField(Tag, related_name = 'implications') + + class Meta: + primary_key = CompositeKey('tag', 'implies_tag') diff --git a/requirements.txt b/requirements.txt index 208d557..1cc7230 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ -alembic==0.8.7 click==6.6 -SQLAlchemy==1.0.14 +peewee>=2.8.3 diff --git a/setup.py b/setup.py index 3129502..660054e 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,13 @@ -from setuptools import setup +from setuptools import setup, find_packages setup( name='archivist', version='0.1', - py_modules=['archivist'], + py_modules=find_packages(), + include_package_data=True, install_requires=[ 'Click', - 'sqlalchemy', - 'alembic' + 'peewee' ], entry_points=''' [console_scripts] -- cgit v1.2.3