On Nov 29, 2010, at 8:28 AM, Naresh Khalasi wrote:

> Hi,
> 
> After some more internal discussions we tried and realized that the version 
> col is not really required at the child table level.
> The second commit in the sample code fails because the version value on the 
> parent row has already moved ahead.
> 
> Please confirm if the understanding/conclusion is correct.

the version col would be just on the base table, that's correct, since no child 
row should ever exist without a parent row, which establishes the version.  As 
far as what happens when version_id_col is placed on two tables internally, I'd 
have to try that out to see why you got silent failure on that.  We try to add 
warnings or exceptions for the wide variety of configurational mistakes that 
are possible.   Ideally the version_id_col on both parent and child would 
actually work as expected, i.e. both columns get populated equally.

Looking at the sample code, the structure of change/commit created at the end 
appears to be the classic case the version id col was designed to detect - 
concurrent modification.   The most recent 0.6 release renamed the exception 
"StaleDataError" to prevent confusion with threading/process issues, which 
aren't necessary to produce this condition.





> 
> Regards,
> Naresh
> 
> On Mon, Nov 29, 2010 at 2:21 PM, Naresh <nkhal...@vayana.in> wrote:
> Hi,
> 
> We have a parent class/table (Notification/notifications) and a child
> class/table(BusinessNotification/business_notifications).
> Both of them have a version_id_col defined.
> We are facing ConcurrentModificationException errors for the  model at
> the end of the mail.
> The problem is because the update state generated uses 'None' a the
> value for notifications.version column.
> 
> We tried removing the version_id_col mapper arg in the child class -
> BusinessNotification and then the error went away and the update
> statement used the correct version column value to update.
> 
> So, firstly we are wondering how do we fix the situation that we can
> have a version_id_col in the child class/table as well?
> 
> Upon further investigations,  we noticed that in the other parts of
> the application we used the following approach.
> 
> parent_table = Table( ... )
> class Parent(DeclarativeBase):
>    __table__ = parent_table
>    __mapper_args__ = {'polymorphic_on': parent_table.c.type,
> 'version_id_col': parent_table.c.version}
> 
> child1_table = Table( ... )
> class Child1(DeclarativeBase)
>    __table__ = child1_table
>    __mapper_args__ = {'polymorphic_identity':'c1',
> 'version_id_col':child1_table.c.version_num}
> 
> With the above style of coding our models, we don't get
> ConcurrentModificationException, but any update statement to the
> parent_table does not use version column.
> 
> 
> Please throw some light on these behaviors.
> 
> Regards,
> Naresh
> 
> P.S. The model and sample client code follows.
> ------------------
> 
> class Notification(DeclarativeBase):
>    """This entity represents the notifications saved for sending
> later """
>    __tablename__ = 'notifications'
>    __table_args__ =  {"mysql_engine":"InnoDB",
>                       "mysql_row_format":"DYNAMIC",
>                       "mysql_charset":"utf8"}
> 
>    id = Column(bigint, primary_key=True, autoincrement=False)
>    entid = Column(bigint, ForeignKey('enterprises.entid',
> name='fk_notifn_entid'), nullable=False)
>    notification_type = Column(types.String(30), nullable=False)
>    source = Column(types.String(30), nullable=False)
>    data  = Column(text_type, nullable=False)
>    status = Column(types.String(12), nullable=False, default='new')
>    created_on = Column(types.DATETIME, nullable=False,
> default=func.current_timestamp())
>    last_updated = Column(types.DATETIME, nullable=True,
> onupdate=func.current_timestamp())
>    version = Column(types.SMALLINT, nullable=False, default=0)
>    __mapper_args__ = {'polymorphic_on': notification_type,
> 'polymorphic_identity':'incident', 'version_id_col': version}
> 
> 
> class BusinessNotification(Notification):
>    """This entity represents the business notifications """
>    __tablename__ = 'business_notifications'
>    __table_args__ =  {"mysql_engine":"InnoDB",
>                       "mysql_row_format":"DYNAMIC",
>                       "mysql_charset":"utf8"}
> 
>    notification_id = Column(bigint, ForeignKey('notifications.id',
> name='fk_bn_notificationid'), primary_key=True, autoincrement=False)
>    event_id = Column(bigint, ForeignKey('doc_events.id',
> name='fk_bn_eventid'), nullable=True)
>    created_on = Column(types.DATETIME, nullable=False,
> default=func.current_timestamp())
>    last_updated = Column(types.DATETIME, nullable=True,
> onupdate=func.current_timestamp())
>    version_num = Column(types.SMALLINT, nullable=False, default=0)
>    __mapper_args__ = {'polymorphic_identity':'event',
> 'version_id_col': version_num}
> #    __mapper_args__ = {'polymorphic_identity':'event'}
> 
> 
> if __name__ == '__main__':
>    try :
>        qry = meta.Session().query(BusinessNotification).filter(and_(
> 
> BusinessNotification.status=='new',
> 
> BusinessNotification.created_on < now()))
>        qry = qry.order_by(BusinessNotification.created_on)
>        all_notifications = qry.all()
>        for notification in all_notifications :
>            # some business logic to trigger status update
>            notification.status='in_progress'
>        meta.Session().commit()
>    except Exception as ex :
>        log.error("Error Identifying Notification Recipients")
>        log.exception(ex)
>        meta.Session().rollback()
>    finally :
>        meta.Session.remove()
> 
> 
> 
> -- 
> Naresh Khalasi | Vayana Services (http://www.vayana.in) | +91-9892294598
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> <sqlq.py>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to