Given the restrictions that you can't change your database structure (and as Gareth Rees points out, that would be better), the way I would resolve this is using an Enum or Class. Basically, while you can have multiple databases with the same structure, you won't have an unbounded number of those databases.
Based on the type of data. I would switch the entire SQL statement with no string injection in it, so that you basically tie the SQL statement to the class. e.g.
if(is_X(my_obj))
query = '''INSERT INTO X_table (state_int, turn_left, turn_right, move_forward) VALUES (?,?,?,?)'''
else if(is_Y(my_obj))
query = '''INSERT INTO Y_table (state_int, turn_left, turn_right, move_forward) VALUES (?,?,?,?)'''
...
...
or
query = my_obj.get_insert_query();
While not ideal, this is a better way of ensuring that you're safe from injection issues without restructuring your entire data layer.
WITH THAT SAID, it's important to be aware that the persistent data layer is the worst layer to have bad architecture in, because it's almost impossible to change once it's in use, and any architectural problems cause problems all the way up the application stack (because you need to write clunky code in order to massage the bad data structure into a clean UI, and the fact that the UI doesn't mirror the data well makes it hard to link visible bug to underlying cause etc).
So while you're still at the stage where you can change the data structure to something more sensible, you should.
Get the data right, everything else is easy. Get the data wrong, everything else is hard.
database.records_table_name
? If it's controlled by the (malicious) user, then of course you have a huge gaping SQL injection vulnerability. If it's not controlled by the user, then you should be okay. \$\endgroup\$database.records_table_name
being supplied by the user or other potential source of malicious/id10t intent? No? You should be good. Yes, kiss your DB bye-bye \$\endgroup\$