the ORM can’t persist any value for “delivery_method” unless there is an actual attribute set event.
If you are saying session.add(DeliveryAddress()) and flushing, these are the options for “deliveryaddress.delivery_method”:
1. the value has no setting and is not present in the INSERT statement - it gets set as NULL in the DB.
2. the value has no setting, but you have a python or server side default set up on it. At before_insert() time, that value is still None so that can’t be what you’re doing.
3. The DeliveryAddress() constructor sets delivery_method, so there’s an attribute set event.
So I can only guess that you’re looking for the None here? I guess there’s some odd relationship to this Settings object such that it already exists in the DB with some other value such that you actually need to positively set None. In any case, to have something happen upon DeliveryAddress(), you can either place that logic as part of __init__() (regular Python!) or if that bothers you, you can also set up the init() event for the DeliveryAddress class.
class BeforeInsertMixin(object):
@classmethod
def __declare_last__(cls):
if hasattr(cls, ‘before_insert’):
event.listen(cls, ‘before_insert’, cls.before_insert)
Base = declarative_base(cls=BeforeInsertMixin)
class DeliveryAddress(Base):
# …
@classmethod
def before_insert(cls, mapper, connection, target):
#…
if you want to change the signature, no problem:
class BeforeInsertMixin(object):
@classmethod
def __declare_last__(cls):
if hasattr(cls, ‘before_insert’):
@event.listens_for(cls, ‘before_insert’)
def before_insert(mapper, connection, target):
target.before_insert(object_session(target))
class DeliveryAddress(Base):
# …
def before_insert(self, session):
#…
These are “frameworky” types of hooks that SQLAlchemy would prefer to remain agnostic of, but it provides for you all the components you need to create whatever system of hooks you’d like.