I have an ActiveMapper class which looks like this: class OraJob(ActiveMapper): class mapping: id = column(Integer, primary_key = True) job_type = column(Unicode(30)) source_type = column(Unicode(30)) ...
Attributes are used / should be used in readonly manner. All updates to database are happening via specialized Oracle procedures (that in turn use AUTONOMOUS_TRANSACTION). This is so because changes to this object must be committed to database no mater what is the outcome of main transaction and must be written immediately so I can track the progress of job from outside. One of update functions looks like this: def start_job(self, status_message, expected_steps = None): self.status_message = status_message if expected_steps is not None: self.expected_steps = expected_steps orapro.tool_job.start_job( # This calls my Oracle function start_job() i_job_id = self.id ,i_status_message = status_message ,i_expected_steps = expected_steps ).execute(connection()) self.status = u"RUNNING" My problem is in: self.status = something because this causes the object to get dirty and it gets updated when I flush the session. This sql update in turn locks the row, and my next call to specialized update function (ie. finish_job) fails with a deadlock (remember, specialized update is inside autonomous transaction). My current solution is to expunge(self) when calling any of specialized update functions: def finish_job(self, status_message, warnings, errors, extra = None): self._expunge() if self.status != u'RUNNING': raise RuntimeError("You can only finish a job if it is in RUNNING state.") self.status_message = status_message self.warnings = warnings self.errors = errors self.extra = extra orapro.tool_job.finish_job( i_job_id = self.id ,i_status_message = status_message ,i_warnings = warnings ,i_errors = errors ,i_extra = extra ).execute(connection()) self.status = u"FINISHED" def _expunge(self): try: self.__expunged except AttributeError: session.expunge(self) self.__expunged = True This barely works because currently I'm calling flush only *after* one of my specialized update functions had a chance to expunge itself. My next try was to create object with _sa_session=None... How can I go about solving this problem: 1. somehow make attributes readonly for outside world but let me change attributes from inside customized update function without affecting dirty state 2. expunge object from session inside __init__ (if it is possible at all) 3. expunge object from session on each call to update function 4. create object somehow so it doesn't end up inside session (is it enough to say _sa_session=None when creating object) 5. something else It seems that "readonly" attribute would be the best solution, because the only interface for changing job state is through several well defined functions (start/update/finish/fail) Thanks, Tvrtko --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---