Can I "touch" a SQLAlchemy record to trigger "onupdate"?
<p>Here's a SQLAlchemy class:</p>

<pre><code>class MyGroup(Base):
    __tablename__ = 'my_group'
    group_id = Column(Integer, Sequence('my_seq'), primary_key=True)
    group_name = Column(String(200), nullable=False, index=True)
    date_created = Column(DateTime, default=func.now())
    date_updated = Column(DateTime, default=func.now(), onupdate=func.now())
</code></pre>

<p>Anytime I add a group_name or (for example) update the group_name, the <code>date_updated</code> field will get updated.  That's great.</p>

<p>But sometimes there are cases where I want to mark a group as "updated" even if the group record itself did not change (for example, if data in a different but related table is updated).  </p>

<p>I could do it manually:</p>

<pre><code>group = session.query(SgmGroup).filter(SgmGroup.group_name=='Some Group').one()
group.date_updated = datetime.datetime.utcnow()
session.commit()
</code></pre>

<p>but I'd really rather let the model do it in its own way, rather than recreate a Python process to manually update the date.  (For example, to avoid mistakes like where maybe the model uses <code>now()</code> while the manual function mistakenly uses <code>utcnow()</code>)</p>

<p>Is there a way with SQLAlchemy to "touch" a record (kind of like UNIX <code>touch</code>) that wouldn't alter any of the record's other values but would trigger the <code>onupdate=</code> function?</p>

<p>I haven't looked at the source but from the <a href="http://docs.sqlalchemy.org/en/latest/core/metadata.html#sqlalchemy.schema.Column.params.onupdate" rel="nofollow">docs</a> it seems that this is only triggered by issuing a SQL <code>UPDATE</code> command:</p>

<blockquote>
  <p>onupdate â A scalar, Python callable, or ClauseElement representing a default value to be applied to the column within UPDATE statements, which wil be invoked upon update if this column is not present in the SET clause of the update. This is a shortcut to using ColumnDefault as a positional argument with for_update=True.</p>
</blockquote>

<p>If your concern is ensuring that your "touch" uses the same function as the  <code>onupdate</code> function you could define a method on your model to perform the touch and have the <code>onupdate</code> parameter point this method.</p>

<p>I think something like this would work:</p>

<pre><code>class MyGroup(Base):
    __tablename__ = 'my_group'
    group_id = Column(Integer, Sequence('my_seq'), primary_key=True)
    group_name = Column(String(200), nullable=False, index=True)
    date_created = Column(DateTime, default=func.now())
    date_updated = Column(
        DateTime,     
        default=self.get_todays_date(),
        onupdate=self.get_todays_date())

    def get_todays_date(self):
        return datetime.datetime.utcnow()

    def update_date_updated(self):
        self.date_updated = self.get_todays_date()
</code></pre>

<p>You could then update your record like this:</p>

<pre><code>group.update_date_updated()
session.commit()
</code></pre>

python sqlalchemy sql-update