SQL Select where not working - python

I am using Python/Flask and trying to query my DB.
conn = sqlite3.connect('./flaskdb.db')
cur = conn.cursor()
cur.execute('SELECT email FROM users WHERE email=\'%s\'', "name")
I have 2 columns, email, password and the value name, password as one of the row/entries.
Why isn't this working? I get the error:
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 0, and there are 7 supplied.

I think you are getting bogged down with using prepared statements here. Try this code:
conn = sqlite3.connect('./flaskdb.db')
cur = conn.cursor()
name = 'someone#somewhere.com'
cur.execute('SELECT email FROM users WHERE email=?', (name,))
Corrections include using ? as a placeholder instead of %s, the latter which is what might be used for other databases. Also, if you want to bind a variable called name, then it too should not have quotes around it.

I have a solution:
cur.execute('SELECT password FROM users WHERE email=(?)', (email,))
you need it as a tuple and (?) as a placeholder.

Related

Can python cursor.execute accept multiple queries in one go?

Can the cursor.execute call below execute multiple SQL queries in one go?
cursor.execute("use testdb;CREATE USER MyLogin")
I don't have python setup yet but want to know if above form is supported by cursor.execute?
import pyodbc
# Some other example server values are
# server = 'localhost\sqlexpress' # for a named instance
# server = 'myserver,port' # to specify an alternate port
server = 'tcp:myserver.database.windows.net'
database = 'mydb'
username = 'myusername'
password = 'mypassword'
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = cnxn.cursor()
#Sample select query
cursor.execute("SELECT ##version;")
row = cursor.fetchone()
while row:
print(row[0])
row = cursor.fetchone()
Multiple SQL statements in a single string is often referred to as an "anonymous code block".
There is nothing in pyodbc (or pypyodbc) to prevent you from passing a string containing an anonymous code block to the Cursor.execute() method. They simply pass the string to the ODBC Driver Manager (DM) which in turn passes it to the ODBC Driver.
However, not all ODBC drivers accept anonymous code blocks by default. Some databases default to allowing only a single SQL statement per .execute() to protect us from SQL injection issues.
For example, MySQL/Connector ODBC defaults MULTI_STATEMENTS to 0 (off) so if you want to run an anonymous code block you will have to include MULTI_STATEMENTS=1 in your connection string.
Note also that changing the current database by including a USE … statement in an anonymous code block can sometimes cause problems because the database context changes in the middle of a transaction. It is often better to execute a USE … statement by itself and then continue executing other SQL statements.
Yes, it is possible.
operation = 'SELECT 1; INSERT INTO t1 VALUES (); SELECT 2'
for result in cursor.execute(operation, multi=True):
But it is not a comprehensive solution. For example, in queries with two selections, you have problems.
Consider that two types of answers must be fetch all in the cursor!
So the best solution is to break the query to sub queries and do your work step by step.
for example :
s = "USE some_db; SELECT * FROM some_table;"
s = filter(None, s.split(';'))
for i in s:
cur.execute(i.strip() + ';')
in the pyodbc documentation should give you the example your looking for. more over in the GitHub wiki: https://github.com/mkleehammer/pyodbc/wiki/Objects#cursors
you can see an example here:
cnxn = pyodbc.connect(...)
cursor = cnxn.cursor()
cursor.execute("""
select user_id, last_logon
from users
where last_logon > ?
and user_type <> 'admin'
""", twoweeks)
rows = cursor.fetchall()
for row in rows:
print('user %s logged on at %s' % (row.user_id, row.last_logon))
from this example and exploring the code, I would say your next step is testing a multi cursor.execute("<your_sql_Querie>").
if this test works, maybe try and create a CLASS then create instances of that class for each query you want to run.
This would be the basic evolution of a developers effort of reproducing documentation...hope this helps you :)
Yes, you can results for multiple queries by using the nextset() method...
query = "select * from Table1; select * from Table2"
cursor = connection.cursor()
cursor.execute(query)
table1 = cursor.fetchall()
cursor.nextset()
table2 = cursor.fetchall()
The code explains it... cursors return result "sets", which you can move between using the nextset() method.

How to create a database with psycopg2 using execute() second argument?

