Python Sqlite: How would you randomly select a value-specific row? - python

I want to be able to randomly select rows that have a certain value. For example, I have a student table in sqlite that stores different characteristics (i.e Gender). I want to randomly pick a student that is male using python. I have looked at other questions (e.g Select a random row from the table using Python) but isn't relevant to value specific rows. How would I do this?

No python specific syntax is needed: sqlite has a random() function:
select
*
from users
where gender == 'M'
order by random()
limit 1
For performance see this: https://stackoverflow.com/a/24591688/788700

Related

MySQL Python Query matching row name with column name

I'm building a software to combine some chemicals into different compounds (each compound can have 1,2,3 or 4 chemicals), but some chemicals cannot combine with some other chemicals.
I have a table in my mysql db that has the following columns:
chemical_id,chemicalName, and one column for each chemical in my list.
Each row has one of the chemicals. the value in the fields tell me if both these chemicals can go together in a compound, or not (1, or 0). So all chemicals have a row, and a column. They were created in the same order, too. Here (dummy data): https://imgur.com/a/e2Fbq1K
I have a python list of chemicals_ids, which I'm gonna combine with themselves to make compounds of 1,2,3 and 4 chems, but I need a function to determine if any two of them ain't compatible.
I was trying to mess around with INFORMATION_SCHEMA COLUMN_NAME but I'm kinda lost.
A loop around something like this would work, but the syntax won't.
list_of_chemicals = ['ChemName1','ChemName2','ChemName3'] #etc
def verify_comp(a,b): #will be passed with chem names
mycursor.execute("SELECT chemicalName FROM chemical_compatibility WHERE chemical_id = 'ChemName1' AND 'ChemName2' = 0")
#etc
I have tried to use %s placeholders but it seems only to work in certain parts of mysql query. I'm a beginner both at Python and SQL so any light will be much appreciated.
Thanks!
I followed #Akina's suggestion and made a new table containing pairs of chemicals and compatibility value for each pair.
I also learned that apart from placeholders %s, which can only be used for values on python cursor sql execute statements, you can use a py variable too by doing something like this:
mycursor.execute("SELECT * FROM "+variablename+" WHERE condition = 1")
I'm not worried about SQL Injection for this project nor do I know if what I say here is 100% correct, but maybe it can help people that are lost nevertheless.

Python 3 update sqlite column by an amount specified in a variable

Scenario: A quiz program with questions worth different amounts of points.
Sqlite database with a table Table1 with a field RunningTotal of type Int.
I'm looking to update the RunningTotal by the quantity 'updateby' passed to the function. This is a numerical value (but may be a string, so i'm converting it to integer to be sure.
tableid is used to identify which row to update.
eg (non-working code : error is that updateby is not a column name)
def UpdateRunningTotal(tableid,updateby)
updateby = int(updateby)
conn.execute("UPDATE Table1 RunningTotal=RunningTotal+updateby WHERE tableid=?", (tableid,))
I know if I put the following it works to increment the field by 1, but as a function i want more flexibility to increment by different amounts.
conn.execute("UPDATE Table1 RunningTotal=RunningTotal+1 WHERE tableid=?", (tableid,))
I'm trying to avoid doing a SELECT statement to read the current value of RunningTotal, do the math on that, and then use that result in the UPDATE statement...that seems inefficient to me (but may not be?)
conn.execute("UPDATE Table1 set RunningTotal=RunningTotal+? WHERE tableid=?", (updateby, tableid,))
use this statement ... i have checked.. its working fine its updting the previous qnty present in database by RunningTotal+updateby
hope your issue will be resolved

Select a random row from the table using Python

Below is the my table.I use MySQL for the database queries.
Structure of the table
I want to print questions randomly by taking the questions from the table. How can I do that using Python?
from random import randint
num = randint(1,5)
Then db query:
SELECT question FROM your_table WHERE ques_id = num;
Alternatively:
SELECT question FROM your_table LIMIT num-1, 1;
num would be a random number between 1 and 5, replace num in the query and it only returns 1 row. Be aware it is starting from index 0, therefore the first argument should be num-1 other than num, second argument is always 1 because you only want to get one row per query.
If all the Ids are in order, get the max one and use the random library to get a random number from 1 to the max id in database.
from random import randint
random_id = randint(1,my_max_id)
then use random_id to get the item from the database.
If you have not setup your python mysql connection, you can refer this
How do I connect to a MySQL Database in Python?.
You could do it at the database level (in MySQL) and thus you would gain an extra speed (by doing the calculations in a lower level of software).
In MySQL, you could get all the questions that you are going to show in a random way.
SELECT qus_id, question FROM your_table ORDER BY RAND();
And then, in python show them by sequentially obtaining the records previously out of order in MySQL.
for question in rows:
show_question(question)
Any "Random" operation is costly to process, so the lower the software level at which it is calculated, the more optimal your program will be.

