I want to select values from MySQL as follows
do_not_select = [1,2,3]
cursor = database.cursor()
cursor.executemany("""SELECT * FROM table_a WHERE id != %s""",(do_not_select))
data = cursor.fetchall()
The query return all the values in the db apart form the first id (1). I don't want it to select id 1,2 or 3 however.
Is this possible using the executemany command..?
Give NOT IN a go:
do_not_select = [1, 2, 3]
cursor.execute("""SELECT * FROM table_a
WHERE id NOT IN ({}, {}, {})""".format(do_not_select[0],
do_not_select[1],
do_not_select[2]))
data.cursor.fetchall()
I suspect (though I haven't tested this) that this would work better id do_not_select was a tuple, then I think you could just fire it straight into your query:
do_not_select = (1, 2, 3)
cursor.execute("""SELECT * FROM table_a
WHERE id NOT IN {}""".format(do_not_select))
data.cursor.fetchall()
I'd be interested to know if this works - if you try it please let me know :)
Related
I have a sqlite database named StudentDB which has 3 columns Roll number, Name, Marks. Now I want to fetch only the columns that user selects in the IDE. User can select one column or two or all the three. How can I alter the query accordingly using Python?
I tried:
import sqlite3
sel={"Roll Number":12}
query = 'select * from StudentDB Where({seq})'.format(seq=','.join(['?']*len(sel))),[i for k,i in sel.items()]
con = sqlite3.connect(database)
cur = con.cursor()
cur.execute(query)
all_data = cur.fetchall()
all_data
I am getting:
operation parameter must be str
You should control the text of the query. The where clause shall allways be in the form WHERE colname=value [AND colname2=...] or (better) WHERE colname=? [AND ...] if you want to build a parameterized query.
So you want:
query = 'select * from StudentDB Where ' + ' AND '.join('"{}"=?'.format(col)
for col in sel.keys())
...
cur.execute(query, tuple(sel.values()))
In your code, the query is now a tuple instead of str and that is why the error.
I assume you want to execute a query like below -
select * from StudentDB Where "Roll number"=?
Then you can change the sql query like this (assuming you want and and not or) -
query = "select * from StudentDB Where {seq}".format(seq=" and ".join('"{}"=?'.format(k) for k in sel.keys()))
and execute the query like -
cur.execute(query, tuple(sel.values()))
Please make sure in your code the provided database is defined and contains the database name and studentDB is indeed the table name and not database name.
Using Psycopg2, I need to test whether a postgresql table exists or not.
In a similar question, it is recommended to use the following test:
cursor.execute("select exists(select * from myDb.mytable_%s)" % complementName)
tableExists = cursor.fetchone()[0]
print(tableExists)
This works great if the table already exists, and returns True, but it does not work if the table does not exist. Instead of returning False like I would need, I get an error
ProgrammingError: relation "myDb.mytable_001"
does not exist
What am I doing wrong? What should I do in order to get a False statement if the table doesn't exist? Thanks for any help!
EDIT
Following advice in comments, I tried also:
tableExists = cursor.execute("SELECT 1 AS result FROM pg_database WHERE datname='mytable_001'")
and
tableExists = cursor.execute("SELECT EXISTS (SELECT 1 AS result FROM pg_tables WHERE schemaname = 'mySchema' AND tablename = 'mytable_001)')")
But both simply return None, whether the table exists or not. However, I'm not sure of the syntax, maybe you can point out some novice mistake I may be making? Thanks!
EDIT 2
Finally the solution consisted in a combination of the latter query above, and fetching the boolean result as follows:
cursor.execute("SELECT EXISTS (SELECT 1 AS result FROM pg_tables WHERE schemaname = 'mySchema' AND tablename = 'mytable_001');")
tableExists = cursor.fetchone()[0]
You can get info from information schema like:
SELECT table_schema,table_name
FROM information_schema.tables
WHERE table_name like 'pg_database';
Your query does not seem to right. You are supposed to provide table name for which you are verifying whether it is exist or not...... There are many more ways to verify whether table exist or not why to make it so complex.....
SELECT table_name FROM information_schema.tables where table_schema = 'your schema name' & store output in any variable then verify whether it is empty or not...you should be fine....
or use
query = SELECT EXISTS (SELECT relname FROM pg_class WHERE relname = 'table
name');
resp = cur.execute(query)
rows = cur.fetchone()
print(rows[0])
this will return True if table exist otherwise False....
I want to get the column names of a table, but there a over million data in it.
So I cannot use:
cursor.execute("SELECT * FROM table_name")
print cursor.description
And in sqlite3, I do it this way
crs.execute("PRAGMA table_info(%s)" %(tablename[0]))
for info in crs:
print info
But this is not working in python mysqldb. Any one know how to do that?
You can use SHOW columns:
cursor.execute("SHOW columns FROM table_name")
print [column[0] for column in cursor.fetchall()]
FYI, this is essentially the same as using desc:
cursor.execute("desc table_name")
print [column[0] for column in cursor.fetchall()]
The correct way to do this would be to use "SHOW columns FROM table_name" however, you could also simply add a LIMIT to your existing query:
cursor.execute("SELECT * FROM table_name LIMIT 0")
print cursor.description
Try
cursor.execute("SELECT * FROM table_name LIMIT 1")
or
cursor.execute("SELECT * FROM table_name WHERE 1=0")
Both prevent massive amounts of data being rattled. The second one is perhaps more elegant.
I've just checked, and even this works:
>>>cursor.execute("SELECT LEFT(long_text,5) as short_text FROM table_name WHERE 1=0")
>>>print cursor.description
(('short_text', 253, 0, 5, 5, 31, 0),)
cursor.execute("SELECT * FROM table_name LIMIT 0")
cursor.column_names
Use the following to find other information
[v for v in dir(cursor) if v.find("_")]
data = pd.read_sql("""SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='TABLE_NAME'""", conn)
print(data.COLUMN_NAME)
After creating the connection, using the information schema, we call pull the column names without extracting any observations.
Suppose I have the following very simple query:
query = 'SELECT * FROM table1 WHERE id = %s'
And I'm calling it from a python sql wrapper, in this case psycopg:
cur.execute(query, (row_id))
The thing is that if row_id is None, I would like to get all the rows, but that query would return an empty table instead.
The easy way to approach this would be:
if row_id:
cur.execute(query, (row_id))
else:
cur.execute("SELECT * FROM table1")
Of course this is non idiomatic and gets unnecessarily complex with non-trivial queries. I guess there is a way to handle this in the SQL itself but couldn't find anything. What is the right way?
Try to use COALESCE function as below
query = 'SELECT * FROM table1 WHERE id = COALESCE(%s,id)'
SELECT * FROM table1 WHERE id = %s OR %s IS NULL
But depending how the variable is forwarded to the query it might be better to make it 0 if it is None
SELECT * FROM table1 WHERE id = %s OR %s = 0
I am looking for an sqlite3 command that let's me select entries given by a tuple, let me explain with an example:
Here is my data:
my_data = [(1,8),(2,4),(3,5),(4,7),(5,13)]
and I am trying to extract entries who's first values are either 1,2 or 4; hence, my desired output is:
[(1, 8), (2, 4), (4, 7)]
I can achieve that with a code below; however, I think that my code is not optimal:
import sqlite3
my_data = [(1,8),(2,4),(3,5),(4,7),(5,13)]
key_indexes = (1,2,4)
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute('''CREATE TABLE my_table
(val_1 INTEGER, val_2 INTEGER)''')
for entry in my_data:
c.execute('''INSERT INTO my_table VALUES(?,?)''',entry)
conn.commit()
result = []
for ind in key_indexes:
c.execute('''SELECT* FROM my_table WHERE val_1 = ?''', (ind,))
temp_res = c.fetchall()
result.extend(temp_res)
I am looking for a code that can replace the for loop at the and with an sqlite3 command.
I want to stick (1,2,4) somewhere in this line:
c.execute('''SELECT* FROM my_table WHERE val_1 = ?''', (ind,))
instead of doing a for loop.
Thank You in Advance
To replace the last for-loop you can build up the list of indexes/indices in a string and hit the database just once.
Please note that this is a two-step process, and not vulnerable -- in and of itself -- to SQL injection attacks.
my_query = '''SELECT val_1, val_2
FROM my_table
WHERE val_1 IN ({:s});'''.format(",".join("?"*len(key_indexes)))
# -> 'SELECT val_1, val_2 FROM my_table WHERE val_1 IN (?,?,?);'
c.execute(myquery, ind).fetchall()
Additionally:
You didn't directly ask about this, but the first for loop and call to execute() could be reduced to a single call to executemany().
You should test which of the two options is faster because the DB-API doesn't specify exactly how executemany() should be implemented; performance may differ across RDBMSs.
c.executemany('''INSERT INTO my_table VALUES (?,?);''', my_data)
You may read up on executemany() here: http://www.python.org/dev/peps/pep-0249/
For now, suffice it to say that it takes as the second argument a sequence of parameters.