I'm trying to create a database with the name a user will provide. As far as I know the correct way is to use the second argument of execute().
So I did as follows:
import psycopg2
conn = psycopg2.connect(host="...", dbname="...",
user="...", password="...", port='...')
cursor = conn.cursor()
query = ''' CREATE DATABASE %s ;'''
name = 'stackoverflow_example_db'
conn.autocommit = True
cursor.execute(query, (name,))
cursor.close()
conn.close()
And I got this error:
psycopg2.errors.SyntaxError: syntax error at or near "'stackoverflow_example_db'"
LINE 1: CREATE DATABASE 'stackoverflow_example_db' ;
I need to do this statement avoiding SQL injection, so using the second argument is a must.
You can't pass values as second argument of execute(), if the statement is a CREATE DATABASE one.
As pointed out by unutbu one way to approach this is using the psycopg2.sql submodule and use identifiers to build the statement avoiding SQL injection.
The code:
import psycopg2
from psycopg2 import sql
conn = psycopg2.connect(host="...", dbname="...",
user="...", password="...", port='...')
cursor = conn.cursor()
query = ''' CREATE DATABASE {} ;'''
name = 'stackoverflow_example_db'
conn.autocommit = True
cursor.execute(sql.SQL(query).format(
sql.Identifier(name)))
cursor.close()
conn.close()
Other aditional observations:
format() do not work with %s, use {} instead
Autocommit mode is a must for this statement to work
The specified connection user needs creation privileges

can't see table created by pyodbc in ms access

I am accessing a MS Access Database in Python 3.6 using pyodbc library. I can read a table, no problems. The I created a simple table (Employee). I inserted records. I was able to fetch the records too by reading the table, no problems.
I also listed the tables in the MS Access DB. Employee table shows in the list.
But when I open up the MS Access Database, I do not find the table. I changed MS Access DB to show hidden and system objects. Employee table doesn't show up.
What am I doing wrong?
Thanks
Here is the code:
import pyodbc
db_file = r'''C:\TickData2018\StooqDataAnalysis.accdb'''
user = 'admin'
password = ''
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.accdb)};DBQ=%s;UID=%s;PWD=%s' %\
(db_file, user, password)
# Or, for newer versions of the Access drivers:
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;UID=%s;PWD=%s' %\
(db_file, user, password)
conn = pyodbc.connect(odbc_conn_str)
print("connection made")
c = conn.cursor()
c.execute("SELECT * FROM 5MtsBaseForAnalysisSorted")
list1 = c.fetchmany(2)
print(list1[0][0])
print(list1[0][1])
print(list1[0][2])
try:
c.execute("""CREATE TABLE employee(
first text,
last text,
pay integer
);""")
except Exception as e:
print(e)
conn.commit
c.execute("INSERT INTO employee VALUES ('Krishna', 'Sundar', 50000)")
c.execute("INSERT INTO employee VALUES ('Divya', 'Sundar', 70000)")
c.execute("INSERT INTO employee VALUES ('Panka', 'Sundar', 70000)")
conn.commit
c.execute("SELECT * FROM employee")
print(c.fetchall())
c.tables()
rows = c.fetchall()
for row in rows:
print(row)
c.close()
del c
conn.close()
This is a general Python object model where you need to call the actual function and not its bounded name. Specifically, your commit lines are not correct where
conn.commit
Should be with open/close parentheses:
conn.commit()
Another way to see the difference is by reviewing the object's type:
type(conn.commit)
# <built-in method commit of pyodbc.Connection object at 0x000000000B772E40>
type(conn.commit())
# NoneType
I did reproduce your issue with exact code and adding parentheses resolved the issue.
An additional solution to manually committing is to set autocommit = True when the connection instance is created.
Eg:
conn = pyodbc.connect(odbc_conn_str, autocommit = True)

how to extract a value from database using python

I want to get a value from a database table using python.
I am sending a query and getting value like this:
conn = pymysql.connect(rds_host, user=name, passwd=password,db=db_name, connect_timeout=10)
with conn.cursor() as cur:
cur.execute("SELECT id FROM user_details WHERE email='{}'".format(email)
for row in cur:
id = row[0]
Is there a way to get the value without using for loop.
Couldn't find the doc ?
https://pymysql.readthedocs.io/en/latest/modules/cursors.html#pymysql.cursors.Cursor.fetchone
cursor.fetchone()
Fetch the next row
Also, you definitly DONT want to use string formatting to build your queries (unless you're ok to have your app wide opened to sql injections of couse). You want to use prepared queries instead:
cur.execute("SELECT id FROM user_details WHERE email=?", [email,])

Python Mysqldb Returns Question Marks

I am using the following code in python and it seems to be returning the "Name" as question marks since the name is in russian. Any help would be much appreciated.
import MySQLdb
db = MySQLdb.connect(host="localhost", user="root",passwd="*****")
cur = db.cursor()
cur.execute("USE WebCorpusStatus;")
cur.execute("SELECT Name, Source, Date(dateScraped) FROM russian WHERE status = 1;")
for row in cur:
print row
MySQLdb.connect takes a use_unicode parameter, which may solve the problem. If not, you may also need to set charset to whatever your table uses:
MySQLdb.connect(host="localhost", user="root",passwd="*****", use_unicode=True, charset='xxxxx')
http://mysql-python.sourceforge.net/MySQLdb.html

Categories