python - How to update parent table timestamp when child table is modified? -


how can update parent timestamp when child table modified?

i use parent table timestamp checking if rest client should update it's local version of these tables.

class parent(db.model):     id = db.column(db.integer, primary_key=true)     version = db.column(db.integer)     timestamp = db.column(db.datetime,                           default=datetime.utcnow,                           onupdate=datetime.utcnow)     childs = db.relationship('children',                              backref='parent',                              lazy='dynamic',                              cascade="all, delete-orphan")  class children(db.model):     id = db.column(db.integer, primary_key=true)     version = db.column(db.integer)     timestamp = db.column(db.datetime,                           default=datetime.utcnow,                           onupdate=datetime.utcnow)     parent_id = db.column(db.integer, db.foreignkey('parent.id'), nullable=false) 

and test this:

    db.create_all()     parent = parent(version=1)     child = children(version=1, parent=parent)     db.session.add_all([parent, child])     db.session.commit()     print "parent timestamp: %s, child timestamp %s" % (parent.timestamp, child.timestamp)     previous_timestamp = parent.timestamp     parent.version = 2     db.session.add(parent)     db.session.commit()     assert parent.timestamp != previous_timestamp # works     print "parent timestamp: %s, child timestamp %s" % (parent.timestamp, child.timestamp)     previous_timestamp = parent.timestamp     child.version = 2     db.session.add(child)     db.session.commit()     # fails. parent timestamp not updated when child modified     assert parent.timestamp != previous_timestamp     print "parent timestamp: %s, child timestamp %s" % (parent.timestamp, child.timestamp) 

use sqlalchemy events answered question.

see below self-contained flask example using in-memory sqlite database , data models (note i've changed children class child , relationship childs children.

browse 3 routes /insert_child/, /delete_child/ , /update_child/ see parent timestamp change.

from datetime import datetime flask import flask flask.ext.sqlalchemy import sqlalchemy, event  app = flask(__name__) app.config['debug'] = true app.config['secret_key'] = 'super-secret' app.config['sqlalchemy_database_uri'] = 'sqlite:///:memory:' app.config['sqlalchemy_echo'] = true db = sqlalchemy(app)   class parent(db.model):     id = db.column(db.integer, primary_key=true)     version = db.column(db.integer)     timestamp = db.column(db.datetime,                           default=datetime.utcnow,                           onupdate=datetime.utcnow)     children = db.relationship('child',                              backref='parent',                              lazy='dynamic',                              cascade="all, delete-orphan")   class child(db.model):     id = db.column(db.integer, primary_key=true)     version = db.column(db.integer)     timestamp = db.column(db.datetime,                           default=datetime.utcnow,                           onupdate=datetime.utcnow)     parent_id = db.column(db.integer, db.foreignkey('parent.id'), nullable=false)   @event.listens_for(parent.children, 'append') @event.listens_for(parent.children, 'remove') def receive_append_or_remove(target, value, initiator):     # update when child added or removed     target.timestamp = datetime.utcnow()   @event.listens_for(child.version, 'set') def receive_attribute_change(target, value, oldvalue, initiator):     # update when child's "version" attribute set     if target.parent:         target.parent.timestamp = datetime.utcnow()   def render_html():     _html = ""     parents = parent.query.all()     parent in parents:         _html += "<h4>parent : {version}; timestamp: {timestamp}</h4>".format(version=parent.version, timestamp=parent.timestamp)         _html += "<ul>"         child in parent.children:             _html += "<li>child : {version}; timestamp: {timestamp}</li>".format(version=child.version, timestamp=child.timestamp)         _html += "</ul>"     return _html   @app.route('/') def index():     return render_html()   @app.route('/insert_child/') def insert_child():     parent = parent.query.first()     child_version = parent.children.count() + 1     child = child(version=child_version, parent=parent)     db.session.add(child)     db.session.commit()     return render_html()   @app.route('/delete_child/') def delete_child():     parent = parent.query.first()     if parent.children.count() > 0:         last_child = parent.children[-1]         parent.children.remove(last_child)         db.session.commit()     return render_html()   @app.route('/update_child/') def update_child():     parent = parent.query.first()     first_child = parent.children[0]     first_child.version += 1     db.session.commit()     return render_html()   @app.before_first_request def before_first_request():     db.drop_all()     db.create_all()      parent = parent(version=1)     child = child(version=1, parent=parent)     db.session.add_all([parent, child])     db.session.commit()  if __name__ == '__main__':     app.run(debug=true) 

Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -