kjh
kjh

Reputation: 3411

mysql/connector python query works in mysql but not python

I've seen the following two answers:

And neither of the solutions work for me. I'm running the code below which completes without any errors every single time yet does not at all modify the mysql table Compounds, and I've verified that the format of the input file matches exactly the format of my mysql table and that it is correctly delimited and not empty.

import os, sys
import mysql.connector
from mysql.connector import errorcode
from mysql.connector.constants import ClientFlag

TABLE_NAME = "Compounds"
fullDataFile  = "data/compounds/parsed/fullData.csv"
cnx = mysql.connector.connect(user='kharland', passwd='password', db='mydb', client_flags=[ClientFlag.LOCAL_FILES])
cursor = cnx.cursor()
print "loading data file: %s/%s" % (os.getcwd(), fullDataFile)
try:
  cursor.execute = (
    "LOAD DATA LOCAL INFILE '%s/%s'"
    " REPLACE"
    " INTO TABLE `%s`"
    " FIELDS TERMINATED BY '^'"
    " LINES TERMINATED BY '\n'"
    " (PUBCHEM_COMPOUND_CID,"
    " PUBCHEM_COMPOUND_CANONICALIZED,"
    " PUBCHEM_CACTVS_COMPLEXITY,"
    " PUBCHEM_CACTVS_HBOND_ACCEPTOR,"
    " PUBCHEM_CACTVS_HBOND_DONOR,"
    " PUBCHEM_CACTVS_ROTATABLE_BOND,"
    " PUBCHEM_CACTVS_SUBSKEYS,"
    " PUBCHEM_IUPAC_INCHI,"
    " PUBCHEM_IUPAC_INCHIKEY,"
    " PUBCHEM_EXACT_MASS,"
    " PUBCHEM_MOLECULAR_FORMULA,"
    " PUBCHEM_MOLECULAR_WEIGHT,"
    " PUBCHEM_OPENEYE_CAN_SMILES,"
    " PUBCHEM_OPENEYE_ISO_SMILES,"
    " PUBCHEM_CACTVS_TPSA,"
    " PUBCHEM_MONOISOTOPIC_WEIGHT,"
    " PUBCHEM_TOTAL_CHARGE,"
    " PUBCHEM_HEAVY_ATOM_COUNT,"
    " PUBCHEM_ATOM_DEF_STEREO_COUNT,"
    " PUBCHEM_ATOM_UDEF_STEREO_COUNT,"  
    " PUBCHEM_BOND_DEF_STEREO_COUNT,"
    " PUBCHEM_BOND_UDEF_STEREO_COUNT,"
    " PUBCHEM_ISOTOPIC_ATOM_COUNT,"
    " PUBCHEM_COMPONENT_COUNT,"
    " PUBCHEM_CACTVS_TAUTO_COUNT);"  %
    (os.getcwd(), fullDataFile, TABLE_NAME))
  cnx.commit()
except mysql.connector.Error as e:
  sys.stderr.write("x Failed loading data: {}\n".format(e))

However if I print this query to terminal and then run it in mysql then it works just fine. Is there a reason the mysql lib might fail to run the actual query or am I missing some function call?

Upvotes: 0

Views: 1336

Answers (1)

spencer7593
spencer7593

Reputation: 108510

MySQL doesn't accept a bind placeholder for an identifier. In this case, the name of the table. That has to be part of the SQL text. You can only supply values using bind placeholders.

You can do this:

SELECT t.id FROM mytable t WHERE t.foo = :val
                                         ^^^^

But this is not valid:

SELECT t.id FROM :mytable t WHERE t.foo = 'bar'
                 ^^^^^^^^ 

You could do a an sprintf-type operation as a prior step, to generate SQL text (a string) that contains the actual table name, and then submit that SQL text (string) to MySQL.

When you get to that cursor.execute, you need the SQL text to include the table name as part of the string. (It's also likely that the name of the file has to be specified as a literal, and can't be a placeholder, but I'm not sure about that. What I am sure about is the table name.)


As a test, try hardcoding the table name "Compounds" and hardcoding the filename into the SQL text...

cursor.execute = (
    "LOAD DATA LOCAL INFILE '/opt/data/compounds/parsed/fullData.csv'"
    " REPLACE"
    " INTO TABLE `Compounds`"

Upvotes: 1

Related Questions