Posted By


arski7 on 09/27/07

Tagged


Statistics


Viewed 487 times
Favorited by 0 user(s)

Related snippets


SqlAlchemy Versionable


/ Published in: Python
Save to your folder(s)

Not sure if this is working or not?


Copy this code and paste it in your HTML
  1. """
  2. Test of Versionable using extensions
  3.  
  4. Why does the before_update or before_insert not cause the
  5. items added to the lists to save? If you call save
  6. twice they do?
  7. """
  8.  
  9. from sqlalchemy import *
  10. from sqlalchemy.orm import *
  11.  
  12. metadata = MetaData('sqlite://')
  13.  
  14. #######
  15. class VersionExt(MapperExtension):
  16. """will update changes"""
  17. def before_update(self, mapper, connection, instance):
  18. instance._doversion()
  19. return EXT_CONTINUE
  20.  
  21. def before_insert(self, mapper, connection, instance):
  22. instance._doversion()
  23. return EXT_CONTINUE
  24.  
  25.  
  26. version_table = Table("version", metadata,
  27. Column("id", Integer, primary_key=True),
  28. Column('assoc_id', None, ForeignKey('version_associations.assoc_id')),
  29. Column("whatchanged", String(255), nullable=False),
  30. Column("version", Integer),
  31. )
  32.  
  33.  
  34. ## association table
  35. version_associations_table = Table("version_associations", metadata,
  36. Column('assoc_id', Integer, primary_key=True),
  37. Column('type', String(50), nullable=False),
  38. Column('version', Integer, default=0),
  39. )
  40.  
  41. class Version(object):
  42. def __init__(self, chg):
  43. self.whatchanged = chg
  44. member = property(lambda self: getattr(self.association, '_backref_%s' % self.association.type))
  45.  
  46. class VersionAssoc(object):
  47. def __init__(self, name):
  48. self.type = name
  49.  
  50. def versionable(cls, name, uselist=True):
  51. """versionable 'interface'.
  52.  
  53.  
  54. """
  55. mapper = class_mapper(cls)
  56. table = mapper.local_table
  57. mapper.add_property('version_rel', relation(VersionAssoc, backref='_backref_%s' % table.name))
  58.  
  59. if uselist:
  60. # list based property decorator
  61. def get(self):
  62. if self.version_rel is None:
  63. self.version_rel = VersionAssoc(table.name)
  64. return self.version_rel.versions
  65. setattr(cls, name, property(get))
  66. else:
  67. # scalar based property decorator
  68. def get(self):
  69. return self.version_rel.versions[0]
  70. def set(self, value):
  71. if self.version_rel is None:
  72. self.version_rel = VersionAssoc(table.name)
  73. self.version_rel.versions = [value]
  74. setattr(cls, name, property(get, set))
  75.  
  76. mapper(Version, version_table)
  77.  
  78. mapper(VersionAssoc, version_associations_table, properties={
  79. 'versions':relation(Version, backref='association'),
  80. })
  81.  
  82. ######
  83. # sample # 1, users
  84.  
  85. users = Table("users", metadata,
  86. Column('id', Integer, primary_key=True),
  87. Column('name', String(50), nullable=False),
  88. # this column ties the users table into the change association
  89. Column('assoc_id', None, ForeignKey('version_associations.assoc_id'))
  90. )
  91.  
  92. class User(object):
  93. def _doversion(self):
  94. v1 = Version('what was changed?')
  95. self.versions.append(v1)
  96. v1.version = 1
  97. print ' in _doversion '
  98.  
  99. mapper(User, users, extension=VersionExt())
  100. versionable(User, 'versions', uselist=True)
  101.  
  102. ######
  103. # use it !
  104. metadata.create_all()
  105.  
  106. u1 = User()
  107. u1.name = 'bob'
  108.  
  109.  
  110. sess = create_session()
  111. sess.save(u1)
  112. sess.flush()
  113. # uncommenting these saves causes the versions to now be saved?
  114. # sess.save(u1)
  115. # sess.flush()
  116. sess.clear()
  117.  
  118. # query objects, get their versions
  119.  
  120. bob = sess.query(User).filter_by(name='bob').first()
  121. print [v.whatchanged for v in bob.versions]
  122. if bob.versions:
  123. print 'bob changed: %s ct = %s ' % (bob.versions[0].whatchanged, len(bob.versions))
  124. else:
  125. print 'no versions'

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.