﻿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 <trac.web.main.RequestDispatcher object at 0x6ec8290> 

e IntegrityError('UNIQUE constraint failed: ticket_change.ticket, ... 

env <trac.env.Environment object at 0x5f99710> 

env_error None 

req <RequestWithSession ""POST '/importer'""> 

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 <talm_importer.importer.ImportModule object at 0x6ec84d0> 

chrome <trac.web.chrome.Chrome object at 0x6ec8150> 

ctype 'application/x-www-form-urlencoded' 

err (<class 'sqlite3.IntegrityError'>, IntegrityError('UNIQUE constraint ... 

handler <talm_importer.importer.ImportModule object at 0x6ec84d0> 

options {} 

req <RequestWithSession ""POST '/importer'""> 

self <trac.web.main.RequestDispatcher object at 0x6ec8290> 

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 <RequestWithSession ""POST '/importer'""> 

self <talm_importer.importer.ImportModule object at 0x6ec84d0> 

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 <talm_importer.readers.XLSReader object at 0x8a98990> 

req <RequestWithSession ""POST '/importer'""> 

self <talm_importer.importer.ImportModule object at 0x6ec84d0> 

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 <function PatchedTicket at 0x2aaab05519b0> 

add_sql_result <function add_sql_result at 0x8f02230> 

cell '1848' 

cls <class 'trac.ticket.model.Version'> 

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 <trac.db.pool.PooledConnection object at 0x82a8208> 

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 <talm_importer.readers.XLSReader object at 0x8a98990> 

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 <talm_importer.processors.ImportProcessor object at 0x2aaab0255590> 

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', <class 'trac.ticket.model.Type'>), ('status', <class ... 

self <talm_importer.importer.ImportModule object at 0x6ec84d0> 

ticket <talm_importer.ticket.PatchedTicketClass object at 0x2aaab012a050> 

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 <talm_importer.processors.ImportProcessor object at 0x2aaab0255590> 

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 <talm_importer.processors.ImportProcessor object at 0x2aaab0255590> 

ticket <talm_importer.ticket.PatchedTicketClass object at 0x2aaab0383990> 

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 <trac.db.pool.PooledConnection object at 0x82a8310> 

name u'blockedby' 

num 6 

old u'5' 

props_unchanged False 

replyto None 

row (1846, u'blockedby', u'1813, 1846') 

self <talm_importer.ticket.PatchedTicketClass object at 0x2aaab0383990> 

ts 1408432129000000 

when datetime.datetime(2014, 8, 19, 9, 15, 32, tzinfo=<LocalTimezone ""CEST"" ... 

when_ts 1408432532000000L 

File ""/caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages/trac/db/util.py"", line 121, in execute Code fragment:Line  

116         If the query is a SELECT, return all the rows (""fetchall""). 

117         When more control is needed, use `cursor()`. 

118         """""" 

119         dql = self.check_select(query) 

120         cursor = self.cnx.cursor() 

121         cursor.execute(query, params) 

122         rows = cursor.fetchall() if dql else None 

123         cursor.close() 

124         return rows 

125   

126     __call__ = execute 

Local variables:Name Value 

cursor <trac.db.util.IterableCursor object at 0x839fd50> 

dql False 

params (1846, 1408432532000000L, u'xxxxxxxxx', u'blockedby', u'1813, ... 

query 'INSERT INTO ticket_change\n                        ... 

self <trac.db.pool.PooledConnection object at 0x82a8310> 

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 <trac.db.util.IterableCursor object at 0x839fd50> 

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 <trac.db.sqlite_backend.EagerCursor object at 0x8eef5a8> 

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 <trac.db.sqlite_backend.EagerCursor object at 0x8eef5a8> 

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 <method 'execute' of 'sqlite3.Cursor' objects> 

kwargs {} 

self <trac.db.sqlite_backend.EagerCursor object at 0x8eef5a8> 



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)





System Information:

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)



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) [GCC 4.7.2] 

pytz 2013d 

setuptools 1.1.6 

SQLite 3.8.2 

jQuery 1.7.2 



Enabled Plugins:

BlackMagicTicketTweaks  0.12.2 /caegrp/cae_develop/gentoo/var/lib/trac/Coconut/plugins/BlackMagicTicketTweaks-0.12.2-py2.7.egg 

NavAdd  0.3 /caegrp/cae_develop/gentoo/var/lib/trac/Coconut/plugins/NavAdd-0.3-py2.7.egg 

SimpleMultiProject  0.0.4dev /caegrp/cae_develop/gentoo/var/lib/trac/Coconut/plugins/SimpleMultiProject-0.0.4dev-py2.7.egg 

TicketImport  0.8.3 /caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages 

TracAccountManager  0.4.4 /caegrp/cae_develop/gentoo/usr/lib/python2.7/site-packages 

TracDateField  3.0.0dev /caegrp/cae_develop/gentoo/var/lib/trac/Coconut/plugins/TracDateField-3.0.0dev-py2.7.egg 

TracMasterTickets  3.0.5dev /caegrp/cae_develop/gentoo/var/lib/trac/Coconut/plugins/TracMasterTickets-3.0.5dev-py2.7.egg 



TracGuide — The Trac User and Administration Guide 



"	defect	new	normal	TicketImportPlugin	normal			Jun Omae	
