Status: | Under development |
---|
By default, Moksha aims to provide a default model to facilitate community interaction and knowledge cultivation.
Moksha contains a generic model that can be used to store arbitrary entities that have dynamic properties. This model can be used or extended by any Moksha application. The data is stored in a polymorphic-valued vertical table, and can be utilized as a normal Python dictionary.
>>> import transaction
>>> from moksha.model import Entity, with_characteristic, DBSession
>>> snake = Entity(u'snake')
>>> snake[u'family'] = u'Python'
>>> snake[u'venomous'] = False
>>> DBSession.add(snake)
>>> transaction.commit()
>>> python = Entity.by_name(u'Python')
>>> snakes = (DBSession.query(Entity).
... filter(or_(Entity.facts.any(
... with_characteristic(u'venomous', False)),
... not_(Entity.facts.any(Fact.key == u'venomous'))))).
... all()
...
>>> snakes = (DBSession.query(Fact).
... filter(with_characteristic(u'venomous', False))).all()
...
Moksha provides a moksha.model.vertical
module that makes it easy to
define polymorphic-valued vertical database models, using SQLAlchemy. A good example of this is
the Entity/Fact model described above.
from datetime import datetime
from sqlalchemy import *
from sqlalchemy.orm import relation, comparable_property
from sqlalchemy.orm.collections import attribute_mapped_collection
from moksha.model import metadata, DBSession, DeclarativeBase
from moksha.model.vertical import (PolymorphicVerticalProperty,
VerticalPropertyDictMixin)
class Fact(PolymorphicVerticalProperty, DeclarativeBase):
""" A polymorphic-valued vertical table property """
__tablename__ = 'facts'
id = Column(Integer, ForeignKey('entities.id'), primary_key=True)
key = Column(Unicode(64), primary_key=True)
type_ = Column(Unicode(16), default=None)
int_value = Column(Integer, default=None)
char_value = Column(UnicodeText, default=None)
boolean_value = Column(Boolean, default=None)
datetime_value = Column(DateTime, default=None)
value = comparable_property(PolymorphicVerticalProperty.Comparator,
PolymorphicVerticalProperty.value)
type_map = {
int: (u'integer', 'int_value'),
unicode: (u'char', 'char_value'),
bool: (u'boolean', 'boolean_value'),
datetime: (u'datetime', 'datetime_value'),
type(None): (None, None),
}
with_characteristic = lambda key, value: and_(Fact.key==key, Fact.value==value)
class Entity(VerticalPropertyDictMixin, DeclarativeBase):
__tablename__ = 'entities'
_property_type = Fact
_property_mapping = 'facts'
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(Unicode(100))
facts = relation(Fact, backref='entity',
collection_class=attribute_mapped_collection('key'))
def __init__(self, name):
self.name = name
@classmethod
def by_name(cls, name):
return DBSession.query(cls).filter(cls.name==name).first()