MySQL/Python INSERT INTO Statement Issues - python

I'm attempting to test adding data to a database via python. I have recognized that many people have issues with the "INSERT INTO" statement, and I have as well. I have received a range of errors, followed by changing the syntax multiple times, and then receiving new errors.
Currently, I have this as my statement:
cursor.execute("""INSERT INTO test (Column 1,Column 2) VALUES (%s,%s)"""% arg)
Where:
arg=("'5','2'")
Running the code outputs the standard 1064 MySQL error.
If someone can explain to me the standard syntax that would be great, because I can't seem to find it anywhere.

If fields or tables have spaces or other special characters in their names, they need delimited with `.
INSERT INTO test (`Column 1`,`Column 2`) ...
It is also a good habit to get into because it prevents hard to diagnose issues with using identifiers that might be confused with reserved or keywords.

It is never the best way to deal with these problems, but it always works to use the "".join(string)
arg=(5,2)
query = "".join(["INSERT INTO test (Column 1,Column 2) VALUES (" , str(arg[0]), ", ", str(arg[1]),")"])
query
Out[25]: 'INSERT INTO test (Column 1,Column 2) VALUES (5, 2)'
And then you execute() it. Cheers !

try this one out. I changed the % -> , and added the values at the end
cursor.execute("""INSERT INTO test (`Column 1`,`Column 2`) VALUES (%s,%s)""", (5,2))

I appreciate your answers but I found a solution. I ended up changing the rows in the DB to "Column1" instead of "Column 1", and this solved the issue.
import MySQLdb as mariadb
db = mariadb.connect(host="", user="root", passwd="", db="")
cursor = db.cursor()
sql = "INSERT INTO test (Column 1,Column 2) VALUES (%s,%s)"
#sqltime=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
arg = ('5',"'2'") #argument input
try:
cursor.execute("""INSERT INTO test (Column1,Column2) VALUES (%s,%s)"""% arg)
db.commit()
except:
cursor.execute('show profiles')
for row in cursor:
print(row)
raise
db.close()

Related

Passing strings to pymysql cursor using Python function

I'm working on a script that will pull data from a database using pymysql and a simple SELECT statement. I'm going to run this statement many times, so I was hoping to simplify things by putting it in a function and passing the column name, table name, where clause and value as arguments to the function.
def retrieve_value_from_db(connection,column_name,table_name,where_clause,where_value):
with connection:
with connection.cursor() as cursor:
sql = "SELECT %s FROM %s WHERE %s=%s"
logging.debug(cursor.mogrify(sql,(column_name,table_name,where_clause,where_value)))
cursor.execute(sql,(column_name,table_name,where_clause,where_value))
result = cursor.fetchone()
connection.commit()
return result
However calling the function below returns the following error
retrieve_value_from_db(connection,"last_name","mother_table","id","S50000")
pymysql.err.ProgrammingError: (1064, "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 ''mother_table' WHERE 'id'='S50000'' at line 1")
Cursor.execute seems to be reading the quotation mark portion of the string, which is causing the programming error. So how do I pass a string argument to the function that cursor.execute can read? Is what I want to do even possible? Thanks in advance.
Perhaps surprisingly, you should not let the database substitution handle table names and column names. It tries to quote them as if they were fields, which is wrong.
sql = "SELECT %s FROM %s WHERE %s=%%s" % (column_name,table_name,where_clause)
...
cursor.execute(sql, (where_value,))

MySQL+Python on Raspbian produces Syntax Error

I am now starting to use Python scripts to manage databases in association with MySQL.
I am facing an issue of Syntax error and can't seem to figure out why.
When i run the following code:
import MySQLdb
import time
conn = MySQLdb.connect("localhost","username","password","DataBase")
c= conn.cursor()
c.execute("SELECT * FROM table")
rows=c.fetchall()
for eachRow in rows:
print eachRow
I can get the rows in my table so everything is fine.
However when i use the INSERT statment as follows:
import MySQLdb
import time
conn = MySQLdb.connect("localhost","username","password","DataBase")
c= conn.cursor()
c.execute("INSERT INTO table(column1, column2) VALUES(23:EA:4A:7F:A1,Someone)")
c.execute("SELECT * FROM table")
rows=c.fetchall()
for eachRow in rows:
print eachRow
I get a syntax error
"near 'Column1,column2) Values(23:EA:4A:7F:A1,Someone)' at line 1"
I have checked the documentation and believe I am using the right syntax.
Have tried using multiple field types (varchar, text,...) and with semicolon at the end or not.
column1 is of type varchar(14)
column1 is of type text
Using mysql Ver 14.14 Distrib 5.5.57 for debian-linux-gnu (armv71)
Try it like this:
INSERT INTO "table" (column1, column2) VALUES('23:EA:4A:7F:A1','Someone')
table is a reserved keyword in SQL, so you should avoid naming your table table. It's like naming your kid Kid, oh wait.. But anyway if you are planning to use reserved keywords, you have to wrap them in double quotes.
As for the values, Someone is a string, so you should definitely wrap it in single quotes. I'm not sure about the type of 23:EA:4A:7F:A1, but I guess that's also a string, so better wrap that too.

Right syntax to use near

I'm trying to run this script, but I have this error:
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 '(than appear 3 users)' at
line 1
Code:
conn = mysql.connector.connect('localhost','root,'','dbtest')
cursor = conn.cursor()
add_data = ("""INSERT INTO data VALUES %s,%s,%s""" %(user, twet, time))
cursor.execute(add_data)
conn.commit()
cursor.close()
conn.close()
I belive that the error is in the %s,%s,%s, I tried a lot of diferent formats but it's always the same result.
Any ideas?
Thanks.
The correct syntax for your connection to your database should read in the lines of:
conn = mysql.connector.connect('localhost','root','','dbtest')
And maybe change your insert statement to:
add_data = ("INSERT INTO data VALUES (\"%s\",\"%s\",\"%s\")" % (user, twet, time))
You must never ever use string substitution in SQL queries. Use the db-api's parameter substitution. Apart from anything else, it will solve one of your syntax problems, which is that your strings are not quoted; it will do that automatically.
The other syntax issue you have, as Mario pointed out, is that arguments to VALUES need to be in parentheses. So, putting those together:
add_data = """INSERT INTO data VALUES (%s,%s,%s)"""
cursor.execute(add_data, (user, twet, time))
The right syntax should be with parenthesis:
INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country) VALUES ('Cardinal','Tom B. Erichsen','Skagen 21','Stavanger','4006','Norway');

Print if MySQL returns no results

This is my code so far. I'm attempting to print No results found if no results are returned by MySQL however I can't figure it out. Perhaps I'm using incorrect arguments. Could anyone provide me with an example? Much appreciated!
def movie_function(film):
connection = mysql connection info
cursor = connection.cursor()
sql = "SELECT * FROM film_database WHERE film_name = '"+film+"' ORDER BY actor"
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print row[1]
When you execute a select statement, cursor.rowcount is set to the number of results retrieved. Also, there is no real need to call cursor.fetchall(); looping over the cursor directly is easier:
def movie_function(film):
connection = mysql connection info
cursor = connection.cursor()
sql = "SELECT * FROM film_database WHERE film_name = %s ORDER BY actor"
cursor.execute(sql, (film,))
if not cursor.rowcount:
print "No results found"
else:
for row in cursor:
print row[1]
Note that I also switched your code to use SQL parameters; there is no need to use string interpolation here, leave that to the database adapter. The %s placeholder is replaced for you by a correctly quoted value taken from the second argument to cursor.execute(), a sequence of values (here a tuple of one element).
Using SQL parameters also lets a good database reuse the query plan for the select statement, and leaving the quoting up to the database adapter prevents SQL injection attacks.
You could use cursor.rowcount after your code to see how many rows were actually returned. See here for more.
I guess, this should work.
def movie_function(film):
connection = mysql connection info
cursor = connection.cursor()
sql = "SELECT * FROM film_database WHERE film_name = %s ORDER BY actor"
cursor.execute(sql, [film])
rows = cursor.fetchall()
if not rows:
print 'No resulrs found'
return
for row in rows:
print row[1]
Note, that I changed the way the film parameter is passed to query. I don't know, how exactly it should be (this depends on what MySQL driver for python you use), but important thing to know, is that you should not pass your parameters directly to the query string, because of security reasons.
You can also use :
rows_affected=cursor.execute("SELECT ... ") -> you have directly the number of returned rows

python, mysql, inserting string into table, error 1054

I am having the problem
OperationalError: (1054, "Unknown column 'Ellie' in 'field list'")
With the code below, I'm trying to insert data from json into a my sql database. The problem happens whenever I try to insert a string in this case "Ellie" This is something do to with string interpolation I think but I cant get it to work despite trying some other solutions I have seen here..
CREATE TABLE
con = MySQLdb.connect('localhost','root','','tweetsdb01')
cursor = con.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS User(user_id BIGINT NOT NULL PRIMARY KEY, username varchar(25) NOT NULL,user varchar(25) NOT NULL) CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB")
con.commit()
INSERT INTO
def populate_user(a,b,c):
con = MySQLdb.connect('localhost','root','','tweetsdb01')
cursor = con.cursor()
cursor.execute("INSERT INTO User(user_id,username,user) VALUES(%s,%s,%s)"%(a,b,c))
con.commit()
cursor.close()
READ FILE- this calls the populate method above
def read(file):
json_data=open(file)
tweets = []
for i in range(10):
tweet = json.loads(json_data.readline())
populate_user(tweet['from_user_id'],tweet['from_user_name'],tweet['from_user'])
Use parametrized SQL:
cursor.execute("INSERT INTO User(user_id,username,user) VALUES (%s,%s,%s)", (a,b,c))
(Notice the values (a,b,c) are passed to the function execute as a second argument, not as part of the first argument through string interpolation). MySQLdb will properly quote the arguments for you.
PS. As Vajk Hermecz notes, the problem occurs because the string 'Ellie' is not being properly quoted.
When you do the string interpolation with "(%s,)" % (a,) you get
(Ellie,) whereas what you really want is ('Ellie',). But don't bother doing the quoting yourself. It is safer and easier to use parametrized SQL.
Your problem is that you are adding the values into the query without any escaping.... Now it is just broken. You could do something like:
cursor.execute("INSERT INTO User(user_id,username,user) VALUES(\"%s\",\"%s\",\"%s\")"%(a,b,c))
But that would just introduce SQL INJECTION into your code.
NEVER construct SQL statements with concatenating query and data. Your parametrized queries...
The proper solution here would be:
cursor.execute("INSERT INTO User(user_id,username,user) VALUES(%s,%s,%s)", (a,b,c))
So, the problem with your code was that you have used the % operator which does string formatting, and finally you just gave one parameter to cursor.execute. Now the proper solution, is that instead of doing the string formatting yourself, you give the query part to cursor.execute in the first parameter, and provide the tuple with arguments in the second parameter.

Categories

Resources