Modify

Opened 8 years ago

Closed 8 years ago

#11933 closed defect (duplicate)

IntegrityError

Reported by: Jeffrey.Ratcliffe@… Owned by: François Granade
Priority: normal Component: TicketImportPlugin
Severity: normal Keywords:
Cc: Jun Omae Trac Release: 1.0

Description (last modified by Jun Omae)

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)
[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)

Attachments (0)

Change History (3)

comment:1 Changed 8 years ago by anonymous

I should point out that this only occurs when updating blocking and blocked by fields.

comment:2 Changed 8 years ago by Jun Omae

Description: modified (diff)
Trac Release: 1.0

comment:3 Changed 8 years ago by Jun Omae

Resolution: duplicate
Status: newclosed

A duplicate of #10188.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain François Granade.
The resolution will be deleted. Next status will be 'reopened'.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.