0

I am trying to make dynamic insert command into mysql, from dictionary values in one transaction but getting an error. Also I was wondering what is the most efficient way to perform this specific case (maybe my code is not optimal)? I am using FOR since in some cases dictionary can be empty. Thanks

    import mysql.connector
    mydb = mysql.connector.connect(..........
    mycursor = mydb.cursor()
    varStatic="test"
    cust={'74.2': '54', '172.26': '76', '7': 'B9'}
    insertStatement='"""INSERT INTO customers (id,number,desc) VALUES (%s,%s,%s)"""'
    for key in cust:
          insertStatement+=',('+key+','+cust[key]+','+varStatic+')'
    mycursor.execute(insertStatement)
    mydb.commit()
Veljko
  • 1,708
  • 12
  • 40
  • 80
  • what error do you get? – Red Cricket Nov 19 '18 at 20:43
  • mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"""REPLACE INTO customers (id,number,desc) VALUES (%s,%s,%s)""",(74.2,54' at line 1 – Veljko Nov 19 '18 at 20:46
  • actually, not quite sure what is wrong but in the same time I do not have feeling that my code is based on best practice.. – Veljko Nov 19 '18 at 20:47
  • That does look like a syntax error. Maybe you could add a debug print statement something like `print insertStatement` and update your question with the output. Your using `'`'s so the `"""` ends up in your string. – Red Cricket Nov 19 '18 at 20:49
  • I think that maybe this is because values KEY, VALUE, VARSTATIC are not quoted at all – Veljko Nov 19 '18 at 20:54
  • `s = '"""%s %s"""' # '"""%s %s"""'` what you want is this: `s = """%s %s""" % ('foo', 'bar') # 'foo bar'` – Red Cricket Nov 19 '18 at 20:56
  • can you please put whole my statement how it should be defined as a solution in Answer? – Veljko Nov 19 '18 at 20:58
  • Well I haven't worked out a whole answer. I just was noting that you are not building the string `insertStatement` correctly. Which just a partial answer. – Red Cricket Nov 19 '18 at 21:00

1 Answers1

1

You may do something like this, but a little confused about how to optimize for-loop and value. If i can get rid of append or replace to List Comprehensions, then you can use insertStatement += ("(%s,%s,%s),"*len(cust.items()))[:-1]

import mysql.connector
mydb = mysql.connector.connect(user="k",passwd="k",db="k")
mycursor = mydb.cursor()
varStatic="test"
cust={'74.2': "54'", '172.26': '76', '7': 'B9'}
insertStatement= """INSERT INTO customers (id,number,desc) VALUES """
value = []
for k,v in cust.items():
    insertStatement += "(%s,%s,%s),"
    value.append(k)
    value.append(v)
    value.append(varStatic)

print(insertStatement[:-1],value)
try:
    mycursor.execute(insertStatement[:-1],value)
    mydb.commit()
except Exception as e:
    print(e)
    mydb.rollback()
KC.
  • 2,981
  • 2
  • 12
  • 22
  • Hi its not working. This is for example output for two elements in dictionary. Something is not properly defined. This is what I am getting with Print statement. INSERT INTO customers (id,number,desc) VALUES (%s,%s,%s),(%s,%s,%s) ['172.26.74.2111', '54.10.EC.0C.1D.6B', 'test', '172.26.74.112232', '54.10.EC.54.92.FD', 'test'] – Veljko Nov 20 '18 at 08:31
  • print(insertStatement[:-1]) returns INSERT INTO customers (id,numbers,desc) VALUES (%s,%s,%s),(%s,%s,%s) this is really not correct – Veljko Nov 20 '18 at 08:33
  • you should read this, and not recommend execute sql straight it will cause injection https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html @Dejan – KC. Nov 20 '18 at 08:40
  • I do not understand quite what you want to say? Are you suggesting to do insert one by one? your print of insert statement returns tis very strange and not correct format. Can you please correct it because answer is definetely not OK? print(insertStatement[:-1]) returns INSERT INTO customers (id,numbers,desc) VALUES (%s,%s,%s),(%s,%s,%s) . – Veljko Nov 20 '18 at 08:58
  • `mycursor.execute()` will pass `['172.26.74.2111', '54.10.EC.0C.1D.6B', 'test', '172.26.74.112232', '54.10.EC.54.92.FD', 'test ']` into `INSERT INTO customers (id,numbers,desc) VALUES (%s,%s,%s),(%s,%s,%s) `. And you don't care about the data type, the function will automatically convert. Of course you can also execute your own sql, but you need to manually process the data to avoid SQL injection. btw, I will not post code I have never run, especially full code. @Dejande – KC. Nov 20 '18 at 09:08
  • Hi I run now and execute query, rows are not inserted in database and getting this as result : 1265 (01000): Data truncated for column 'id' at row 1 – Veljko Nov 20 '18 at 09:12
  • @Dejan it seems the `id` you insert is too long. This is the question https://stackoverflow.com/questions/18089240/data-truncated-for-column – KC. Nov 20 '18 at 09:17
  • id is varchar(30). so it should import it. I think that issue is that your code is adding something additional on my statement for that column and it does not take only key value for the import. I suppose that is the issue. – Veljko Nov 20 '18 at 09:21
  • I modifies now ID to be varchar 3000 and still getting the same error. – Veljko Nov 20 '18 at 09:23
  • can you show your column, i want to try again. also i need the data which caused this error. – KC. Nov 20 '18 at 09:25
  • SHOW COLUMNS: id varchar(3000) YES NULL name varchar(50) YES NULL address varchar(50) YES NULL – Veljko Nov 20 '18 at 09:39
  • data is very simple : varStatic="test" cust={'172.26.74.2111': '54.10.EC.0C.1D.6B', '172.26.74.112232': '54.10.EC.54.92.FD'} – Veljko Nov 20 '18 at 09:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/183938/discussion-between-kcorlidy-and-dejan). – KC. Nov 20 '18 at 09:40