diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-06-10 23:53:05 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-06-10 23:53:05 -0400 |
commit | fe6827b88837b264f726e17891eb37e2b7e38a83 (patch) | |
tree | 0492dd6ef4ef80d1a5751484912a087795357606 | |
parent | ee79d879e4800d0abf7abcd594c37b1cd833ac91 (diff) | |
download | sqlalchemy-ticket_1311.tar.gz |
- add some more detailticket_1311
-rw-r--r-- | examples/custom_attributes/active_column_defaults.py | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/examples/custom_attributes/active_column_defaults.py b/examples/custom_attributes/active_column_defaults.py index 5f2d7b749..9560c3dc0 100644 --- a/examples/custom_attributes/active_column_defaults.py +++ b/examples/custom_attributes/active_column_defaults.py @@ -5,8 +5,15 @@ def configure_listener(mapper, class_): """Establish attribute setters for every default-holding column on the given mapper.""" + # iterate through ColumnProperty objects for col_attr in mapper.column_attrs: + + # look at the Column mapped by the ColumnProperty + # (we look at the first column in the less common case + # of a property mapped to multiple columns at once) column = col_attr.columns[0] + + # if the Column has a "default", set up a listener if column.default is not None: default_listener(col_attr, column.default) @@ -14,7 +21,11 @@ def configure_listener(mapper, class_): def default_listener(col_attr, default): """Establish a default-setting listener. - Given a class_, attrname, and a :class:`.ColumnDefault` instance. + Given a class_, attrname, and a :class:`.DefaultGenerator` instance. + The default generator should be a :class:`.ColumnDefault` object with a + plain Python value or callable default; otherwise, the appropriate behavior + for SQL functions and defaults should be determined here by the + user integrating this feature. """ @event.listens_for(col_attr, "init_scalar", retval=True, propagate=True) @@ -24,17 +35,24 @@ def default_listener(col_attr, default): # the callable of ColumnDefault always accepts a context # argument; we can pass it as None here. value = default.arg(None) - elif default.is_clause_element or default.is_sequence: - # the feature can't easily support this. This + elif default.is_scalar: + value = default.arg + else: + # default is a Sequence, a SQL expression, server + # side default generator, or other non-Python-evaluable + # object. The feature here can't easily support this. This # can be made to return None, rather than raising, # or can procure a connection from an Engine # or Session and actually run the SQL, if desired. raise NotImplementedError( "Can't invoke pre-default for a SQL-level column default") - else: - value = default.arg + # set the value in the given dict_; this won't emit any further + # attribute set events or create attribute "history", but the value + # will be used in the INSERT statement dict_[col_attr.key] = value + + # return the value as well return value @@ -44,6 +62,7 @@ if __name__ == '__main__': from sqlalchemy.orm import Session from sqlalchemy.ext.declarative import declarative_base import datetime + import time Base = declarative_base() @@ -62,7 +81,8 @@ if __name__ == '__main__': w1 = Widget() - # not persisted at all, default values are present + # not persisted at all, default values are present the moment + # we access them assert w1.radius == 30 current_time = w1.timestamp assert ( @@ -74,7 +94,8 @@ if __name__ == '__main__': sess.add(w1) sess.commit() - # data is persisted + # data is persisted. The timestamp is also the one we generated above; + # e.g. the default wasn't re-invoked later. assert ( sess.query(Widget.radius, Widget.timestamp).first() == (30, current_time) |