id,summary,reporter,owner,description,type,status,priority,component,severity,resolution,keywords,cc,release 11933,IntegrityError,Jeffrey.Ratcliffe@…,François Granade,"Some ticket updates (reproducibly) produce the following error (I have xxxed out the user names): Oops… Trac detected an internal error: IntegrityError: UNIQUE constraint failed: ticket_change.ticket, ticket_change.time, ticket_change.field This is probably a local installation issue. Found a bug in Trac? If you think this should work and you can reproduce the problem, you should consider creating a bug report. Note that the following plugins seem to be involved: TicketImport, TracAccountManager Please report this issue to the plugin maintainer. Before you do that, though, please first try searching for similar issues, as it is quite likely that this problem has been reported before. For questions about installation and configuration of Trac or its plugins, please try the mailing list instead of creating a ticket. Otherwise, please ==== How to Reproduce ==== While doing a POST operation on `/importer`, Trac issued an internal error. ''(please provide additional details here)'' Request parameters: {{{ {'__FORM_TOKEN': u'01783ea1a906cec59efad846', 'action': u'import'} }}} User agent: `Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729)` ==== System Information ==== || '''`Trac`''' || `1.0.1` || || '''`Docutils`''' || `0.10` || || '''`Genshi`''' || `0.7 (with speedups)` || || '''`Pygments`''' || `1.6` || || '''`pysqlite`''' || `2.6.0` || || '''`Python`''' || `2.7.5 (default, Dec 13 2013, 10:35:27) ` [[br]] `[GCC 4.7.2]` || || '''`pytz`''' || `2013d` || || '''`setuptools`''' || `1.1.6` || || '''`SQLite`''' || `3.8.2` || || '''`jQuery`''' || `1.7.2` || ==== Enabled Plugins ==== || '''`BlackMagicTicketTweaks`''' || `0.12.2` || || '''`NavAdd`''' || `0.3` || || '''`SimpleMultiProject`''' || `0.0.4dev` || || '''`TicketImport`''' || `0.8.3` || || '''`TracAccountManager`''' || `0.4.4` || || '''`TracDateField`''' || `3.0.0dev` || || '''`TracMasterTickets`''' || `3.0.5dev` || ==== Python Traceback ==== {{{ Traceback (most recent call last): File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/web/main.py"", line 497, in _dispatch_request dispatcher.dispatch(req) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/web/main.py"", line 214, in dispatch resp = chosen_handler.process_request(req) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 86, in process_request encoding=req.session['importer.encoding']) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 130, in _do_import return self._process(filereader, get_reporter_id(req), ImportProcessor(self.env, req, uploadedfilename, tickettime)) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 401, in _process processor.end_process_row() File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/processors.py"", line 153, in end_process_row self._save_ticket(self.ticket) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/processors.py"", line 122, in _save_ticket db=self.db) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/ticket/model.py"", line 351, in save_changes self[name])) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/util.py"", line 121, in execute cursor.execute(query, params) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/util.py"", line 65, in execute return self.cursor.execute(sql_escape_percent(sql), args) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 78, in execute result = PyFormatCursor.execute(self, *args) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 56, in execute args or []) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 48, in _rollback_on_error return function(self, *args, **kwargs) IntegrityError: UNIQUE constraint failed: ticket_change.ticket, ticket_change.time, ticket_change.field }}} a new bug report describing the problem and explain how to reproduce it. {{{ Python Traceback Most recent call last: File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/web/main.py"", line 497, in _dispatch_request Code fragment:Line 492 try: 493 if not env and env_error: 494 raise HTTPInternalError(env_error) 495 try: 496 dispatcher = RequestDispatcher(env) 497 dispatcher.dispatch(req) 498 except RequestDone: 499 pass 500 resp = req._response or [] 501 except HTTPException, e: 502 _send_user_error(req, env, e) Local variables:Name Value dispatcher e IntegrityError('UNIQUE constraint failed: ticket_change.ticket, ... env env_error None req resp [] File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/web/main.py"", line 214, in dispatch Code fragment:Line 209 msg = _('Do you have cookies enabled?') 210 raise HTTPBadRequest(_('Missing or invalid form token.' 211 ' %(msg)s', msg=msg)) 212 213 # Process the request and render the template 214 resp = chosen_handler.process_request(req) 215 if resp: 216 if len(resp) == 2: # old Clearsilver template and HDF data 217 self.log.error(""Clearsilver template are no longer "" 218 ""supported (%s)"", resp[0]) 219 raise TracError( Local variables:Name Value chosen_handler chrome ctype 'application/x-www-form-urlencoded' err (, IntegrityError('UNIQUE constraint ... handler options {} req self File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 86, in process_request Code fragment:Line 81 if tickettime == 0: 82 raise TracError('No time set since preview, unable to import: please upload the file again') 83 84 return self._do_import(req.session['importer.uploadedfile'], int(req.session['importer.sheet']), 85 req, req.session['importer.uploadedfilename'], tickettime, 86 encoding=req.session['importer.encoding']) 87 88 else: 89 req.session['importer.uploadedfile'] = None 90 req.session['importer.uploadedfilename'] = None 91 Local variables:Name Value action u'import' req self tickettime 1408432532 File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 130, in _do_import Code fragment:Line 125 126 def _do_import(self, uploadedfile, sheet, req, uploadedfilename, tickettime, encoding=None): 127 filereader = get_reader(uploadedfile, sheet, self._datetime_format(), encoding=encoding) 128 try: 129 try: 130 return self._process(filereader, get_reporter_id(req), ImportProcessor(self.env, req, uploadedfilename, tickettime)) 131 finally: 132 filereader.close() 133 except: 134 # Unlock the database. This is not really tested, but seems reasonable. TODO: test or verify this 135 self.env.get_db_cnx().rollback() Local variables:Name Value encoding u'utf-8' filereader req self sheet 1 tickettime 1408432532 uploadedfile u'/tmp/tmp8cr4dT' uploadedfilename u'140818_task_update.xlsx' File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 401, in _process Code fragment:Line 396 processor.process_comment(row[commentfield]) 397 398 relativeticketvalues.append(dict([(f[1:].lower(), row[f]) 399 for f in relativeticketfields])) 400 401 processor.end_process_row() 402 row_idx += 1 403 404 405 # All the rows have been processed. Handle global stuff 406 for name in list(newvalues): Local variables:Name Value PatchedTicket add_sql_result cell '1848' cls column u'blocking' column_lower u'blocking' columns [u'id', u'blockedby', u'blocking'] commentfield None commentfields [] computedfields {'changetime': {'set': False, 'value': ""''(now)''""}, 'cc': {'set': False, ... customfields [u'blockedby', u'blocking', u'corrections', u'due_date', u'ftr', u'prof', ... db duplicate_summaries [] email None existingusers set([u'', u'xxxxxxx', u'xxxxxxxxx', u'xxxxxx', u'xxxxxxx', ... existingvalues {} f 'resolution' field {'name': u'work_data', 'format': u'wiki', 'value': '', 'label': u'Path to ... filereader idcolumn u'id' importedfields [u'id', u'blockedby', u'blocking'] lowercaseimportedfields [u'id', u'blockedby', u'blocking'] lowercaserelativeticketfields [] missingdefaultedfields ['changetime', 'priority', 'type', 'status', u'due_date', 'reporter', ... missingemptyfields ['cc', 'keywords', u'ftr', 'severity', u'spec_link', 'version', u'prof', ... missingfields ['changetime', 'cc', 'keywords', u'ftr', 'severity', u'spec_link', ... name u'xxxxxxxx' newusers [] newvalues {} notimportedfields [] ownercolumn None processor relativeticketfields [] relativeticketvalues [{}, {}, {}] reporter u'xxxxxxxxxx' row {u'id': '1846', u'blockedby': '1846', u'blocking': '1848'} row_idx 2 rows [{u'id': '1094', u'blockedby': '', u'blocking': '1813'}, {u'id': '1813', ... selects [('type', ), ('status', ticket ticket_id '1846' tracfields ['ticket', 'id', 'summary', 'reporter', 'owner', 'description', 'type', ... username u'xxxxxxx' File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/processors.py"", line 153, in end_process_row Code fragment:Line 148 149 self.ticket.insert(when=self._tickettime(), db=self.db) 150 self.added[self.ticket.id] = 1 151 else: 152 if self.ticket.is_modified() or self.comment: 153 self._save_ticket(self.ticket) 154 self.modified[self.ticket.id] = 1 155 156 self.crossref.append(self.ticket.id) 157 self.ticket = None 158 Local variables:Name Value self File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/processors.py"", line 122, in _save_ticket Code fragment:Line 117 else: 118 comment=None 119 ticket.save_changes(get_reporter_id(self.req), 120 comment, 121 when=self._tickettime(), 122 db=self.db) 123 124 def end_process_row(self): 125 126 if self.ticket.id == None: 127 if self.missingemptyfields: Local variables:Name Value comment u""''Batch update from file 140818_task_update.xlsx''"" self ticket with_comment True File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/ticket/model.py"", line 351, in save_changes Code fragment:Line 346 % name, (self[name], self.id)) 347 db(""""""INSERT INTO ticket_change 348 (ticket,time,author,field,oldvalue,newvalue) 349 VALUES (%s, %s, %s, %s, %s, %s) 350 """""", (self.id, when_ts, author, name, self._old[name], 351 self[name])) 352 353 # always save comment, even if empty 354 # (numbering support for timeline) 355 db(""""""INSERT INTO ticket_change 356 (ticket,time,author,field,oldvalue,newvalue) Local variables:Name Value author u'Jeffrey Ratcliffe' cnum '7' comment u""''Batch update from file 140818_task_update.xlsx''"" db name u'blockedby' num 6 old u'5' props_unchanged False replyto None row (1846, u'blockedby', u'1813, 1846') self ts 1408432129000000 when datetime.datetime(2014, 8, 19, 9, 15, 32, tzinfo= dql False params (1846, 1408432532000000L, u'xxxxxxxxx', u'blockedby', u'1813, ... query 'INSERT INTO ticket_change\n ... self File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/util.py"", line 65, in execute Code fragment:Line 60 return r 61 except Exception, e: 62 self.log.debug('execute exception: %r', e) 63 raise 64 if args: 65 return self.cursor.execute(sql_escape_percent(sql), args) 66 return self.cursor.execute(sql) 67 68 def executemany(self, sql, args): 69 if self.log: 70 self.log.debug('SQL: %r', sql) Local variables:Name Value args (1846, 1408432532000000L, u'xxxxxxxxxx', u'blockedby', u'1813, ... self sql 'INSERT INTO ticket_change\n ... File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 78, in execute Code fragment:Line 73 PyFormatCursor.__init__(self, con) 74 self.rows = [] 75 self.pos = 0 76 77 def execute(self, *args): 78 result = PyFormatCursor.execute(self, *args) 79 self.rows = PyFormatCursor.fetchall(self) 80 self.pos = 0 81 return result 82 83 def fetchone(self): Local variables:Name Value args ('INSERT INTO ticket_change\n ... self File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 56, in execute Code fragment:Line 51 raise 52 def execute(self, sql, args=None): 53 if args: 54 sql = sql % (('?',) * len(args)) 55 return self._rollback_on_error(sqlite.Cursor.execute, sql, 56 args or []) 57 def executemany(self, sql, args): 58 if not args: 59 return 60 sql = sql % (('?',) * len(args[0])) 61 return self._rollback_on_error(sqlite.Cursor.executemany, sql, Local variables:Name Value args (1846, 1408432532000000L, u'xxxxxxxxxx', u'blockedby', u'1813, ... self sql 'INSERT INTO ticket_change\n ... File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 48, in _rollback_on_error Code fragment:Line 43 sqlite_version_string = sqlite.sqlite_version 44 45 class PyFormatCursor(sqlite.Cursor): 46 def _rollback_on_error(self, function, *args, **kwargs): 47 try: 48 return function(self, *args, **kwargs) 49 except sqlite.DatabaseError: 50 self.cnx.rollback() 51 raise 52 def execute(self, sql, args=None): 53 if args: Local variables:Name Value args ('INSERT INTO ticket_change\n ... function kwargs {} self File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/web/main.py"", line 497, in _dispatch_request dispatcher.dispatch(req) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/web/main.py"", line 214, in dispatch resp = chosen_handler.process_request(req) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 86, in process_request encoding=req.session['importer.encoding']) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 130, in _do_import return self._process(filereader, get_reporter_id(req), ImportProcessor(self.env, req, uploadedfilename, tickettime)) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/importer.py"", line 401, in _process processor.end_process_row() File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/processors.py"", line 153, in end_process_row self._save_ticket(self.ticket) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/talm_importer/processors.py"", line 122, in _save_ticket db=self.db) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/ticket/model.py"", line 351, in save_changes self[name])) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/util.py"", line 121, in execute cursor.execute(query, params) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/util.py"", line 65, in execute return self.cursor.execute(sql_escape_percent(sql), args) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 78, in execute result = PyFormatCursor.execute(self, *args) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 56, in execute args or []) File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/sqlite_backend.py"", line 48, in _rollback_on_error return function(self, *args, **kwargs) }}}",defect,closed,normal,TicketImportPlugin,normal,duplicate,,Jun Omae,1.0