Logic error in exporttodatabase.py

I’m getting an occasional exception from exporttodatabase.py:

Failed to write measurements to database
Traceback (most recent call last):
  File "/usr/cellprofiler/src/CellProfiler/cellprofiler/modules/exporttodatabase.py", line 3028, in write_data_to_db
    disp_columns.append((table_name,self.truncate_string_for_display(stmt%tuple(my_rows[0]))))
UnboundLocalError: local variable 'my_rows' referenced before assignment
Error detected during run of module ExportToDatabase
Traceback (most recent call last):
  File "/usr/cellprofiler/src/CellProfiler/cellprofiler/pipeline.py", line 1796, in run_with_yield
    module.run(workspace)
  File "/usr/cellprofiler/src/CellProfiler/cellprofiler/modules/exporttodatabase.py", line 1704, in run
    self.write_data_to_db(workspace)
  File "/usr/cellprofiler/src/CellProfiler/cellprofiler/modules/exporttodatabase.py", line 3028, in write_data_to_db
    disp_columns.append((table_name,self.truncate_string_for_display(stmt%tuple(my_rows[0]))))
UnboundLocalError: local variable 'my_rows' referenced before assignment

I’m not sure what condition leads to this happening, but it happens in 8 out of 42 batches when I run in batch mode.

When I look at the code around line 3022, I can see why the exception might happen:

                    if self.db_type == DB_MYSQL:                                                                                                            
                        # Write 25 rows at a time (to get under the max_allowed_packet limit)                                                               
                        for i in range(0,len(object_rows), 25):                                                                                             
                            my_rows = object_rows*                                                                            
                            self.cursor.executemany(stmt, my_rows)                                                                                          
                        if self.show_window:                                                                                                                
                            disp_columns.append((table_name,self.truncate_string_for_display(stmt%tuple(my_rows[0]))))                                      

If len(object_rows) is 0, then my_rows never gets set, and if self.show_window is true then it tries to use my_rows, throwing the exception.

Of course, I’m not sure why self.show_window would be true when running headless! In any case, it looks to me that this code should be:

                    if self.db_type == DB_MYSQL:                                                                                                            
                        my_rows = None
                        # Write 25 rows at a time (to get under the max_allowed_packet limit)                                                               
                        for i in range(0,len(object_rows), 25):                                                                                             
                            my_rows = object_rows*                                                                            
                            self.cursor.executemany(stmt, my_rows)                                                                                          
                        if my_rows != None and self.show_window:                                                                                                                
                            disp_columns.append((table_name,self.truncate_string_for_display(stmt%tuple(my_rows[0]))))                                      

-Jon**

Hi Jon,

Indeed! I believe this recent fix addresses that issue. Can you git pull again and see if that helps?

Thanks for reporting,
David