Python MySQL Statement returning Error - python

hey, I'm very new to all this so please excuse stupidity :)
import os
import MySQLdb
import time
db = MySQLdb.connect(host="localhost", user="root", passwd="********", db="workspace")
cursor = db.cursor()
tailoutputfile = os.popen('tail -f syslog.log')
while 1:
x = tailoutputfile.readline()
if len(x)==0:
break
y = x.split()
if y[2] == 'BAD':
timestring = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
if y[2] == 'GOOD':
print y[4] + '\t' + y[7]
so i run the program and this is the error message I am getting
user#machine:~/$ python reader.py
Traceback (most recent call last):
File "reader.py", line 17, in ?
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
File "/usr/lib/python2.4/site-packages/MySQLdb/cursors.py", line 163, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.4/site-packages/MySQLdb/connections.py", line 35, 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 '[4], y[7]' at line 1")
user#machine:~/$
So i'm assuming that the error is obviously coming from the SQL Statement
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
Here is an example of what y[4] and y[7] will look like.
YES Mail.Sent.To.User:user#work.com.11.2.2008:23.17
Is this error happening because I should be escaping those values before I try and Insert them into the Database?
Or am I completely missing the point??
Any help would be appreciated!
thanks in advance.

As pointed out, you're failing to copy the Python variable values into the query, only their names, which mean nothing to MySQL.
However the direct string concatenation option:
cursor.execute("INSERT INTO releases (date, cat, name) VALUES ('%s', '%s', '%s')" % (timestring, y[4], y[7]))
is dangerous and should never be used. If those strings have out-of-bounds characters like ' or \ in, you've got an SQL injection leading to possible security compromise. Maybe in your particular app that can never happen, but it's still a very bad practice, which beginners' SQL tutorials really need to stop using.
The solution using MySQLdb is to let the DBAPI layer take care of inserting and escaping parameter values into SQL for you, instead of trying to % it yourself:
cursor.execute('INSERT INTO releases (date, cat, name) VALUES (%s, %s, %s)', (timestring, y[4], y[7]))

cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
should be
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, '%s', '%s')" % (y[4], y[7]))
Your best bet to debug things like this is to put the query into a variable and use that:
query = "INSERT INTO releases (date, cat, name) values (timestring, '%s', '%s')" % (y[4], y[7])
print query
cursor.execute(query)
That print statement would make it very obvious what the problem is.
If you're going to be using list variables a lot like this it can get very confusing, consider using the list just once and putting the variables into a dictionary. It's a bit longer to type, but is much, much easier to keep track of what's going on.

