I have 5 character fields in my SQL database, but I am unable to insert rows into the table. I have no problem when I do in Access Database.
Here is the code for my Insert statement and the error I am getting:
f1=hostname; f2=p.Caption; f3=p.Version; f4="1998-10-01";f5="2018-11-01"
print(f1,'--',f2,'--',f3,'--',f4,'--',f5)
sql = "INSERT INTO software VALUES (%s, %s, %s, %s, %s)"
cursor.execute(sql, {f1,f2,f3,f4,f5})
Error Message:
cursor.execute(sql, (f1,f2,f3,f4,f5)) pyodbc.ProgrammingError: ('The
SQL contains 0 parameter markers, but 5 parameters were supplied',
'HY000')
Assuming you're using pyodbc, the parameter marker is a ?:
sql = "INSERT INTO software VALUES (?, ?, ?, ?, ?)"
Related
I have the following Python code:
cursor.execute("INSERT INTO table VALUES var1, var2, var3,")
where var1 is an integer, var2 and var3 are strings.
How can I write the variable names without Python including them as part of the query text?
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
Note that the parameters are passed as a tuple.
The database API does proper escaping and quoting of variables. Be careful not to use the string formatting operator (%), because
It does not do any escaping or quoting.
It is prone to uncontrolled string format attacks e.g. SQL injection.
Different implementations of the Python DB-API are allowed to use different placeholders, so you'll need to find out which one you're using -- it could be (e.g. with MySQLdb):
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
or (e.g. with sqlite3 from the Python standard library):
cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))
or others yet (after VALUES you could have (:1, :2, :3) , or "named styles" (:fee, :fie, :fo) or (%(fee)s, %(fie)s, %(fo)s) where you pass a dict instead of a map as the second argument to execute). Check the paramstyle string constant in the DB API module you're using, and look for paramstyle at http://www.python.org/dev/peps/pep-0249/ to see what all the parameter-passing styles are!
Many ways. DON'T use the most obvious one (%s with %) in real code, it's open to attacks.
Here copy-paste'd from pydoc of sqlite3:
# Never do this -- insecure!
symbol = 'RHAT'
cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
# Do this instead
t = ('RHAT',)
cur.execute('SELECT * FROM stocks WHERE symbol=?', t)
print(cur.fetchone())
# Larger example that inserts many records at a time
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
('2006-04-06', 'SELL', 'IBM', 500, 53.00),
]
cur.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)
More examples if you need:
# Multiple values single statement/execution
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO'))
print c.fetchall()
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO'))
print c.fetchall()
# This also works, though ones above are better as a habit as it's inline with syntax of executemany().. but your choice.
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO')
print c.fetchall()
# Insert a single item
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00))
http://www.amk.ca/python/writing/DB-API.html
Be careful when you simply append values of variables to your statements:
Imagine a user naming himself ';DROP TABLE Users;' --
That's why you need to use SQL escaping, which Python provides for you when you use cursor.execute in a decent manner. Example in the URL is:
cursor.execute("insert into Attendees values (?, ?, ?)", (name, seminar, paid))
The syntax for providing a single value can be confusing for inexperienced Python users.
Given the query
INSERT INTO mytable (fruit) VALUES (%s)
Generally*, the value passed to cursor.execute must wrapped in an ordered sequence such as a tuple or list even though the value itself is a singleton, so we must provide a single element tuple, like this: (value,).
cursor.execute("""INSERT INTO mytable (fruit) VALUES (%s)""", ('apple',))
Passing a single string
cursor.execute("""INSERT INTO mytable (fruit) VALUES (%s)""", ('apple'))
will result in an error which varies by the DB-API connector, for example
psycopg2:
TypeError: not all arguments converted during string formatting
sqlite3
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 5 supplied
mysql.connector
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax;
* The pymysql connector handles a single string parameter without erroring. However it's better to wrap the string in a tuple even if it's a single because
you won't need to change the code if you switch connector package
you keep a consistent mental model of the query parameters being a sequence of objects rather than a single object.
I'm getting this Sqlite3 programming error: sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 2, and there are 0 supplied.
I'm not sure why. I have tried everything I can think of. Please assist.
Thanks!
import csv
import sqlite3
with sqlite3.connect("new.db") as connection:
c = connection.cursor()
employees = csv.reader(open("employees.csv", "rU"))
#c.execute("CREATE TABLE employees (firstname TEXT, lastname TEXT)")
c.executemany("INSERT INTO employees(firstname, lastname) values (?, ?)", employees)
c.executemany("INSERT INTO employees(firstname, lastname) values (?, ?)", employees)
You have two ?, but supplied only with employees => values (?, ?)", employees)
csv.reader yields a generator expression. Thus, you need to caste the result as a list:
c.executemany("INSERT INTO employees(firstname, lastname) values (?, ?)", list(employees))
employees needs to be a 2d list, some for each call of executemany. You can create is easily using a nested list comprehensions:
import csv
import sqlite3
with sqlite3.connect("new.db") as connection:
c = connection.cursor()
reader = csv.reader(open("employees.csv", "rU"))
employees = [[x for x in row] for row in reader]
c.executemany("INSERT INTO employees(firstname, lastname) values (?, ?)", employees)
Below is my code for loading data in a mysql table (7 column of information):
#!/usr/bin/env python
import mysql.connector, csv, sys
csv.field_size_limit(sys.maxsize)
cnx = mysql.connector.connect(user='testuser', password= 'testuser', database='database')
cursor = cnx.cursor()
table=csv.reader(file("logs.txt"), delimiter='\t')
for row in table:
cursor.execute("INSERT INTO first_table (column1, column2, column3, column4 , column5, column6, column7) VALUES (%s, %s, %s, %s, %s, %s, %s)", row)
cnx.commit()
cnx.close()
Below is truncated content of what logs.txt file consist of, 7 columns (tab-delimited) and the last column (mouse_phene_id) may be empty or has single or multiple items delimited by space:
human_gene_symbol entrez_id homolog_id hgnc_assoc mouse_gene_symbol mouse_mgi_id mouse_phene_id
A1BG 1 11167 yes A1bg MGI:2152878
A1CF 29974 16363 yes A1cf MGI:1917115 MP:0005387 MP:0005386 MP:0005388 MP:0005385 MP:0002873 MP:0010768 MP:0005369 MP:0005376 MP:0005384 MP:0005378
A2M 2 37248 yes A2m MGI:2449119
A3GALT2 127550 16326 yes A3galt2 MGI:2685279
A4GALT 53947 9690 yes A4galt MGI:3512453 MP:0005386 MP:0010768 MP:0005376
A4GNT 51146 87446 yes A4gnt MGI:2143261 MP:0005384 MP:0002006 MP:0005385 MP:0005381 MP:0005387
AAAS 8086 9232 yes Aaas MGI:2443767 MP:0005389 MP:0005386 MP:0005378
AACS 65985 11322 yes Aacs MGI:1926144
AADAC 13 37436 yes Aadac MGI:1915008
I get the following error and since this is a common error, I tried everything that was posted on stackoverflow related to this error and still unfixed and stuck:
Traceback (most recent call last):
File "insert_mysql.py", line 23, in <module>
cursor.execute("INSERT INTO first_table (column1, column2, column3, column4 , column5, column6, column7) VALUES (%s, %s, %s, %s, %s, %s, %s)", row)
File "/usr/local/lib/python2.7/dist-packages/mysql/connector/cursor.py", line 551, in execute "Not all parameters were used in the SQL statement")
mysql.connector.errors.ProgrammingError: Not all parameters were used in the SQL statement
first_table:
Greatly appreciate any help, advice. Thank you in advance.
The error you are seeing is likely being caused by a row in the logs.txt file which does not have the same number of items (7) which your insert prepared statement is expecting. The error
Not all parameters were used in the SQL statement
means that you had one or more positional parameters which could not be assigned values, and hence were not used.
I can make two suggestions about where in the file the problem might be. First, you log file may have one or more header lines, which might not have the same number of columns or types of values the script expects. You may skip any number of initial lines via this:
skip_first_line = next(table)
skip_second_line = next(table)
# etc.
In other words, just call next() to consume any number of initial lines in the log file which do not contain the actual data you want to insert.
If not, then perhaps the problematic line is somewhere in the middle of the file. You can try printing each row in your script, to see where it dies:
for row in table:
cursor.execute("INSERT INTO first_table (column1, column2, column3, column4 , column5, column6, column7) VALUES (%s, %s, %s, %s, %s, %s, %s)", row)
print row
I have multiple list and i would like to insert the data that is stored in the list into the sqlite database.
My insert statement is:
c.executemany("INSERT INTO admin(class, level, registerNo, ic, name) VALUES(?, ?, ?, ?, ?)", (sclass, level, registerNo, ic, name))
But my error stated:
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 5, and there are 10 supplied.
I have a tuple that i wanna store its elements, I'm trying to insert it as following and it gives the following error, what am i doing wrong ? records_to_be_inserted is the tuple that has 8 elements.
with self.connection:
cur = self.connection.cursor()
cur.executemany("INSERT INTO rehberim(names, phone, mobile, email, \
photo, address, note, date) VALUES(?, ?, ?, ?, ?, ?, ?, ?)", self.records_to_be_inserTed)
Traceback (most recent call last):
File "/home/tayfun/workspace/personal_guide/modules/mainwindow.py", line 57, in save_records
photo, address, note, date) VALUES(?, ?, ?, ?, ?, ?, ?, ?)", self.records_to_be_inserTed)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 8, and there are 0 supplied.
Note that the executemany is for inserting multiple rows, e.g.,
import sqlite3
""" the table structure is:
create table tab
a char(1),
b char(2),
c char(3)
)
"""
conn = sqlite3.connect('C:\\test.db')
stmt = "insert into tab (a, b, c) values (?, ?, ?)"
cur = conn.cursor()
## many rows
vals = [('1','2','3'), ('2','3','4'), ('3','4','5')]
cur.executemany(stmt, vals)
cur.close()
This will result in three rows in the database. If it is because you have multiple values in one query, you need to format it!
Edit: Added formatting with dictionaries
By using the following approach you do not need to consider the order of the values in the format call because the key in the dictionary is mapping the value into the {key_word} placeholder.
values = {'a' : 'value_a',
'b' : 'value_b'}
stmt = "insert into tab (col_a, col_b) values ({a}, {b})".format(**values)
The query must have all the data ready to be inserted.
You are calling a function in the query, which i guess you want that provides the data but that wont work.
You need to pass all the data in variables or locate them in the tuple index (like: tuple_name[1], tuple_name[4], etc.)
Example:
myTuple = ['a','b','c','d','e','f','g']
cur.executemany("INSERT INTO rehberim(names, phone, mobile, email, \
photo, address, note, date) VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6}" .format (myTuple[1], myTuple[2], myTuple[3], myTuple[4], myTuple[5], myTuple[6], myTuple[7])