python inserting single quotes (') around MySQL table name - python

I have a database called project1 with the following tables:
_systbl1
_systbl2
_systbl3
dataset1
dataset2
dataset3
MySQL user odbc will need to be granted SELECT permissions on dataset% tables whenever a new one is added.
To accomplish this, I'm using a simple python script, like so:
#!/usr/bin/python
import MySQLdb
db = MySQLdb.connect(
host="localhost",
user="user",
passwd="pass",
db="project1"
)
# Create Cursor Object
cur = db.cursor()
# get list of tables beginning with dataset
cur.execute("SHOW TABLES FROM project1 LIKE 'dataset%';")
# run GRANT statement for each table
for row in cur.fetchall() :
cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`#`localhost`;", row)
cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`#`%`;", row)
Unfortunately, it gives me the following error:
Traceback (most recent call last):
File "mysql_query.py", line 20, in <module>
cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`#`localhost`;", row)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1146, "Table 'project1.'dataset1'' doesn't exist")
As you can see in the last line of the error, the problem is that python is putting a single quote around the table names when generating the query.
What am I missing here?

Do not use SQL parameters for table names. SQL parameters are escaped by the database adapter to not be interpreted as anything but literal values.
You'll have to interpolate those yourself instead, but be absolutely certain that your table name does not hold untrusted data (prevent SQL injection attacks):
cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`#`localhost`;" % row)
cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`#`%%`;" % row)
(where the % character in the grant has been escaped by doubling it to %%).

Instead use:
cur.execute("GRANT SELECT ON `project`.`%s` TO `odbc`#`localhost`" % row)
This will not use the normal escaping of the input. Beware of a backtick in any of your table names, though.

sql = """CREATE TABLE IF NOT EXISTS `""" + project + """` ( `id` INT(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`))"""

Related

Python MySQL Update from Excel file doesn't work

I am able to insert and replace the data in my MySQL table.
But I want to update the column dLieferdatum if the column sku equals cArtNr.
The Excel file looks as follows:
My Python Code:
cursor = connection.cursor()
query = """UPDATE d032683a.jll99_deliverytime_import SET dLieferdatum %s WHERE sku = %s"""
for r in range(1, sheet.nrows):
cArtNr = sheet.cell(r,1).value
dLieferdatum = sheet.cell(r,2).value
values = (dLieferdatum, cArtNr)
cursor.execute(query, values)
connection.commit()
cursor.close()
connection.close()
My Compiler (cygwin) error message:
Traceback (most recent call last):
File "sql_update.py", line 63, in
cursor.execute(query, values)
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 ''2020-05-29' WHERE sku = '11330342'' at line 1")
Many thanks and best regards.
I think you are missing an equal sign in the update statement and that is why you are getting the error. I think if you add equal sign then you should be fine.
Also,if I were you, I would print the query in the console to see what is the exact query that is being sent to database and also for testing might run that query directly in database.
UPDATE d032683a.jll99_deliverytime_import SET dLieferdatum = %s WHERE sku = %s
You print(query) should look like below:
UPDATE d032683a.jll99_deliverytime_import SET dLieferdatum = '2020-05-29' WHERE sku = '11330342'

PostgreSQL: Unable to drop a specific table named "user"

I'm unable to delete a specific table in my PostgreSQL database. That table is called "user". When I try to run the snippet of code below,
import psycopg2
conn = psycopg2.connect("dbname='mydatabase' user='postgres' host='localhost' password='mypassword'")
cur = conn.cursor()
cur.execute("DROP TABLE user;")
conn.commit()
conn.close()
It spits out the following error
Traceback (most recent call last):
File "dev_psycog.py", line 20, in <module>
cur.execute("DROP TABLE user;")
psycopg2.ProgrammingError: syntax error at or near "user"
LINE 1: DROP TABLE user;
I can delete any other table in my database just fine, but I can't seem to delete my table called "user". Is it because "user" is a reserved keyword?
Quote "user" as below
import psycopg2
conn = psycopg2.connect("dbname='mydatabase' user='postgres' host='localhost' password='mypassword'")
cur = conn.cursor()
cur.execute('DROP TABLE "user";')
conn.commit()
conn.close()
See here.
There is a second kind of identifier: the delimited identifier or
quoted identifier. It is formed by enclosing an arbitrary sequence of
characters in double-quotes (").

Testing Python to MySQL error

I have created a little script that allows me to save data to MySQLdb. At first it was working fine when I was using:
cursor.execute('INSERT INTO people (name, text) VALUES ("dan", "test2")')
The above would save "dan" into the title and "test2" into the text. I wanted to test to see if I was able to define something and fill it in this way. For example if I was to scrape a site and say (dan = soup.title.string) or something like that it would be able to populate this data into the database. I have tried to have a look around but cannot seem to find anything.
import MySQLdb
import sys
try:
db = MySQLdb.connect(
host = 'localhost',
user = 'root',
passwd = '',
db = 'python',
)
except:
print "db not found"
dan = "dandandan"
test2 = "testing101"
cursor = db.cursor()
cursor.execute('INSERT INTO people (name, text) VALUES (dan, test2)')
cursor.execute('SELECT * FROM people')
result = cursor.fetchall()
db.commit()
db.close()
The error I am receiving is:
C:\Users\********\Desktop>python mysqltest.py
Traceback (most recent call last):
File "mysqltest.py", line 18, in <module>
cursor.execute('INSERT INTO people (name) VALUES (dan)')
File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "C:\Python27\lib\site-packages\MySQLdb\connections.py", line 36, in defau
lterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1054, "Champ 'dan' inconnu dans field list"
)
You need to use parameters.
cursor.execute('INSERT INTO people (name, text) VALUES (%s,%s)', (dan, test2))
Use prepared statements:
cursor.execute("INSERT INTO people (name, text) VALUES (%s,%s)", (dan, test2))
From the documentation :
paramstyle
String constant stating the type of parameter marker formatting
expected by the interface. Set to 'format' = ANSI C printf format
codes, e.g. '...WHERE name=%s'. If a mapping object is used for
conn.execute(), then the interface actually uses 'pyformat' = Python
extended format codes, e.g. '...WHERE name=%(name)s'. However, the API
does not presently allow the specification of more than one style in
paramstyle.
Note that any literal percent signs in the query string passed to
execute() must be escaped, i.e. %%.
Parameter placeholders can only be used to insert column values. They
can not be used for other parts of SQL, such as table names,
statements, etc.

MySQL SELECT from field in CSV in Python

I am currently having issues with performing a MySQL SELECT Query based on rows in a .csv file inside a python script;
#!/usr/bin/env python
import MySQLdb, csv, sys
db = MySQLdb.connect(host="hostname",
user="user",
passwd="password",
db="database")
cur = db.cursor()
customers=csv.reader(file("customers.csv"))
for row in customers(row):
cur.execute("select field from database.table where customernumber = %s;" % row)
cur.commit()
cur.close()
I am getting this;
Traceback (most recent call last):
File "script.py", line 17, in <module>
cur.execute("select field from database.table where field = %s;" % row)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.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 '['1598']' at line 1")
The first row in the .csv file is 1598.
For some reason it is encasing this entry with '['1598']' hence the mySQL query failing,
Any ideas why it is encasing it and how to stop it?
Thanks in advance!
I have renamed all mysql details to defaults for DPA Reasons
Ashley
First, you need to fix your csv reader logic. Then you need to pass the value as an argument to execute, commit() is done on the connection not the cursor and finally - you are closing your connection in the loop itself.
import csv
with open('customers.csv') as f:
reader = csv.reader(f)
rows = list(reader)
for row in rows:
cur.execute("select field from database.table where customernumber = %s;", (row[0],))
con.commit()
con.close()
try this,
for row in customers:
print row , row[0]
row[0] should be first column value.
Change executing the SELECT to something like this:
cur.execute("SELECT field FROM database.table WHERE customernumber = %s", (row[0],))
If row[0] has the number, otherwise which ever index has it, like row[4].
cur.execute("select field from database.table where customernumber = %s;" % row[0])
You need to pass row[0] instead of row. row is a list and row[0] is the first element of that list.

How to insert a table consist of several dictionaries into MySQL tables?

I have the below result from my python code:
[
{filename:'1,2',Name:'Gorge',registration number: '6657', registration date: '2012-09-10 14:31:13'},
{filename:'5,43',Name:'mazu',registration number:'45', registration date:'2012-10-08 17:28:47'}]
and as soon as I want to put it in a MySQL table, I got this error:
Traceback (most recent call last):
File "C:\Users\jio\Datasets 1\MyTable_info.py", line 63, in <module>
cur.executemany(query,records)
File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 243, in executemany
self.errorhandler(self, ProgrammingError, msg.args[0])
File "C:\Python27\lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: not enough arguments for format string
My python code to insert the result in MySQL table is the below code:
con = MySQLdb.connect(host = "******", port=***, user = "***", passwd="*****", db="****")
with con:
cur=con.cursor()
cur.execute('''CREATE TABLE IF NOT EXISTS info(id INT(10) auto_increment primary key,file_name VARCHAR(10),
Name VARCHAR(50),Registration ID INT(50),registration time INT(50))''')
query= "INSERT INTO info (file_name, Name, Registration ID, registration time) VALUES ( %s, %s, %s, %s )"
cur.executemany(query,records)
con.commit()
Does anyone has an idea why I get this error and what does the error mean?
You are trying to insert a String into a field INT(50).
Take a look in the last field of the table, registration time field. It is an Integer and you are trying to insert values like '2012-10-08 17:28:47' or '2012-09-10 14:31:13'.
For a quick fix just change registration time field type as a VARCHAR(50).
But maybe, for perfomance issues, you should think to use some kind of TIMESTAMP field instead of a VARCHAR for this kind of purposes.
Apart from don't use INT type for field where you would like to add some kind of String.
Modify the records variable from
[ {filename:'1,2',Name:'Gorge',registration number: '6657', registration date: '2012-09-10 14:31:13'},
{filename:'5,43',Name:'mazu',registration number:'45', registration date:'2012-10-08 17:28:47'}]
to
[('1,2','Gorge','6657', '2012-09-10 14:31:13'),('5,43','mazu','45','2012-10-08 17:28:47')]
And avoid use whitespaces for the columns names as well
Try to quote field names. What the contents of records?
Don't use spaces in field names.
If you are required to, quote them with the ` character.

Categories

Resources