On Jan 26, 2009, at 1:29 PM, Toby Bradshaw wrote:
> > Michael Bayer wrote: >> also your example should read like this: >> >> a = session.query(A).all()[0] >> print a.time_units >> a.time_units = 1 >> print a.time_units >> #print A.timeunits >> #print A.time_units >> > Huh ? time_units is the column name in the database. I want to refer > to > that column through the attribute 'timeunits'. I also want to use > descriptors to do extra work when setting that attribute. The synonym > api docs say: > > *def synonym(/name/, /map_column=False/, /descriptor=None/, / > proxy=False/)* > Set up name as a synonym to another mapped property. > > So when I say: > > mapper(A, table_A, properties = { > "time_units" : synonym("timeunits", map_column = True) > }) > > > Am I not saying 'create an alias to column 'time_units' in table_A and > call it 'timeunits' ?? I think your confusion is focused on the concept of SQLAlchemy instrumented descriptors, as it seems you're expecting the SQLAlchemy column-mapped descriptor to "wrap" an existing descriptor. This is not how it works. SQLAlchemy does not populate instance state using getattr()/setattr(), in the default case it populates __dict__ directly. The dictionary which it uses can be wrapped with a user- defined "proxying" dictionary but that's not an API you need to get involved with. By moving all low-level operations to __dict__ and all in-python operations to instrumented descriptors, the separation of event-producing attribute access and direct en-masse state access is clear, and the very high-volume activity of populating object state is performed without the overhead of setattr() or event production. The "synonym" model is provided so that a user-defined descriptor and a SQLAlchemy-column mapped descriptor can co-exist, but instead of being wrapped, they use different names. So usage of the model means: one descriptor maps to the column and is entirely generated by SQLAlchemy, the other is your custom descriptor and SQLAlchemy places a proxy around it to provide class-level behavior like Foo.bar == somevalue (which you also might want to customize, but that's a different issue). Your custom descriptor is the public face of the attribute, and communicates with the value that exists in the database using the column-mapped descriptor, which is usually treated as private. Symmetric set/get behavior is provided by the user-defined descriptor as the sole public interface. So since you'd like to refer to the *translated* attribute as "timeunits", i think you'd want to configure this way: class MyClass(object): ... timeunits = property(_get, _set) mapper(MyClass, table, properties={ "_timeunits":table.c.time_units, "timeunits": synonym("_timeunits") }) which will map the original "time_units" column to the mapped attribute "_timeunits", and the "timeunits" descriptor will provide class-level comparison behavior (i.e. MyClass.timeunits == 5). the map_column flag does not apply here since you are naming your descriptor something different than the original mapped column. The column-mapped attribute "_timeunits" is generally treated as "private" within the application space since it represents directly the "raw" data that is populated/retrieved to/from the database. you can also leave "time_units" mapped under its own name: mapper(MyClass, table, properties={ "timeunits": synonym("time_units") }) in which case your descriptor would communicate raw values to/from the "time_units" attribute, which is mapped automatically to its own name. Also consider that direct translation of a single column can be accomplished at the Table level using a custom TypeDecorator. If you went with that route, there would be no need to use synonym() or custom descriptors. --~--~---------~--~----~------------~-------~--~----~ 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 sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---