Should that be ‘a’ or ‘an’ SQLAlchemy object?
My current CMS project is based on creating templates in the back-end, and then using these to produce ‘inherited’ objects with the same attributes.

I quickly found that it’s surprisingly tricky to grab a template object using SQLAlchemy, and copy it into a similar, but separate, entity. Using the Python ‘copy’ function confuses SQLAlchemy - when you try to save it, it thinks it is merely a representation of the original (template) object.
Here’s how I create separate ‘clones’ from my template objects, defining a function on the object itself:
def clone (self, source, table):
for c in table.c:
if not c.name.endswith('id'):
setattr(self, c.name, getattr(source, c.name))
Here’s a usage example:
template_meta = self.session.query(Meta).filter(and_(Meta.is_template == 1, Meta.id == id)).one()
new_meta = Meta(new_object.id)
new_meta.clone(template_meta, table_meta)
The clone function takes the object’s table as an argument, so that only the basic column values are copied. The table object has an attribute called c - these are the table columns in long form (eg. meta.id, meta.title, etc). Using c.name gives us just the name of the column.
Looping through the source object’s attributes would result in SQLA attributes and any child objects being copied too, which is not what we want.
Notice too that anything ending in ‘id’ is ignored - otherwise we would get the original object’s relationships - again this is not what I want in this situation. The new object should have its own relationships.
Post a Comment