Fixes the data corruption caused in the form_values table (content field) by the migrate script 65.

This commit is contained in:
Ramkrishna Chakrabarty
2011-03-08 12:42:26 -05:00
parent a221548e8f
commit a20d7738b6
@@ -0,0 +1,78 @@
'''
This migration script fixes the data corruption caused in the form_values
table (content json field) by migrate script 65.
'''
from sqlalchemy import *
from sqlalchemy.orm import *
from migrate import *
from migrate.changeset import *
from sqlalchemy.exc import *
from galaxy.util.json import from_json_string, to_json_string
from galaxy.model.custom_types import _sniffnfix_pg9_hex
import logging
log = logging.getLogger( __name__ )
metadata = MetaData( migrate_engine )
db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) )
def upgrade():
print __doc__
metadata.reflect()
cmd = "SELECT form_values.id as id, form_values.content as field_values, form_definition.fields as fields " \
+ " FROM form_definition, form_values " \
+ " WHERE form_values.form_definition_id=form_definition.id " \
+ " ORDER BY form_values.id"
result = db_session.execute( cmd )
corrupted_rows = 0
for row in result:
# first check if loading the dict from the json succeeds
# if that fails, it means that the content field is corrupted.
try:
field_values_dict = from_json_string( str( row['field_values'] ) )
except Exception, e:
corrupted_rows = corrupted_rows + 1
# content field is corrupted
fields_list = from_json_string( _sniffnfix_pg9_hex( str( row['fields'] ) ) )
field_values_str = _sniffnfix_pg9_hex( str( row['field_values'] ) )
field_values_dict = {}
# look for each field name in the values and extract its value (string)
for index in range( len(fields_list) ):
field = fields_list[index]
field_name_key = '"%s": "' % field['name']
field_index = field_values_str.find( field_name_key )
if field_index == -1:
# if the field name is not present the field values dict then
# inform the admin that this form values cannot be fixed
print "The 'content' field of row 'id' %i does not have the field '%s' in the 'form_values' table and could not be fixed by this migration script." % ( int( field['id'] ), field['name'] )
else:
# check if this is the last field
if index == len( fields_list )-1:
# since this is the last field, the value string lies between the
# field name and the '"}' string at the end, hence len(field_values_str)-2
value = field_values_str[ field_index+len( field_name_key ):len( field_values_str )-2 ]
else:
# if this is not the last field then the value string lies between
# this field name and the next field name
next_field = fields_list[index+1]
next_field_index = field_values_str.find( '", "%s": "' % next_field['name'] )
value = field_values_str[ field_index+len( field_name_key ):next_field_index ]
# clean up the value string, escape the required quoutes and newline characters
value = value.replace( "'", "\''" )\
.replace( '"', '\\\\"' )\
.replace( '\r', "\\\\r" )\
.replace( '\n', "\\\\n" )\
.replace( '\t', "\\\\t" )
# add to the new values dict
field_values_dict[ field['name'] ] = value
# update the db
json_values = to_json_string(field_values_dict)
cmd = "UPDATE form_values SET content='%s' WHERE id=%i" %( json_values, int( row['id'] ) )
db_session.execute( cmd )
print 'Fixed %i corrupted rows.' % corrupted_rows
def downgrade():
pass