Python, SQL: How to update multiple rows and columns in a single trip around the database?

Hello StackEx community.
I am implementing a relational database using SQLite interfaced with Python. My table consists of 5 attributes with around a million tuples.
To avoid large number of database queries, I wish to execute a single query that updates 2 attributes of multiple tuples. These updated values depend on the tuples' Primary Key value and so, are different for each tuple.
I am trying something like the following in Python 2.7:
stmt= 'UPDATE Users SET Userid (?,?), Neighbours (?,?) WHERE Username IN (?,?)'
cursor.execute(stmt, [(_id1, _Ngbr1, _name1), (_id2, _Ngbr2, _name2)])
In other words, I am trying to update the rows that have Primary Keys _name1 and _name2 by substituting the Neighbours and Userid columns with corresponding values. The execution of the two statements returns the following error:
OperationalError: near "(": syntax error
I am reluctant to use executemany() because I want to reduce the number of trips across the database.
I am struggling with this issue for a couple of hours now but couldn't figure out either the error or an alternate on the web. Please help.
Thanks in advance.
If the column that is used to look up the row to update is properly indexed, then executing multiple UPDATE statements would be likely to be more efficient than a single statement, because in the latter case the database would probably need to scan all rows.
Anyway, if you really want to do this, you can use CASE expressions (and explicitly numbered parameters, to avoid duplicates):
UPDATE Users
SET Userid = CASE Username
WHEN ?5 THEN ?1
WHEN ?6 THEN ?2
END,
Neighbours = CASE Username
WHEN ?5 THEN ?3
WHEN ?6 THEN ?4
END,
WHERE Username IN (?5, ?6);

Wildcards in column name for MySQL

I am trying to select multiple columns, but not all of the columns, from the database. All of the columns I want to select are going to start with "word".
So in pseudocode I'd like to do this:
SELECT "word%" from searchterms where onstate = 1;
More or less. I am not finding any documentation on how to do this - is it possible in MySQL? Basically, I am trying to store a list of words in a single row, with an identifier, and I want to associate all of the words with that identifier when I pull the records. All of the words are going to be joined as a string and passed to another function in an array/dictionary with their identifier.
I am trying to make as FEW database calls as possible to keep speedy code.
Ok, here's another question for you guys:
There are going to be a variable number of columns with the name "word" in them. Would it be faster to do a separate database call for each row, with a generated Python query per row, or would it be faster to simply SELECT *, and only use the columns I needed? Is it possible to say SELECT * NOT XYZ?
No, SQL doesn't provide you with any syntax to do such a select.
What you can do is ask MySQL for a list of column names first, then generate the SQL query from that information.
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'your_table'
AND column_name LIKE 'word%'
let's you select the column names. Then you can do, in Python:
"SELECT * FROM your_table WHERE " + ' '.join(['%s = 1' % name for name in columns])
Instead of using string concatenation, I would recommend using SQLAlchemy instead to do the SQL generating for you.
However, if all you are doing is limit the number of columns there is no need to do a dynamic query like this at all. The hard work for the database is selecting the rows; it makes little difference to send you 5 columns out of 10, or all 10.
In that case just use a "SELECT * FROM ..." and use Python to pick out the columns from the result set.
No, you cannot dynamically produce the list of columns to be selected. It will have to be hardcoded in your final query.
Your current query would produce a result set with one column and the value of that column would be the string "word%" in all rows that satisfy the condition.
You can generate the list of column names first by using
SHOW COLUMNS IN tblname LIKE "word%"
Then loop through the cursor and generate SQL statement uses all the columns from the query above.
"SELECT {0} FROM searchterms WHERE onstate = 1".format(', '.join(columns))
This could be helpful: MySQL wildcard in select
In conclusion it is not possible in MySQL directly.
What you could do as a dirty workaround is get all the column names from the table with an initial query (http://dev.mysql.com/doc/refman/5.0/en/show-columns.html) and then compare in python if the name matches your pattern. Afterwards you could do the MySQL select statement with the found column names like this:
SELECT word1, word2, word3 from searchterms where onstate = 1;

Categories

Resources