never use "direct string concatenation" with SQL, because it's not secure, more correct variant:
cursor.execute('INSERT INTO releases (date, cat, name) VALUES (%s, %s, %s)', (timestring, y[4], y[7]))
it automatically escaping forbidden symbols in values (such as ", ' etc)

Related

SQL Insert query from flask not working

db.execute('CREATE TABLE IF NOT EXISTS test (name TEXT)')
print("Table created successfully")
db.execute('INSERT INTO %s VALUES (%s)' % ('test', 'sample'))
db.close()
I am using Python. The table is created successfully with a column of "name", but I am unable to insert anything.
I get the error:
sqlite3.OperationalError: no such column: sample
Why?
I think you need something like:
INSERT INTO test (name)
VALUES
('sample');
Translated into python:
db.execute('INSERT INTO %s (name) VALUES (\'%s\')' % ('test', 'sample'))
You forgot the column name?
db.execute('CREATE TABLE IF NOT EXISTS test (name TEXT)')
print("Table created successfully")
db.execute('INSERT INTO %s (name) VALUES (%s)' % ('test', 'sample'))
db.close()
You need to commit your changes. If you don't call db.commit(), your changes (including creating the table) will be rolled back when you close the database.
This should work:
db.execute('INSERT INTO test VALUES (%s)' % ('sample'))
You definitely don't want to use string substitutions. That opens you to https://www.owasp.org/index.php/SQL_Injection. Instead, use database binding which incidentally fixes your actual error (which is that you are treating sample as a column name, rather than data).
Ok, might as well write it up:
import sqlite3
db = sqlite3.connect(':memory')
#you control this stuff, as the db schema isn't typically coming from user data
#so less likely to be a mess...
#i.e. build your query templates with string substitutions, but exec with binds.
tablename = 'test'
db.execute('CREATE TABLE IF NOT EXISTS %s (name TEXT)' % (tablename))
print("Table created successfully")
qry = 'INSERT INTO %s VALUES (?)' % (tablename)
#the data is where you want to be careful
db.execute(qry, ('sample',))
print ("insert done")
db.close()
which gives:
Table created successfully
insert done
Check out docs # https://docs.python.org/2/library/sqlite3.html Starting at # Never do this -- insecure!.

how to populate database using python faker

I am trying to populate a table using python faker and I am getting this error . Here is my code
import psycopg2
from faker import Faker
fake = Faker()
conn = psycopg2.connect(database="testdb", user="****", password="****", host="127.0.0.1", port="5432")
print "Opened database successfully"
cur = conn.cursor()
for i in range (10):
Id =fake.random_digit_not_null()
name = fake.name()
age=fake.random_number(digits=None)
adress =fake.address()
salary = fake.random_int(min=0, max=9999)
cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \
VALUES (Id,name,age,adress,salary)");
conn.commit()
print "Records created successfully";
conn.close()
here is the error
Traceback (most recent call last):
File "fakegenerator.py", line 16, in <module>
VALUES (Id,name,age,adress,salary)");
psycopg2.ProgrammingError: column "id" does not exist
LINE 1: ...OMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (Id,name,ag...
^
HINT: There is a column named "id" in table "company", but it cannot be referenced from this part of the query.
You're not filling in the values into your query, instead you're sending the string as-is to the database. This would actually fill your query with values:
cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (%s, %s, %s, %s, %s)", (Id, name, age, adress, salary));
This wraps the variables filled with the values you want to insert into a tuple and let's psycopg2 handle quoting your strings correctly which is less work for you and keeps you safe from SQL injection, should you use your code as a base for productive code. This is documented in the module's documentation.
the sql request in cur.execute seems to be a problem try this
cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \
VALUES ({},{},{},{},{})".format(Id,name,age,adress,salary));

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.

Python Mysql issue with %s for the table

Question
Why does %s escape sequence not work in my Python script with MySQL package?
Background and Code
I have an issue with the following line:
cursor.execute("""INSERT INTO `%s` (Date, Counter_in, Counter_out, Interface_name) VALUES (CURRENT_TIMESTAMP, %s, %s, %s)""", (Equipment, In_Octets, Out_Octets, interface))
I get the following error message :
Traceback (most recent call last):
File "SNMP_Query.py", line 41, in <module>
cursor.execute("""INSERT INTO `%s` (Date, Counter_in, Counter_out, Interface_name) VALUES (CURRENT_TIMESTAMP, %s, %s, %s)""", (Equipment, In_Octets, Out_Octets, interface))
File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 166, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1146, "Table 'Sipartech.'itx6-f10-1'' doesn't exist")
I have double checked and the table itx6-f10-1 and indeed it does exist.
One mistake I can notice in your insert query is that you are write Date a column name without (`) symbol, where date is MySQL date type: keyword. So, in your query :-
cursor.execute("""INSERT INTO `%s` (Date, Counter_in,
^
should be
cursor.execute("""INSERT INTO `%s` (`Date`, `Counter_in`,
^ added (`)
Second, I couldn't understand why MySQL:1146 Error? It happen when database files are missing.
As I can notice %s is working that is how you could find database name from Equipment a Python variable in your code.
But why you are getting:
'Sipartech.'itx6-f10-1''
^ ^ extra '
of-course this can't be a data base name and may be the reason for mysql error:1146 , you should get:
'Sipartech.itx6-f10-1'
Check the code and query.
Also if you have doubt with %s, then you can use string.formate() function instead of %s. like:
"""
INSERT INTO {0} ( `Date`,
`Counter_in`,
`Counter_out`,
`Interface_name`)
VALUES (CURRENT_TIMESTAMP, {1}, {2}, {3})
""".formate(Equipment, In_Octets, Out_Octets, interface))
Also, Remember if In_Octets, Out_Octets, interface are not integers then put ' around each braces {} in query string.

