allow the possibility of column-level "default" values to populate before persistence (new event + recipe)
In declarative mode, you are able to write something like:
class Person(DeclarativeBase):
status = Column(Unicode(20), nullable=False, default=u'alive')
Unfortunately, the "default" parameter is only taken into account when inserting the Person into the database. It means that, until you flush() the session, querying the "status" attribute will return None rather than the default value. It would be handier if the descriptor was smart enough to return the default value when it hasn't been set.
Comments (8)
-
repo owner -
repo owner let me clarify why its not a trivial behavioral change to make defaults fire off on first ORM attribute access in all cases (as an optional behavior, its not a problem at all).
The example above is a straight string value, but "default" accommodates Python functions as well as SQL expressions too. The fact that you can have a SQL expression there automatically makes consistent behavior here impossible. If a new object is not attached to a session, accessing the attribute would require an error raise for a SQL-based default.
If the object is present in the session, accessing the "status" variable could either execute the SQL expression standalone, or it could perform a flush() and refetch from the database. It might seem like the former is appropriate, except it is not always - the default function may be a context-sensitive function which draws upon the other values in the
ExecutionContext
. It might be a timestamp representing the time that the full row was inserted. It also can in some cases result in many more round trips than the "flush()" approach would have, such as many columns with defaults firing off individually that would otherwise be executed with a single INSERT and SELECT of the whole row. on the other hand defaulting to an implicit flush() is a huge surprise in a wide range of scenarios - automatic flushing of pending objects attached to a session is a big source of problems as the object may not have all required attributes populated.The proposed feature is also a big behavioral change for a huge number of applications and would probably cause a lot of breakage and upgrade headaches, for any application which is expecting the default value of
None
which operates right now.It's not controversial at all though to use an attribute extension to provide a pre-flush default.
-
repo owner and let me correct myself further that
AttributeExtension
doesn't allow this to be implemented at the moment. you'd have to use descriptors. a possibleAttributeExtension
approach would be acreate_default()
method added to its definition, but its signature and behavior would need to be carefully considered. -
repo owner - add an init_scalar event, which allows us to build
out default-setting recipes such as one that allows us to actively
read column-level defaults. References
#1311
→ <<cset ee79d879e480>>
- add an init_scalar event, which allows us to build
out default-setting recipes such as one that allows us to actively
read column-level defaults. References
-
repo owner see ee79d879e4800d0abf7 for the beginning of this implemented as an event plus a recipe. This feature is difficult as a generic built-in but fairly straightforward as a recipe.
-
repo owner - changed milestone to 1.1
- changed title to allow the possibility of column-level "default" values to populate before persistence
- edited description
-
repo owner - changed title to allow the possibility of column-level "default" values to populate before persistence (new event + recipe)
-
repo owner - changed status to resolved
Add an init_scalar event for attributes
This allows us to build default-setting recipes such as one that allows us to actively read column-level defaults. An example suite is also added.
Change-Id: I7b022d52cc89526132d5bc4201ac27fea4cf088d Fixes:
#1311→ <<cset e28b44813721>>
- Log in to comment
this can be accomplished using an AttributeExtension. that's not a comment on the default behavior of Column with default however.