def namedb_update_prepare( cur, primary_key_or_keys, input_record, table_name, must_equal=[], only_if={} ):
    """
    Prepare to update a record, but make sure that the fields in input_record
    correspond to acual columns.
    Also, enforce any fields that must be equal to the fields
    in the given record (must_equal), and require that certian fields in record
    have certain values first (only_if)

    Return an UPDATE ... SET ... WHERE statement on success.
    Raise an exception if not.

    DO NOT CALL THIS METHOD DIRECTLY
    """

    record = copy.deepcopy( input_record )
    must_equal_dict = dict( [(c, None) for c in must_equal] )

    # extract primary key
    # sanity check: primary key cannot be mutated
    primary_keys = []
    if isinstance(primary_key_or_keys, (str,unicode)):
        primary_keys = [primary_key_or_keys]
    else:
        primary_keys = primary_key_or_keys

    for primary_key_col in primary_keys:
        primary_key_value = record.get(primary_key_col, None)
        assert primary_key_value is not None, "BUG: no primary key value given in record"
        assert primary_key_col in must_equal, "BUG: primary key set to change"

    assert len(must_equal) > 0, "BUG: no identifying information for this record"

    # find set of columns that will change 
    update_columns = []
    for k in input_record.keys():
        if k not in must_equal:
            update_columns.append( k )

    # record keys correspond to real columns
    namedb_assert_fields_match( cur, record, table_name, columns_match_record=False )

    # must_equal keys correspond to real columns
    namedb_assert_fields_match( cur, must_equal_dict, table_name, columns_match_record=False )

    # only_if keys correspond to real columns 
    namedb_assert_fields_match( cur, only_if, table_name, columns_match_record=False )

    # only_if does not overlap with must_equal
    assert len( set(must_equal).intersection(only_if.keys()) ) == 0, "BUG: only_if and must_equal overlap"

    update_values = []
    for c in update_columns:
        if record[c] == False:
            update_values.append(0)
        elif record[c] == True:
            update_values.append(1)
        else:
            update_values.append(record[c])

    update_values = tuple(update_values)
    update_set = [("%s = ?" % c) for c in update_columns]

    where_set = []
    where_values = []
    for c in must_equal:
        if record[c] is None:
            where_set.append( "%s IS NULL" % c )
        elif record[c] == True:
            where_set.append( "%s = 1" % c )
        elif record[c] == False:
            where_set.append( "%s = 0" % c )
        else:
            where_set.append( "%s = ?" % c)
            where_values.append( record[c] )


    for c in only_if.keys():
        if only_if[c] is None:
            where_set.append( "%s IS NULL" % c)
        elif record[c] == True:
            where_set.append( "%s = 1" % c )
        elif record[c] == False:
            where_set.append( "%s = 0" % c )
        else:
            where_set.append( "%s = ?" % c)
            where_values.append( only_if[c] )

    where_values = tuple(where_values)

    query = "UPDATE %s SET %s WHERE %s" % (table_name, ", ".join(update_set), " AND ".join(where_set))

    log.debug(namedb_format_query(query, update_values + where_values))

    return (query, update_values + where_values)
Prepare to update a record, but make sure that the fields in input_record
    correspond to acual columns.
    Also, enforce any fields that must be equal to the fields
    in the given record (must_equal), and require that certian fields in record
    have certain values first (only_if)

    Return an UPDATE ... SET ... WHERE statement on success.
    Raise an exception if not.

    DO NOT CALL THIS METHOD DIRECTLY