[sqlalchemy] Re: Separate version table
Thats handy. Where could i get the utils module you're using for Enum datatype? On 28 loka, 23:52, Arnar Birgisson [EMAIL PROTECTED] wrote: On 10/28/07, mmstud [EMAIL PROTECTED] wrote: Thanks there were some good ideas to try. Btw. what does the first def constructor(fun)? It is a decorator I use on mapped classes constructors. It allows me to give keyword arguments to constructors with initial values for any field in class.c (i.e. any mapped columns). cheers, Arnar --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: Separate version table
I dont need history tracking, just revert documents to older ones. that is history, just not timed history. u'll have documents, and then for each document a bunch of versions. Once get it working on simple form, then perhaps trying optimicing and feeding only field, that has changed. Version field automatic update was on my mind lately. Could it be something like this: Column(version, Integer, default=1, nullable=False, onupdate=document_versions.select(document_versions.document_id=c.d ocument_id, order_by=version, order=DESC, limit=1) no idea, what this onupdate is expected to do here? afaik these things are done with a mapper extension, but i'm not sure its the only way. what would be version field? something that counts the inserts for that particular document_id? I just dont know, how to get current document id, is it just c.document_id? yes, yourobj.document_id or whatever u named it as column. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: Separate version table
On 29 loka, 09:08, [EMAIL PROTECTED] wrote: I dont need history tracking, just revert documents to older ones. that is history, just not timed history. Most optimal would it be, if i can make rows with updated fields only, not to copy whole row... but im afraid setting unchanged field to None would be problematic when retrieving versions. I should retrieve several rows and collect the latest not None fields... just pondering u'll have documents, and then for each document a bunch of versions. Once get it working on simple form, then perhaps trying optimicing and feeding only field, that has changed. Version field automatic update was on my mind lately. Could it be something like this: Column(version, Integer, default=1, nullable=False, onupdate=document_versions.select(document_versions.document_id=c.d ocument_id, order_by=version, order=DESC, limit=1) no idea, what this onupdate is expected to do here? It was meant to be oninsert, not onupdate, but on the other hand, if making system with mapper extension, i think i need to do before_update and increase version number there as well as making a new insert and halt doing update. afaik these things are done with a mapper extension, but i'm not sure its the only way. I'm going to try with mapper extension what would be version field? something that counts the inserts for that particular document_id? Yes, just a counter for every insert to document_id. I could use len(Versions) or get latest DocumentVersion.version+1 --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: Separate version table
On 10/29/07, mmstud [EMAIL PROTECTED] wrote: Thats handy. Where could i get the utils module you're using for Enum datatype? The Enum datatype is from the ASPN cookbook, with type bindings for SA. Here's part of my utils module. cheers, Arnar # -*- encoding: UTF-8 -*- import sqlalchemy.types as types import datetime, time from itertools import groupby def numericSort(alist, val=lambda x: x): Returns a copy. See recipe 135435 on aspn def genidx(str): index = [] def _append(fragment, alist=index): if fragment.isdigit(): fragment = int(fragment) alist.append(fragment) prev_isdigit = str[0].isdigit() current_fragment = '' for char in str: curr_isdigit = char.isdigit() if curr_isdigit == prev_isdigit: current_fragment += char else: _append(current_fragment) current_fragment = char prev_isdigit = curr_isdigit _append(current_fragment) return tuple(index) indicies = map(genidx, map(val, alist)) decorated = zip(indicies, alist) decorated.sort() return [item for idx, item in decorated] # From ASPN cookbook, Zoran Isailovski (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486) # Added JSON and SQLAlchemy handles def Enum(*names): ##assert names, Empty enums are not supported # - Don't like empty enums? Uncomment! class EnumClass(types.TypeDecorator): __slots__ = names impl = types.Integer def __iter__(self):return iter(constants) def __len__(self): return len(constants) def __getitem__(self, i): return constants[i] def __repr__(self):return 'Enum' + str(names) def __str__(self): return 'enum ' + str(constants) def convert_bind_param(self, value, engine): return value.Value def convert_result_value(self, value, engine): return self[value] class EnumValue(object): __slots__ = ('__value') def __init__(self, value): self.__value = value Value = property(lambda self: self.__value) EnumType = property(lambda self: EnumType) def __hash__(self):return hash(self.__value) def __cmp__(self, other): if type(other) is str: return cmp(str(self), other) elif type(other) is unicode: return cmp(str(self), str(other)) else: # C fans might want to remove the following assertion # to make all enums comparable by ordinal value {;)) assert self.EnumType is other.EnumType, Only values from the same enum are comparable return cmp(self.__value, other.__value) def __invert__(self): return constants[maximum - self.__value] def __nonzero__(self): return bool(self.__value) def __repr__(self):return str(names[self.__value]) def __json__(self):return str(names[self.__value]) maximum = len(names) - 1 constants = [None] * len(names) for i, each in enumerate(names): val = EnumValue(i) setattr(EnumClass, each, val) constants[i] = val constants = tuple(constants) EnumType = EnumClass() return EnumType class Region(object): def __init__(self, left, top, width, height): self.left = left self.top = top self.width = width self.height = height def __str__(self): return Region(%d,%d,%d,%d) % (self.left,self.top,self.width,self.height) def __repr__(self): return str(self) def countdistinct(iterable, groups=None, key=None): Count things. items = ['red', 'green', 'blue', 'blue'] countdistinct(items) {'blue': 2, 'green': 1, 'red': 1} You can ensure that specific groups are always included in the result, even if they don't occur in the input: items = ['red', 'blue', 'blue'] countdistinct(items, groups=['red', 'green', 'blue']) {'blue': 2, 'green': 0, 'red': 1} The optional `key` argument can be used to provide a function that returns the comparison key for every item: from operator import itemgetter items = [dict(name='foo', category='buzz'), ... dict(name='bar', category='buzz')] print countdistinct(items, key=itemgetter('category')) {'buzz': 2} if groups is None: groups = [] d = dict([(g, 0) for g in groups]) for g, l in groupby(iterable, key=key): d[g] = len(list(l)) + d.get(g, 0) return d --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: Separate version table
Found enumeration implementations: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/Enum http://cheeseshop.python.org/pypi/enum/0.4.3 On 29 loka, 09:04, mmstud [EMAIL PROTECTED] wrote: Thats handy. Where could i get the utils module you're using for Enum datatype? On 28 loka, 23:52, Arnar Birgisson [EMAIL PROTECTED] wrote: On 10/28/07, mmstud [EMAIL PROTECTED] wrote: Thanks there were some good ideas to try. Btw. what does the first def constructor(fun)? It is a decorator I use on mapped classes constructors. It allows me to give keyword arguments to constructors with initial values for any field in class.c (i.e. any mapped columns). cheers, Arnar --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: Separate version table
On 10/29/07, mmstud [EMAIL PROTECTED] wrote: On 29 loka, 09:08, [EMAIL PROTECTED] wrote: I dont need history tracking, just revert documents to older ones. that is history, just not timed history. Most optimal would it be, if i can make rows with updated fields only, not to copy whole row... but im afraid setting unchanged field to None would be problematic when retrieving versions. I should retrieve several rows and collect the latest not None fields... just pondering That reminded me, I have another project that does automatic changelogs. There is something in the ML archives, but here's some more code. I'm afraid all class, variable and field names are in Icelandic - I put in comments with translations where it matters. I also removed alot of auxiliary tables since this is proprietary code. The base entity that keeps a changelog of itself is Verkefni (means project). A changelog entry is generated by calling changelog_entry on a dirty object. This is not done automatically as sometimes one wants to update an object without generating a log entry. Arnar # -*- encoding: UTF-8 -*- import datetime import cherrypy import sqlalchemy from sqlalchemy.ext.sessioncontext import SessionContext from sqlalchemy.ext.assignmapper import assign_mapper from sqlalchemy.orm import MapperExtension, EXT_PASS _engine = None metadata = sqlalchemy.DynamicMetaData() def get_engine(): global _engine dburi = cherrypy.config.get('verkstjorinn.db.uri') encoding = cherrypy.config.get('verkstjorinn.db.encoding', 'utf-8') echo = cherrypy.config.get('verkstjorinn.db.echo', False) if not _engine: _engine = sqlalchemy.create_engine(dburi, encoding=encoding, echo=echo, convert_unicode=True) metadata.connect(_engine) elif not metadata.is_bound(): metadata.connect(_engine) return _engine ctx = SessionContext(lambda:sqlalchemy.create_session(bind_to=get_engine())) def sa_uow_cleanup(): ctx.current.clear() sa_uow_cleanup.failsafe = True cherrypy.tools.sacleanup = cherrypy.Tool('on_end_request', sa_uow_cleanup) class base_model(object): def __repr__(self): props = [] for key in self.c.keys(): props.append(%s=%r % (key, getattr(self, key))) return %s %s % (self.__class__.__name__, ' '.join(props)) from sqlalchemy import * ## Verkefni = Projects verkefni_flokkar = Table(verkefni_flokkar, metadata, Column(verkefni, Integer, ForeignKey(verkefni.verkefni), primary_key=True), Column(flokkur, Integer, ForeignKey(flokkar.flokkur), primary_key=True) ) # No mapper for this table, it's only a join table for the many-to-many relation verkefni = Table(verkefni, metadata, Column(verkefni, Integer, primary_key=True), Column(skrad, DateTime, nullable=False, default=func.now()), Column(sidast_breytt, DateTime, nullable=False, default=func.current_timestamp(), onupdate=func.current_timestamp()), Column(skrad_af, Unicode(20), ForeignKey(notendur.notandi), nullable=False), Column(deadline, Date), Column(titill, Unicode, nullable=False), Column(lysing, Unicode, nullable=False), Column(mikilvaegi, Integer, ForeignKey(mikilvaegi.mikilvaegi), nullable=False, default=40), Column(forgangur, Integer, nullable=False, default=0), Column(framvinda, Integer, nullable=False, default=0), Column(fasi, Integer, ForeignKey(fasar.fasi), nullable=False, default=5), Column(abyrgdarmadur, Unicode(20), ForeignKey(notendur.notandi), nullable=False), Column(cc, Unicode), Column(verknumer, Unicode(20)), Column(tengilidur, Unicode(60)), Column(bidur_eftir, Unicode) ) class Verkefni(base_model): class DEFAULTS: def __init__(self): self.verkefni = 0 self.skrad = datetime.datetime.now() self.sidast_breytt = datetime.datetime.now() self.titill = self.lysing = self.verknumer = None self.tengilidur = None self.deadline = None self.bidur_eftir = None self.flokkar = [] self.mikilvaegi = Mikilvaegi.get(40) self.forgangur = 0 self.framvinda = 0 self.fasi = Fasi.get(5) self.abyrgdarmadur = None # Must be set by controller self.cc = None self.depends_on = () self.depend_on_me = () def get_fyrirtaeki(self): return [] def get_framkvaemd(self): return [] def combined_athugasemdir(self): return [] def get_dependency_parents(self): return [] def get_dependency_children(self): return [] @property def skyldverkefni(self): related = SkyltVerkefni.select_by( or_(SkyltVerkefni.c._verkefni_a==self.verkefni,SkyltVerkefni.c._verkefni_b==self.verkefni) ) relations = [] for sv in related: if sv.verkefni_a == self: relations.append((sv.verkefni_b, sv.athugasemd))
[sqlalchemy] Re: post_processors error during 0.3.10 to 0.4 migration (returning different object type based on db data)
On Oct 28, 2007, at 11:02 PM, Ron wrote: I have a datastore that consists of 3 tables. 1. Thing table (just a primary-key name column) 2. Attr table (key/value columns with an id and foreign key to Thing table) 3. Thing-to-Thing relation table (Things can be 'connected' to each other) heres some questions: does the metaclass create a mapper() for every subclass ? i.e. is there a mapper for Server, SunServer, etc ? it seems like there is (since by the wrong mapper i meant, calling object_mapper(instance) returns a Server or SunServer mapper, not the Thing mapper which loaded the object). if there is a distinct mapper per class, cant your metaclass simply assign a hidden type attribute to each class, a single string value which indicates what class to load ? then you can just have a single type column in the thing table and SA's regular inheritance mechanisms take care of the rest. the metaclass would only need to worry about things when the user first creates the object. im not seeing any reasons here why this wouldnt work. also when you say the user shouldnt have to know about SA, that suggests the other way I might do this, that Thing stays as Thing and the user-facing object is actually a wrapper for a Thing, and is not mapped to the ORM directly. this makes it less convenient as the user-facing object cant be used in SA operations directly, you'd have to translate around sessions and queries. theres three examples in the distro you should look at: examples/polymorph/single.py - single table inheritance examples/vertical/vertical.py - stores vertical attributes similarly to your Thing examples/elementtree/adjacency_list.py - this is mostly about self- referential relationships, but also illustrates how a non-mapped object can be supplied its internals by a mapped object (i.e. its a wrapper). --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] SQLalchemy coding style
Hi all, I'm intersted in using sqlalchemy and started to read the manuals. I didn't find a hint for my question, so I'm asking here. I hope it's not too annoying. Most code examples in the documentation use something like this from sqlalchemy. import My question is: Is this the good/proper way to import the sqlalchemy stuff. I'm concerned about polluting the current namespace. I could assume that class names like 'Table' are too common to reserve them for the sqlalchemy classes. What would you recommend? How are the gurus out there using sqlalchemy? Thanks in advance. Best regards Andreas Mock --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: SQLalchemy coding style
Hi, I have a python file for all the table and class definitions (model.py). In that I do from sqlalchemy import *, and that's ok as in that one file I know not to use names like Table. In my other python files I just import classes from model.py, and specific bits of sqlalchemy. Ok, occasionally I get lazy and just do an import * :) Paul On 10/29/07, McA [EMAIL PROTECTED] wrote: Hi all, I'm intersted in using sqlalchemy and started to read the manuals. I didn't find a hint for my question, so I'm asking here. I hope it's not too annoying. Most code examples in the documentation use something like this from sqlalchemy. import My question is: Is this the good/proper way to import the sqlalchemy stuff. I'm concerned about polluting the current namespace. I could assume that class names like 'Table' are too common to reserve them for the sqlalchemy classes. What would you recommend? How are the gurus out there using sqlalchemy? Thanks in advance. Best regards Andreas Mock --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] How to get list of relations
Hi, How do I get a list of the relations a mapper has? I've been using mapper.properties, but have just realised this doesn't pick up backrefs. Any ideas? Thanks, Paul --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: SQLalchemy coding style
What would you recommend? How are the gurus out there using sqlalchemy? I don't know what the gurus are doing. I'll answer as long as none of them does :-) It's probably what you're assuming already: Mapped classes can be treated as Active Records. Usually, I'm encapsulating these active records in their own modules. These modules can be seen as a layer directly above the relational DB, and they have all SQLAlchemy imports encapsulated. (99% in practice ;-) If you can't encapsulate, Pythons import machinery will allow us to use names like sa.Table ... so I can't see a pollution problem (at least, not worse than with any other library.) Regards- Ruben --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: SQLalchemy coding style
McA wrote: Hi all, I'm intersted in using sqlalchemy and started to read the manuals. I didn't find a hint for my question, so I'm asking here. I hope it's not too annoying. Most code examples in the documentation use something like this from sqlalchemy. import I am just experimenting with sqlalchemy, but I am pretty sure to start using it soon, I wondered about this too, to me it was confusing to look at code and not easily able to see where things come from. Having seen the wxPython project move to use the namespace as of 2.6 (with I think two transition releases), I have done all the tests so far doing the following type of import and corresponding code. This has not caused any problems so far and to while a little bit more typing makes the code more readable, especially for newbies. But I wonder why this is not done by everyone, i.e. what are the reasons not to do it this way? import sqlalchemy as sa import sqlalchemy.orm as sao metadata = sa.MetaData() cbbottle_table = sa.Table( u'cbbottle', metadata, sa.Column( u'cbbottleid', sa.Integer(), sa.Sequence('gen_cbbottle_cbbottleid'), primary_key= True, nullable= False), sa.Column( u'maturityfirst', sa.Integer()), sa.Column( u'maturitybest', sa.Integer()), sa.Column( u'maturitypast', sa.Integer()), ... sa.Column( u'fk_cbvintageid', sa.Integer(), sa.ForeignKey(u'cbvintage.cbvintageid')), ) Werner My question is: Is this the good/proper way to import the sqlalchemy stuff. I'm concerned about polluting the current namespace. I could assume that class names like 'Table' are too common to reserve them for the sqlalchemy classes. What would you recommend? How are the gurus out there using sqlalchemy? Thanks in advance. Best regards Andreas Mock --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: How to get list of relations
Hey whats going on. I am a new sqlalchemist as well but lets see if this helps any. This is how I am getting a list of all names that corrispond with my document names class. names = [ c.name for c in model.Document.select_by(param=param) ] So I am just collecting all the names from my Document table. I added select_by(param=param) if you want to find all the names that have to do with a parameter. names becomes a list I hope this helps a little. On Oct 29, 2007 11:21 AM, Paul Johnston [EMAIL PROTECTED] wrote: Hi, How do I get a list of the relations a mapper has? I've been using mapper.properties, but have just realised this doesn't pick up backrefs. Any ideas? Thanks, Paul --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: Looking for feedback on encapsulating SA logic (newbie)
mapper(User, users_table) Is not using assign_mapper preferable? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---