having a composite primary key implies that each row contains a unique
identity. So you'd create a copy of your mapped instance as a new
object and save() that to the session. You can add a
"create_new_version()" method to your class which does something along
the lines of:
class MyObject(object):
def create_new_version(self):
v = MyObject()
for k in ['attr1', 'attr2', 'attr3', ...]:
setattr(v, getattr(self, k))
return v
if you wanted to attempt to "force" such a change on an existing
object such that it becomes an insert again, we don't have a "public"
API for that right now. the "non-public" way would look like:
sess.expunge(myobject)
del myobject._instance_key
sess.save(myobject)
As it turns out, the "_instance_key" attribute is probably not going
to be writable in that way in the next 0.4 release (although we might
have to maintain it in such a way throughout 0.4 if people are already
relying on tricks like that).
But I think just sticking with standard ORM semantics and making a
simple copy method is the most straightforward and readable approach.
That way, creating a new version is as easy as:
session.save(myobject.create_new_version())
On Mar 25, 11:04 pm, Michael Robellard <[EMAIL PROTECTED]> wrote:
> I am working on creating some tables that are versionable and what I
> wanted to do was have a Composite Primary Key
> where the id is the sequence and the vernum is the version number that
> tracks the changes. next_version is supposed to be the max of all
> version numbers for the id + 1. something along the lines of:
>
> nodes_table = Table('nodes', metadata,
> Column('id', PGBigInteger, Sequence('node_id_seq'),
> primary_key=True),
> Column('owner_id', Integer,
> ForeignKey('users.id')),
> Column('created', DateTime,
> default=func.current_timestamp()),
> Column('modified', DateTime,
> default=func.current_timestamp(), onupdate=func.current_timestamp()),
> Column('status', String(50)),
> Column('type', String(50), nullable=False),
> )
>
> versionnodes_table = Table('versionnodes', metadata,
> Column('id', PGBigInteger,
> ForeignKey('nodes.id'), primary_key=True),
> Column('vernum', Integer, primary_key=True,
> default=1),
> Column('modified_by_id', Integer,
> ForeignKey('users.id'))
> )
>
> mapper(Node, nodes_table, polymorphic_on=nodes_table.c.type,
> polymorphic_identity='Node',
> properties={'childnodes':relation(Node,
> secondary=node_relation_table,
>
> primaryjoin=nodes_table.c.id==node_relation_table.c.id1,
>
> secondaryjoin=nodes_table.c.id==node_relation_table.c.id2,
> backref='parentnodes'),
> 'owner':relation(User)
> }
> )
> mapper(VersionNode, versionnodes_table, inherits=Node,
> polymorphic_identity='versionnode',
> properties={'next_version' :
> column_property(select([func.max(versionnodes_table.c.vernum)+1],
> versionnodes_table.c.id==nodes_table.c.id).label('next_version')),
> 'modified_by' : relation(User)
> }
> )
>
> what I am trying to figure out is how to set it up so that when a
> change is made to a versionnode it is saved as a new record instead of
> issuing an update on the current record. I have looked at using a
> MapperExtension but since a before_update can't change the flush, I
> don't think that will work. I also looked at a SessionExtension but I
> couldn't figure out how to make those work. Any ideas would be very
> helpful.
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---