I am trying to insert values into database table using Python. I have connected to the database server and have gotten the INSERT INTO sql statement to work, however I cannot figure out how to insert values from a list into my database. I think my problem is simple, and just involves using the for-in loop correctly, but I do not know how to fix it.
The line I need help with is "for i in cur:
cur.execute("INSERT INTO Events2013 VALUES (i))")"
Here is part of my code:
import cx_Oracle
import fileDb
import g
fileDb.loadTeams()
fileDb.loadEvents()
for event in g.eventList:
print '%s, %s, %s' % (event.eventName, event.eventType, event.dates)
dsn_tns = cx_Oracle.makedsn('hostname', 1521, 'orcl')
con = cx_Oracle.connect('std15', 'std15', dsn_tns)
cur = con.cursor()
for i in cur:
cur.execute("INSERT INTO Events2013 VALUES (i))")
cur.execute("SELECT * FROM Events2013")
for result in cur:
print result
cur.execute("COMMIT")
cur.close()
con.close()
cur.execute("INSERT INTO Events2013 VALUES (i))")
that i doesn't automatically expand to the variables (it's passed as a literal i)
I imagine you need something like
for event in g.eventList:
cur.execute("INSERT INTO Events2013 VALUES ('%s','%s','%s')" % (event.eventName, event.eventType, event.dates))
Related
I am struggling with generating the delete query where parameters for the query is actually a set of values.
So I need to delete rows where parameters are a pair values for example:
delete from table where col1 = %s and col2 = %s
which can be executed in Python like:
cur = conn.cursor()
cur.execute(query, (col1_value, col2_value))
Now I would like to run a query:
delete from table where (col1, col2) in ( (col1_value1, col2_value1), (col1_value2, col2_value2) );
I can generate the queries and values and execute the exact SQL but I can't quite generate prepared statement.
I tried:
delete from table where (col1, col2) in %s
and
delete from table where (col1, col2) in (%s)
But when I try to execute:
cur.execute(query, list_of_col_value_tuples)
or
cur.execute(query, tuple_of_col_value_tuples)
I get an exception that indicates that psycopg2 cannot convert arguments to strings.
Is there any way to use psycopg2 to execute a query like this?
You could dynamically add %s placeholders to your query:
cur = con.cursor()
query = "delete from table where (role, username) in (%s)"
options = [('admin', 'foo'), ('user', 'bar')]
placeholders = '%s,' * len(options)
query = query % placeholders[:-1] # remove last comma
print(query)
print(cur.mogrify(query, options).decode('utf-8'))
Out:
delete from table where (role, user) in (%s,%s)
delete from table where (role, user) in (('admin', 'foo'),('user', 'bar'))
Alternatively, build the query using psycopg2.sql as answered there.
Actually the resolution is quite easy if carefully constructed.
In the miscellaneous goodies of psycopg2 there is a function execute_values.
While all the examples that are given by psycopg2 deal with inserts as the function basically converts the list of arguments into a VALUES list if the call to delete is formatted like so:
qry = "delete from table where (col1, col2) in (%s)"
The call:
execute_values(cur=cur, qry=qry, argslist=<list of value tuples>)
will make the delete perform exactly as required.
This question already has answers here:
How to use variables in SQL statement in Python?
(5 answers)
Closed 11 months ago.
I have created a database with postgresql. I am able to insert string values into table. I want to insert variable data into table. But I am getting invalid syntax for integer error.
import psycopg2
temp= 30
hum = 50
conn = psycopg2.connect('dbname=test')
cur = conn.cursor()
cur.execute("INSERT INTO DHT11 (temperature, humidity) VALUES('temp','hum')")
conn.commit()
cur.execute('select * from DHT11')
results = cur.fetchall()
for result in results:
print(result)
Please use parameters when passing values into your queries, like so:
import psycopg2
temp= 30
hum = 50
conn = psycopg2.connect('dbname=test')
cur = conn.cursor()
cur.execute("INSERT INTO DHT11 (temperature, humidity) VALUES(%s, %s)", (temp, hum))
conn.commit()
cur.execute('select * from DHT11')
results = cur.fetchall()
for result in results:
print(result)
When you use this form you protect yourself from SQL Injection. The driver also takes care of escaping and quoting the values you are passing into the query.
In your original code, putting 'temp' and 'hum' in your query string tried to put the literal values, temp and hum into your table. The strings are not integers.
This is my R piece of code but i want to do the same thing in python, as i am new in it having problems to write the correct code can anybody guide me how to write this is python. I have already made connections of database and also tried simple queries but here i am struggling
sql_command <- "SELECT COUNT(DISTINCT Id) FROM \"Bowlers\";"
total<-as.numeric(dbGetQuery(con, sql_command))
data<-setNames(data.frame(matrix(ncol=8,
nrow=total)),c("Name","Wkts","Ave","Econ","SR","WicketTaker","totalovers",
"Matches"))
for (i in 1:total){
sql_command <- paste("SELECT * FROM \"Bowlers\" where Id = ", i ,";",
sep="")
p<-dbGetQuery(con, sql_command)
p[is.na(p)] <- 0
data$Name[i] = p$bowler[1]
}
after this which works fine how should i proceed to write the loop code:
with engine.connect() as con:
rs=con.execute('SELECT COUNT(DISTINCT id) FROM "Bowlers"')
for row in rs:
print (row)
Use the format method for strings in python to achieve it.
I am using postgresql, but your connection should be similar. Something like:
connect to test database:
import psycopg2
con = psycopg2.connect("dbname='test' user='your_user' host='your_host' password='your_password'")
cur = con.cursor() # cursor method may differ for your connection
loop over your id's:
for i in range(1,total+1):
sql_command = 'SELECT * FROM "Bowlers" WHERE id = {}'.format(i)
cur.execute(sql_command) # execute and fetchall method may differ
rows = cur.fetchall() # check for your connection
print ("output first row for id = {}".format(i))
print (rows[0]) # sanity check, printing first row for ids
print('\n') # rows is a list of tuples
# you can convert them into numpy arrays
I'm trying to insert rows on a MySQL table using pymysql (Python 3), the relevant code is the following.
def saveLogs(DbConnection, tableName, results):
for row in results:
formatStrings = ",".join(["?"]*len(row))
sql = "INSERT INTO %s VALUES (%s);"%(tableName,formatStrings)
DbConnection.cursor().execute(sql, tuple(row))
DbConnection.commit()
I'm using "?" for the types, but I get the error not all arguments converted during string formatting. row is a list composed of strings, ints and datetime.datetime. I guess the issue is the "?" but I have checked the PEP 249 and it's still not clear to me how should I do it. Any suggestions?
Use string formatting for the table name only (though make sure you trust the source or have a proper validation in place). For everything else, use query parameters:
def saveLogs(DbConnection, tableName, results):
cursor = DbConnection.cursor()
sql = "INSERT INTO {0} VALUES (%s, %s, %s)".format(tableName)
for row in results:
cursor.execute(sql, row)
DbConnection.commit()
There is also that executemany() method:
def saveLogs(DbConnection, tableName, results):
cursor = DbConnection.cursor()
cursor.executemany("INSERT INTO {0} VALUES (%s, %s, %s)".format(tableName), results)
DbConnection.commit()
When executing the following:
import pymysql
db = pymysql.connect(host='localhost', port=3306, user='root')
cur = db.cursor()
print(cur.execute("SELECT ParentGuardianID FROM ParentGuardianInformation WHERE UserID ='" + UserID + "'"))
The output is1
How could I alter the code so that the actual value of the ParentGuardianID (which is '001') is printed as opposed to 1.
I'm sure the answer is simple but I am a beginner so any help would be much appreciated - thanks!
cur.execute() just returns the number of rows affected. You should do cur.fetchone() to get the actual result, or cur.fetchall() if you are expecting multiple rows.
The cursor.execute() method gives out a cursor related to the result of the SQL sentence. In case of a select query, it returns the rows (if any) that meet it. So, you can iterate over these rows using a for loop for instance. In addition, I would recommend you to use pymysql.cursors.DictCursor because it allows treating the query results as a dictionary.
import pymysql
db = pymysql.connect(host='localhost', port=3306, user='root')
cur = db.cursor(pymysql.cursors.DictCursor)
UserId = 'whatsoever'
sql = "SELECT ParentGuardianID FROM ParentGuardianInformation WHERE UserID ='%s'"
cur.execute(sql % UserId)
for row in cur:
print(row['ParentGuardianID'])
Good luck!