Thanks Arnar, that was interesting to read. I learned a lot with these
codes. Here i share current point of my progress. I managed to do
mapper extension and document -> documentversion objects seems to work
ok, but im not so sure, if my solution was very elegant. So if anyone
sees this and wants to give further addvises, i'll be glad to hear. My
next step is to extend versioned documents from user point to the
organisation wide shared documents.

################################################################################
# Models
################################################################################
from string import join
from datetime import datetime

class User(object):
    def __init__(self, name):
        self.name = name

class Organisation(object):
    def __init__(self, name):
        self.name = name

class Language(object):
    def __init__(self, alpha2, name):
        self.alpha2 = alpha2
        self.name = name

class Document(object):

    def first(self):
        return self.versions[0]

    def latest(self):
        return self.versions[len(self.versions)-1]

class DocumentVersion(object):
    def __init__(self, name, content, language):
        self.name = name
        self.content = content
        self.language = language

class OrganisationDocumentVersion(object):
    def __init__(self, document_version, user):
        self.document_version = document_version
        self.updator = user

################################################################################
# Table definitions
################################################################################

from connections import engine
from sqlalchemy import ForeignKey, MetaData, Table, Column, String,
Integer, Unicode, DateTime, Date, Time, Boolean
from datetime import datetime

METADATA = MetaData()

USERS_TABLE = Table("users", METADATA,
    Column("id", Integer, primary_key=True),
    Column("name", Unicode(100), nullable=False),
)

ORGANISATIONS_TABLE = Table("organisations", METADATA,
    Column("id", Integer, primary_key=True),
    Column("name", Unicode(100), nullable=False),
)

LANGUAGES_TABLE = Table("languages", METADATA,
    Column("id", Integer, primary_key=True),
    Column("alpha2", String(2), unique=True, nullable=False),
    Column("name", Unicode(100), unique=True, nullable=False),
)
DOCUMENTS_TABLE = Table("documents", METADATA,
    Column("id", Integer, primary_key=True),
    Column("user_id", Integer, ForeignKey('users.id'),
nullable=False),
    Column("status", Integer, default=1, nullable=False), # 0 =
deleted, 1 = active
    Column("created", DateTime, default=datetime.now()),
)
DOCUMENT_VERSIONS_TABLE = Table("document_versions", METADATA,
    Column("id", Integer, primary_key=True),
    Column("document_id", Integer, ForeignKey('documents.id'),
nullable=False),
    Column("language_id", Integer, ForeignKey('languages.id'),
nullable=False),
    Column("name", Unicode(64), nullable=False),
    Column("content", Unicode),
    Column("version", Integer, default=1, nullable=False),
    Column("updated", DateTime, default=datetime.now()),
    Column("status", Integer, default=1, nullable=False), # 0 =
deleted, 1 = active
)

ORGANISATION_DOCUMENT_VERSIONS =
Table("organisation_document_versions", METADATA,
    Column("organisation_id", Integer, ForeignKey('organisations.id'),
primary_key=True),
    Column("document_version_id", Integer,
ForeignKey('document_versions.id'), primary_key=True),
    Column("user_id", Integer, ForeignKey('users.id'),
nullable=False),
)

METADATA.create_all(engine)

################################################################################
# Mappers
################################################################################
from models import *
from tables import *

from sqlalchemy.orm import mapper, relation, MapperExtension,
EXT_PASS, EXT_STOP
from datetime import datetime

class VersionedDocumentMapperExtension(MapperExtension):

    def before_update(self, mapper, connection, instance):
        colvalues = dict([(key, getattr(instance, key)) for key in
instance.c.keys()])
        del colvalues['id']
        colvalues['version'] = instance.version + 1
        colvalues['updated'] = datetime.now()
        # create a new version insert
        ins = DOCUMENT_VERSIONS_TABLE.insert(colvalues)
        connection.execute(ins)
        # get old values select, revert old values to current instance
        # this prevents making an update for the current instance
        sel =
DOCUMENT_VERSIONS_TABLE.select(DOCUMENT_VERSIONS_TABLE.c.id ==
instance.id)
        oldvalues = connection.execute(sel).fetchone()
        instance.name = oldvalues["name"]
        instance.content = oldvalues["content"]
        instance.language_id = oldvalues["language_id"]
        instance.status = oldvalues["status"]
        return EXT_STOP

    def before_delete(self, mapper, connection, instance):
        """ TODO! Hwo to halt actualy deleting the row?"""
        upd = DOCUMENT_TABLE.update(DOCUMENT_TABLE.c.id ==
instance.document.id)
        connection.execute(upd, status = 0)
        instance.document.status = 0
        return EXT_STOP

versioned_document_ext = VersionedDocumentMapperExtension()
#versioned_organisation_document_ext =
VersionedOrganisationDocumentMapperExtension()

mapper(User, USERS_TABLE, properties={
    'documents':relation(Document, backref="creator"),
 
'organisation_document_versions':relation(OrganisationDocumentVersion,
backref="updator"),
    }
)

mapper(Organisation, ORGANISATIONS_TABLE, properties={
    'document_versions':relation(OrganisationDocumentVersion,
backref="organisation"),
    }
)

mapper(Language, LANGUAGES_TABLE, properties={
    'document_versions':relation(DocumentVersion, backref="language"),
    }
)
mapper(Document, DOCUMENTS_TABLE, allow_column_override=True,
properties={
    'versions':relation(DocumentVersion, backref="document"),
    }
)
mapper(DocumentVersion, DOCUMENT_VERSIONS_TABLE,
extension=versioned_document_ext, properties={})

mapper(OrganisationDocumentVersion, ORGANISATION_DOCUMENT_VERSIONS,
allow_column_override=True, properties={})

################################################################################
# Example
################################################################################
from dbsessions import db_sess
from models import *
from mappers import *

user = db_sess.query(User).filter_by(id=1).first()
user_document = user.documents[0]
#user_document.versions
#user_document.first()
document_version = user_document.latest()
document_version.name = "new name"
document_version.language = language

db_sess.save(document_version)
db_sess.commit()
db_sess.refresh(user_document) # refreshing only user object does not
work


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to