Error message in python-mysql cursor: 1054 unknown column "x" in 'field list'

This is my first post! I also just started programming, so please bear with me!
I am trying to load a bunch of .csv files into a database, in order to later perform various reports on the data. I started off by creating a few tables in mysql with matching field names and data types to what will be loaded into the tables. I am manipulating the filename (in order to parse out the date to use as a field in my table) and cleaning up the data with python.
So my problem right now (haha...) is that I get this error message when I attempt the 'Insert Into' query to mysql.
Traceback (most recent call last):
File "C:\Program Files\Python\load_domains2.py", line 80, in <module>
cur.execute(sql)
File "C:\Program Files\Python\lib\site-packages\MySQLdb\cursors.py", line 166, in execute
self.errorhandler(self, exc, value)
File "C:\Program Files\Python\lib\site-packages\MySQLdb\connections.py", line 35, in defaulterrorhandler
raise errorclass, errorvalue
OperationalError: (1054, "Unknown column 'a1200e.com' in 'field list'")
'a1200e.com' refers to a specific domain name I'm inserting into that column. My query is as follows:
sql="""INSERT INTO temporary_load
(domain_name, session_count, search_count, click_count,
revenue, revenue_per_min, cost_per_click, traffic_date)
VALUES (%s, %d, %d, %d, %d, %d, %d, %s)""" %(cell[0],
int(cell[1]),
int(cell[2].replace (",","")),
int(cell[3].replace(",","")),
float(cell[4].replace("$","")),
float(cell[5].replace("$","")),
float(cell[6].replace("$","")),
parsed_date)
cur.execute(sql)
I am very new at all this, so I'm sure my code isn't at all efficient, but I just wanted to lay everything out so it's clear to me. What I don't understand is that I have ensured my table has correctly defined data types (corresponding to those in my query). Is there something I'm missing? I've been trying to work this out for a while, and don't know what could be wrong :/
Thanks so much!!!
Val
Thomas is, as usual, absolutely correct: feel free to let MySQLdb handle the quoting issues.
In addition to that recommendation:
The csv module is your friend.
MySQLdb uses the "format" parameter style as detailed in PEP 249.
What does that mean for you?
All parameters, whatever type, should be passed to MySQLdb as strings (like this %s). MySQLdb will make sure that the values are properly converted to SQL literals.
By the way, MySQLdb has some good documentation.
Feel free to include more detail about your source data. That may make diagnosing the problem easier.
Here's one way to insert values to a MySQL database from a .csv file:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import csv
import MySQLdb
import os
def main():
db = MySQLdb.connect(db="mydb",passwd="mypasswd",) # connection string
filename = 'data.csv'
f = open(filename, "rb") # open your csv file
reader = csv.reader(f)
# assuming the first line of your csv file has column names
col_names = reader.next() # first line of .csv file
reader = csv.DictReader(f, col_names) # apply column names to row values
to_db = [] # this list holds values you will insert to db
for row in reader: # loop over remaining lines in .csv file
to_db.append((row['col1'],row['col2']))
# or if you prefer one-liners
#to_db = [(row['col1'],row['col2']) for row in reader]
f.close() # we're done with the file now
cursor = db.cursor()
cursor.executemany('''INSERT INTO mytable (col1,col2)
VALUES (%s, %s)''', to_db) # note the two arguments
cursor.close()
db.close()
if __name__ == "__main__":
main()
You should be using DB-API quoting instead of including the data in the SQL query directly:
sql = """INSERT INTO temporary_load
(domain_name, session_count, search_count, click_count,
revenue, revenue_per_min, cost_per_click, traffic_date)
VALUES (%s, %d, %d, %d, %d, %d, %d, %s)"""
args = (cell[0],
int(cell[1]),
int(cell[2].replace (",","")),
int(cell[3].replace(",","")),
float(cell[4].replace("$","")),
float(cell[5].replace("$","")),
float(cell[6].replace("$","")),
parsed_date)
cur.execute(sql, args)
This makes the DB-API module quote the values appropriately, and resolves a whole host of issues that you might get when doing it by hand (and usually incorrectly.)

Categories

Resources