Log in

"ORM for non-R" or Document Models

« previous entry | next entry »
Aug. 21st, 2009 | 09:33 pm
music: Endraum

UPD: see Models repository for implementation.

Task: develop a kind of Django ORM for non-relational storages (key/value, document-oriented).
Goals: a) validation of incoming data, b) retrieving data of certaing kind from storage.

K/V features: attributes are mostly serialized and stored as record value → hard to query (but not in TC TDB).
DODB features: model represents a document.
Common features: a class doesn't have to be structured exactly the same as the record it represents because the constraints typical for RDBMS (the number and types of fields) make no sense here. This means that a model can describe a subset of valid attributes for a single record, and not necessarily will these attributes be required. This also means that a single document can be represented by more than one model; moreover, these models can have nothing in common. Thus, a model describes not a record but a query on a storage. (The really funny thing about such models is that they are saved queries written in a Pythonic DDL.) Therefore, duck typing is available right on the data level (vs. traditional rigid architecture or even document type labels).

Possible fun extras:
- a model with its data distributed among multiple storages (a sort of join by multiple databases — something that even geniusql can't do [yet]). Of course integrity issues will follow.
- more that one allowed data type per attribute. (probably harmful.)

Задача: сделать аналог Django ORM для нереляционных хранилищ (KVS или DODB).
Цели: а) валидация входящих данных; б) получение данных определенного типа из хранилища.

Особенности для KVS: чаще всего атрибуты модели будут сериализованы в значении записи.
Особенности для DODB: модели соответствует документ.
Общие особенности: нет смысла в жесткой привязке атрибутов ООП-класса к структуре некой записи в хранилище, поскольку нет характерных для RBDMS ограничений на содержимое записи (кол-во и тип полей). это означает, что модель может описывать _не все_ поля, и не все описанные поля будут обязательными. это также означает, что один документ может соответствовать более чем одной модели; более того, эти модели могут быть вообще не связаны между собой. то есть, модель описывает не запись, а выборку из хранилища. (смех в том, что такая модель и есть не что иное как запрос к базе, написанный на питоническом DDL!) значит, прямо в данных возможна типизация не статическая, а duck typing.

Возможные плюшки:
- модель, данные которой размазаны сразу по нескольким хранилищам (джойн по нескольким базам). ессно, проблемы с целостностью.
- разрешать более одного типа данных для любого поля. (скорее всего, вредная фича.)

Syntax proposal:
from datashaping.models import Model, String, Number

class Person(Model):
    name = String(required=True)
    age = Number()

    class Meta:
        identified_by = {'type': 'person'}

or even so:
class Person(Model):
    type = String(required=['person'])
    name = String(required=True)
    age = Number()

another funny option:
class OlderPerson(Person):
    type = String(in_=['person'])
    name = String(exists=True)
    age = Number(gte=70)

...which can be reduced to:
from datashaping.models import Field as f

custom_validator = lambda value: ...

class OlderPerson(Person):
    type = f(choices=['person'], exists=True)
    name = f(basestring, exists=True)
    age  = f((int,float), gte=70)
    foo  = f(custom_validator)

(note that foo__exists=True is the Datashaping's way to say foo is not None.)

Link | Leave a comment | Share

Comments {0}