I want to insert variable values into db2 table using Python code
id = input("table id: ")
tabname = input("Enter Table name: ")
descr = input("Enter description : ")
inser_sql = "INSERT INTO schema.table VALUES (?, ?, ?)",(id, tabname, descr)
stmt = ibm_db.prepare(conn, inser_sql)
ibm_db.execute(stmt)
this code gives me error:
stmt = ibm_db.prepare(conn, inser_sql)
Exception: statement must be a string or unicode
Assuming that your table is defined like this:
"create table myschema.mytable(id int, tabname varchar(10), description varchar(10))"
I understand your intention is to insert a specific row into it with a prepared statement and parameter markers.
Skipping the input part:
In [14]: id = 1
In [15]: tabname = 'TAB'
In [16]: descr = 'my desc'
you just need to prepare the statement first, bind the parameters later and then execute:
insert_sql = "INSERT INTO myschema.mytable VALUES (?, ?, ?)"
prep_stmt = ibm_db.prepare(conn, insert_sql)
ibm_db.bind_param(prep_stmt, 1, id)
ibm_db.bind_param(prep_stmt, 2, tabname)
ibm_db.bind_param(prep_stmt, 3, descr)
ibm_db.execute(prep_stmt)
The exact answer will depend on the specific DB2 library you're using, but the variable holding your query should just be a plain string.
You will probably need to pass parameters to it when you execute the statement:
inser_sql = "INSERT INTO schema.table VALUES (?, ?, ?)"
stmt = ibm_db.prepare(conn, inser_sql)
ibm_db.execute(stmt, (id, tabname, descr))
# ^^^^^^^^^^^^^^^^^^^^
Related
I have a python function that deletes a row in mysql table using name attribute as a condition:
def delete(table: str, name: str):
cursor.execute(f"DELETE FROM {table} WHERE name = {name}")
conn.commit()
I have one row with a name attribute equal to "Name". When I use this function with "Name" it deletes every single row in a table.
I'm guessing that it has to do with passed string being same as attribute. But what would be the solution to that problem except renaming attributes?
So for one, I think you are missing quotes around name, as well as a semicolon.
For further reading you should also take a look at Python parameterized query and Prepared Statement
I do agree with the comments, that table should not be an injected argument for security reasons!
def delete(table: str, name: str):
query = f"DELETE FROM {table} WHERE name = ?"
print(query)
cursor.execute(query, (name,))
conn.commit()`
EDIT FULL WORKING EXAMPLE:
import sqlite3
conn = sqlite3.connect("test")
query_create = '''CREATE TABLE IF NOT EXISTS projects (
id integer PRIMARY KEY,
name text NOT NULL,
begin_date text,
end_date text
);'''
conn.execute(query_create)
query_insert = '''insert into projects (id, name, begin_date, end_date) values (1,"name","date","date")'''
conn.execute(query_insert)
query_select = '''select * from projects'''
cur = conn.execute(query_select)
print(cur.fetchall())
def delete(table: str, name: str):
query = f"DELETE FROM {table} WHERE name = ?"
print(query)
conn.execute(query, (name,))
delete('projects', 'name')
cur = conn.execute(query_select)
print(cur.fetchall())
Gives Output:
[(1, 'name', 'date', 'date')]
DELETE FROM projects WHERE name = ?
[]
This question already has answers here:
How to use variables in SQL statement in Python?
(5 answers)
Closed 3 years ago.
I’m setting up a new flask app, and I'm using sqlite3 as DB. It is possible to maintain the setup even if I have to insert 5 values?
def encrypt():
now = datetime.now()
date_time = now.strftime("%d/%m/%Y - %H:%M")
filename = secure_filename(request.form['filename'].replace(" ", "_").replace("(", "").replace(")", ""))
password = request.form['password']
username = session.get('username')
id = request.form['id']
type = infile[-4:]
file = filename[:-4] + '.enc'
infile = os.path.join(app.config['DATA_FOLDER'], filename)
outfile = os.path.join(app.config['DATA_FOLDER'], filename[:-4] + '.enc')
con = sqlite3.connect(app.config['DataBase'])
cur = con.cursor()
cur.executemany('INSERT INTO keys (id, file, type, date_time, attempts) VALUES (?,?,?,?,?)', id, file, type, date_time, "0")
con.commit()
con.close()
return 'ok'
The following error is shown in logs:
File "./myapp.py", line 524, in encrypt
cur.executemany('INSERT INTO keys (id, file, type, date_time, attempts) VALUES (?,?,?,?,?)', id, file, type, date_time, "0")
TypeError: function takes exactly 2 arguments (6 given)
Firstly, you don't need to use executemany as that is used when you want to insert multiple rows into a single table. What you have there is just multiple values that will represent a single row. Use placeholders for the values in the SQL statement, and pass a tuple as the second argument to execute.
cur.execute('INSERT INTO keys (id, file, type, date_time, attempts) VALUES (?, ?, ?, ?, ?)', (id, file, type, date_time, "0"))
Bonus answer (the executemany case)
Now, when you want to insert multiple rows in the same table, you'd use the cursor.executemany method. And that takes 2 arguments, like you've found out in your error above:
a string, which represents the SQL query
a collection of parameters, where each parameter is a list of values representing a row
The sql query is executed against all parameters in the collection.
Working example with both execute and executemany that can be pasted in a Python file and run
import sqlite3
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
cursor.execute('CREATE TABLE person (first_name text, last_name text, age integer)')
cursor.execute('SELECT * FROM person')
print(cursor.fetchall()) # outputs []
first_name, last_name, age = 'Carl', 'Cox', 47
cursor.execute('INSERT INTO person (first_name, last_name, age) VALUES (?, ?, ?)', (first_name, last_name, age))
cursor.execute('SELECT * FROM person')
print(cursor.fetchall()) # outputs [('Carl', 'Cox', 47)]
many_values = [
('Boris', 'Brejcha', 37),
('Mladen', 'Solomun', 43),
]
cursor.executemany('INSERT INTO person (first_name, last_name, age) VALUES (?, ?, ?)', many_values)
cursor.execute('SELECT * FROM person')
print(cursor.fetchall()) # outputs [('Carl', 'Cox', 47), ('Boris', 'Brejcha', 37), ('Mladen', 'Solomun', 43)]
conn.close()
So you see in the executemany case how the method takes just 2 parameters, but the 2nd parameter is a sequence of sequences.
I am getting the error 'sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 4, and there are 1 supplied.' The below code should be making a database and creating a table with the the titles listed below. Then take values from a csv. file and add it under the allotted headings. Any help would be would be appreciated!
import const
import sqlite3
SEP = ','
DATA_FILENAME = 'pokemon.csv'
con = sqlite3.connect('poki.db')
cur = con.cursor()
cur.execute('DROP TABLE IF EXISTS poki')
cur.execute( ' CREATE TABLE poki( pokemon TEXT, species_id INTEGER,'
' height REAL, weight REAL)' )
values = ('INSERT INTO poki VALUES (?, ?, ?, ?)')
for line in DATA_FILENAME:
list_of_values = line.strip().split(SEP)
cur.execute(values, list_of_values)
cur.close()
con.commit()
con.close()
Dears,
how can I check if pos_cli from database is equal to variable pos_id? for now with code below I get the following error
cur.execute("CREATE TABLE IF NOT EXISTS Magnit_Coor (pos_cli INTEGER PRIMARY KEY, lat INTEGER, long INTEGER);")
cur.execute('SELECT * FROM Magnit_pos')
data = cur.fetchall()
while True:
for coo in data:
full_add = coo[6:11]
pos_id = coo[0]
print (pos_id)
yand_add = ", ".join(full_add)
g = cur.execute('SELECT EXISTS (SELECT * FROM Magnit_Coor WHERE pos_cli = (?))',pos_id)
g = cur.fetchone()[0]
error below
10001
Traceback (most recent call last):
File "geoco.py", line 17, in <module>
g = cur.execute('SELECT EXISTS (SELECT * FROM Magnit_pos WHERE pos_cli = (?))',pos_id)
ValueError: parameters are of unsupported type
The initial code to create Magnit_pos table and pos_cli especially below
cur.execute("DROP TABLE IF EXISTS Magnit_Pos;")
cur.execute(
"CREATE TABLE Magnit_Pos (pos_cli INTEGER PRIMARY KEY, magnit_name TEXT, codesfa TEXT, codewsot TEXT, pos_sap TEXT, source_dc TEXT, zip TEXT, region TEXT, area TEXT, city TEXT, street TEXT, house TEXT, build TEXT);")
with open('magnit.csv') as csvfile:
magnit = csv.reader(csvfile, delimiter=';')
print(magnit)
for row in magnit:
print(row[0])
# to_db = [unicode(row[0], "utf8"), unicode(row[1], "utf8")]
cur.execute("INSERT INTO Magnit_Pos (pos_cli, magnit_name, codesfa, codewsot, pos_sap, source_dc, zip, region, area, city, street, house, build) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", row)
From python's sqlite3 documentation (emphasis mine):
Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor’s execute() method.
So you should be using:
g = cur.execute('SELECT EXISTS (SELECT * FROM Magnit_Coor WHERE pos_cli = (?))',(pos_id,))
I wrote a program in order to dynamically update a database table but I am getting an error. I stuffed the program with whatever I know little about. Here's my code:
import MySQLdb
class data:
def __init__(self):
self.file123 = raw_input("Enter film: ")
self.title_ = raw_input("Enter film: ")
self.year = raw_input("Enter year: ")
self.director = raw_input("Enter director: ")
a=data()
db = MySQLdb.connect(host="localhost", # your host, usually localhost
user="root", # your username
passwd="mysql", # your password
db="sakila") # name of the data base
cursor = db.cursor()
cursor.execute("INSERT INTO films (file123, title_, year, director) VALUES (?, ?, ?, ?)", (a.file123, a.title_, a.year, a.director))
db.commit()
db.close()
This is the error:
File "C:\Python27\maybe1.py", line 20, in <module>
cursor.execute("INSERT INTO films (file123, title_, year, director) VALUES (?, ?, ?, ?)", (a.file123, a.title_, a.year, a.director))
File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 184, in execute
query = query % db.literal(args)
TypeError: not all arguments converted during string formatting
How can I fix this issue ?
You should change ? to %s.
Here is question about why mysqldb use %s instead of ?.
I would do it this way:
query = "INSERT INTO films (file123, title_, year, director) VALUES (%s, %s, %s, %s)" % (a.file123, a.title_, a.year, a.director)
cursor.execute(query)
Replace %s with correct data type, else it will try everything as string which might break at table level.