Here is a sample of python code:
query = "SELECT * FROM users WHERE id = 17"
cursor.execute(query)
row = cursor.fetchone()
In this example, the query is meant to return at most a single row; but sometimes I want to fetch a single row from a multiple-row result with the same code, for instance:
query = "SELECT * FROM users WHERE name LIKE 'foo%'"
cursor.execute(query)
row = cursor.fetchone()
In term of performance, is it better to explicitly write LIMIT 1?
No, the LIMIT clause is executed after the SELECT on the Result set. if you have much rows with the id = 17 , you must transfer a little bit more from the server to the client if you do not use LIMIT.
Related
This question has been asked a dozen times on this site with no real answer.
I use mysql.connector all the time for work, but recently I've discovered that it does not consistently return all results.
sql = ("""SELECT cp.location, cpt.created_ts, cpt.amount FROM
customer_plan_transactions cpt
JOIN customer_plans cp on cp.id = cpt.customer_plan_id
WHERE cpt.created_ts like "2022-09%" """)
cursor = my_db.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
print(len(rows))
4395
Though, if I run this query through phpMyAdmin:
Any ideas? Is there another library I should be using for MySql?
edit: It must be a bug with mysql.connector. If I simply re-order the fields in the select statement, I suddenly get all the rows I am expecting.
sql = ("""SELECT cpt.created_ts, cp.location, cpt.amount FROM customer_plan_transactions cpt
JOIN customer_plans cp on cp.id = cpt.customer_plan_id
WHERE cpt.created_ts between "2022-09-01" and "2022-10-01" """)
cursor = jax_uc.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
print(len(rows))
63140
So, it's a bug, right?
I am using Sqlite3 and Python. Here is some sample code:
test
-----------------
amount | date
query = "SELECT SUM (column1) FROM test WHERE date BETWEEN '"+blah+"' AND '"+blah+"'"
c.execute(query)
data = c.fetchone()
if not data:
amountsum = 0
else:
amountsum = data[0]
print(amountsum)
The problem is that it only runs else:. If data is NoneType it does not set amountsum to 0 either. How can I make this work?
In this case, data will never be None, due to the aggregating query. SELECT SUM(...) FROM table will always return exactly one row. However, the SUM can be None in SQLite, if there are no rows in the table, so that should be taken into account:
query = "SELECT SUM (column1) FROM test WHERE ..."
c.execute(query)
data = c.fetchone()
amount = data[0] or 0
(A sidenote: you seem to be creating your SQL query using string concatenation, which is a potential SQL injection vulnerability. Consider using parameterized queries instead.)
The problem is, to get count and table data, I have to hit the database two times in Django. For example:
count = queryset.count() # To get count
data = queryset.values('columns') # To get data
Is there any way to get data in the single query. One solution is to use len() function, but it is not good for a bigger table to load in RAM.
In mysql, I got this, But how to execute through Django ORM
SELECT t1.count, id FROM table1, (select count(*) as count FROM table1) as t1 limit 10;
Any help will be appreciated.
I mean len should just count what is already in memory if you get the data first, so it should be better than two queries to database.
data = queryset.values('columns') # To get data
count = len(data) # To get count from database records in memory
Anyway, for direct database queries without the model layer from Django docs:
from django.db import connection
def my_custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("SELECT t1.count, id FROM table1, (select count(*) as count FROM table1) as t1 limit 10")
row = dictfetchall(cursor)
return row
I have a piece of code that I realized is probably quite inefficient, though I'm not sure how to improve it.
Basically, I have a database table like this:
Example DB table
Any or several of columns A-G might match my search query. If that is the case, I want to query VALUE from that row. I need VALUE not to equal NULL though, so if that's the case, it should keep looking. If my query were abc, I'd want to obtain correct.
Below is my current code, using a database named db with a table table.
cur=db.cursor()
data="123"
fields_to_check=["A","B","C","D","E","F","G"]
for field in fields_to_check:
"SELECT Value FROM table WHERE {}='{}'".format(field,data)
query=cur.fetchone()
if query and query !="NULL":
break
db.close()
I think that the fact that this performs 8 queries is likely very inefficient.
cur=db.cursor()
data="123"
fields_to_check=["A","B","C","D","E","F","G"]
sub_query = ""
for field in fields_to_check:
sub_query = sub_query + "or {}='{}' ".format(field,data)
if sub_query:
query = "SELECT Value FROM table WHERE ("+ str(sub_query[2:]) +") and value IS NOT NULL;"
if query:
cur.execute(query)
rows = cur.fetchall()
if rows:
for row in rows:
print(row)
I want to know if a row exists already in one of my tables, in this case coll. In order to do this I played around with SQLite in the shell a little and stumbled upon SELECT EXISTS(SELECT 1 FROM coll WHERE ceeb="1234"). In SQLite this works perfectly and it returns either a 0 or a 1-- which is exactly what I wanted. So, with code in hand, I wrote up a quick Python script to see if I could get this to work for me before sticking it into my program. This is what I came up with:
import sqlite3
conn = sqlite3.connect('stu.db')
c = conn.cursor()
sceeb = int(raw_input(":> "))
ceeb_exists = c.execute('SELECT EXISTS(SELECT 1 FROM coll WHERE ceeb="%d" LIMIT 1)' % sceeb)
print ceeb_exists
Instead of assigning ceeb_existsa 1 or a 0 it gives me an output that looks like <sqlite3.Cursor object at 0x01DF6860>. What am I doing wrong here?
The execution of a query always results in 0 or more rows. You'd need to fetch those rows; a SELECT EXISTS query results in 1 row, so you'd need to fetch that row.
Rows always consist of 1 or more columns, here you get one, so you could use tuple assignment (note the , comma after ceeb_exists):
c.execute('SELECT EXISTS(SELECT 1 FROM coll WHERE ceeb="%d" LIMIT 1)' % sceeb)
ceeb_exists, = c.fetchone()
However, using an EXISTS query is a bit redundant here; you could just test if there is any row returned. You should also use query parameters to avoid a SQL injection attack (you are asking a user to give you the ceeb value, so that is easily hijacked):
c.execute('SELECT 1 FROM coll WHERE ceeb=? LIMIT 1', (sceeb,))
ceeb_exists = c.fetchone() is not None
cursor.fetchone() returns None if there is no row available to fetch, the is not None test turns that into True or False.
.executes() returns a cursor object as you can see.
In order to print the results of the query you need to iterate over it:
for result in exists:
print result