Hi there, On 10/28/07, mmstud <[EMAIL PROTECTED]> wrote: > Next design problem for me is version table. I have Document model > with DocumentVersion model, but i dont know how to: > > - get the latest version of document > - set creator and updator, automatic behavior for this > - update version number > - fetch thru Document(s) and DocumentVersion(s)
I didn't read your code thoroughly, but I have a model with some similarities. Perhaps it will provide some insight. Basically, I'm dealing with "Pages" and "PageVersions". "PageVersions" refers to it's parent "Page", but "Page" also keeps the version number of the latest version. Arnar # encoding: utf-8 import os from datetime import datetime from sqlalchemy import * from softproof import utils from softproof.json import jsonify_saobject __meta__ = metadata def constructor(fun): def decorated(self, *args, **kw): assert hasattr(self, 'c') for key,value in kw.items(): if hasattr(self.c, key): setattr(self, key, value) del kw[key] fun(self, *args, **kw) return decorated jobs = Table("jobs", __meta__, Column("jobno", Unicode(15), primary_key=True), Column("created", DateTime, nullable=False, default=datetime.now), Column("deleted", Boolean, nullable=False, default=False)) class Job(object): @constructor def __init__(self, jobno=None): if jobno: self.jobno = jobno def sortedpages(self): listcopy = self.pages[:] listcopy.sort(key=Page.sort_key) return listcopy def get_page_by_name(self, pagename): """Finnur síðu með nafnið pagename og skilar henni. Skilar None ef engin síða hefur viðkomandi nafn. Ef pagename er _firstpage_ er skilað viðeigandi síðu (t.d. kápu ef hún er til)""" if len(self.pages) == 0: return None if '_firstpage_' == pagename: for p in self.pages: if 'KAP' in p.pagename: return p return self.pages[0] for p in self.pages: if p.pagename == pagename: return p return None def create_page(self, pagename, *args, **kwargs): p = Page(job=self, pagename=pagename, *args, **kwargs) return p def get_path(self): if self.jobno.startswith('P'): pg1, pg2, pg3 = self.jobno.split('.') return os.path.join(pg1, pg1+'.'+pg2, self.jobno) else: return os.path.join(self.jobno[:-3]+'000', self.jobno[:-2]+'00', self.jobno) mapper(Job, jobs) pageversions = Table("pageversions", __meta__, Column("jobno", Unicode(15), ForeignKey("pages.jobno"), primary_key=True), Column("pagename", Unicode(30), ForeignKey("pages.pagename"), primary_key=True), Column("version", Integer, primary_key=True, default=1), Column("created", DateTime, nullable=False, default=datetime.now), Column("md5sum", String(32)), Column("width", Integer, nullable=False, default=0), Column("height", Integer, nullable=False, default=0), ForeignKeyConstraint(["jobno", "pagename"],["pages.jobno", "pages.pagename"])) class PageVersion(object): @constructor def __init__(self, page=None, version=None): if page: self.page = page if version: self.version = version @property def filename(self): if self.version == 1: return self.page.pagename + '.jpg' else: return "%s.v%02d.jpg" % (self.page.pagename, self.version) mapper(PageVersion, pageversions) PageStates = utils.Enum('new', 'approved', 'rejected') pages = Table("pages", __meta__, Column("jobno", Unicode(15), ForeignKey("jobs.jobno"), primary_key=True), Column("pagename", Unicode(30), primary_key=True), Column("created", DateTime, nullable=False, default=datetime.now), Column("deleted", Boolean, nullable=False, default=False), Column("current_version", Integer), Column("status", PageStates, nullable=False, default=PageStates.new)) class Page(object): @constructor def __init__(self, job=None, pagename=None): if job: self.job = job if pagename: self.pagename = pagename self.currentversion = PageVersion(self, 1) self.status = PageStates.new def add_version(self): self.currentversion = PageVersion(self, self.currentversion.version+1) self.status = PageStates.new comment = self.add_comment() comment.closeable = False comment.content = u'Ný útgáfa rippuð' return self.currentversion def get_version(self, versionno): return self.versions[versionno-1] def _get_status(self): return self._status def _set_status(self, newstatus): if self._status is None: self._status = newstatus return if self._status == newstatus: return if self._status == PageStates.new and newstatus == PageStates.approved: opencomment = False for c in self.comments: if not c.closeable: continue opencomment = opencomment or c.closed is None if opencomment: raise ValueError('Cant set job state to approved if it has open comments.') self._status = newstatus status = property(_get_status, _set_status) def changeStatus(self, newstatus, user_name=None): self.status = newstatus comment = self.add_comment(user_name) comment.closeable = False if newstatus == PageStates.new: comment.content = u"Merkt sem ný" elif newstatus == PageStates.approved: comment.content = u"Samþykkt" elif newstatus == PageStates.rejected: comment.content = u"Hafnað" def get_next_page(self): myindex = self.job.pages.index(self) if myindex < len(self.job.pages)-1: return self.job.pages[myindex+1] else: return None def get_previous_page(self): myindex = self.job.pages.index(self) if myindex > 0: return self.job.pages[myindex-1] else: return None SORT_VALUES = { "ali": 0 - 1000, "kap": 1 - 1000, "ik": 2 - 1000, "ib": 3 - 1000, "bak": 4 - 1000, "aud": 5 - 1000, "r": 6 - 1000, # Tölur koma hér "lakk": 1 + 100000, "__default__": 2 + 100000, } def sort_key(self): t = [] pn = self.pagename if pn.endswith("-P1"): pn = pn[:-3] if pn.startswith(self.job.jobno + "."): pn = pn[len(self.job.jobno)+1:] for part in pn.split("."): if part.lower().strip() in Page.SORT_VALUES: t.append(Page.SORT_VALUES[part.lower().strip()]) else: try: t.append(int(part)) except ValueError: t.append(part) return tuple(t) def __jsonextra__(self, props): props['status'] = self.status mapper(Page, pages, properties={ '_status': pages.c.status, 'job': relation(Job, backref=backref('pages', cascade="all, delete-orphan", order_by=pages.c.pagename)), 'currentversion': relation(PageVersion, foreignkey=pages.c.current_version, primaryjoin=and_(pages.c.jobno==pageversions.c.jobno, pages.c.pagename==pageversions.c.pagename, pages.c.current_version==pageversions.c.version), post_update=True), 'versions': relation(PageVersion, cascade="all, delete-orphan", primaryjoin=and_(pages.c.jobno==pageversions.c.jobno, pages.c.pagename==pageversions.c.pagename), order_by=pageversions.c.version, backref=backref('page', primaryjoin=and_(pages.c.jobno==pageversions.c.jobno, pages.c.pagename==pageversions.c.pagename))) # '_status': pages.c.status, # 'status': synonym('_status') }) --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---