On Mar 12, 2012, at 2:06 PM, Paddy Mullen wrote:
> I am trying to create a column that stores sha1sums of content, and
> allows easy programatic access of that content. I would like my table
> definition to look like this
>
> class Picture(Base):
> content = sa.Column('content_sha1sum', DataColumn(se))
>
> I would like to be able to create instances of pictures like this
>
> p = Picture()
> p.content(binary_image_string)
>
> I only want to save the sha1sum to the database, DataColumn takes care
> of computing the sha1sum, and actually saving the content to s3 or the
> filesystem. I also want DataColumn to be a deferred column, I can do
> that with deferred
>
> All good so far.
>
> What I can't do, or can't do cleanly is figure out how to access the
> sha1sum behind content
>
> p = s.query(Picture).all().first()
>
> p.content_sha1sum
> p.content_direct_url
>
> Where direct_url is a function of the sha1sum. The problem with a
> custom column is, I can't make sha1sum loading eager and the call to
> s3/filesystem lazy, this means that every re-hydration of a Picture
> requires a read from the filesystem.
>
> There are a couple of ways that I could go. First would be to store
> the sha1sum directly as a regular String column, and create properties
> of names "content" and "content_direct_url". Another method would be
> to use a mixin, but that is a bit ugly.
>
> What I really want is a way to add all 3 properties with a single
> line. I'm willing to modify DeclarativeMeta .
So really the problem here is not the mechanics of things, you just want a very
particular way of declaring it in your model.
I'm a strong proponent of mixins, but I suppose here the "ugly" part is that
the mixin doesn't really grant a nice way of defining what the name of the
column/attribute would be, and you just want a single attribute that becomes
several.
So if you really want totally "magic" kinds of configuration, that is, you set
up just one attribute on the class that magically creates two others, the
straight path to this, without having to hack into metaclasses, is to use
events. The blog post at
http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm/ illustrates a technique
for doing this. Using the "mapper_configured" event you receive an event
whenever a mapper is finished initializing itself. At that point you can scan
through the class and/or mapping and apply any additional things you want to
apply.
Another path is to override __mapper_cls__, which is a way of receiving a hook
as soon as declarative sets up the mapping for the class. An example of using
this method is in the distro in examples/declarative_reflection/. You'd use
similar techniques, and at that stage you can also augment what gets sent to
mapper() and add columns directly on the Table. The advantage to
__mapper_cls__ is that you get to set up the class early, while the advantage
to the mapper_configured event is that the approach remains discrete and
separate from everything else going on, and also has access to the full
configuration of other mappers.
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
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.