I wish to retrieve a single value from this database I have created. For example, The user will select a Name from a drop down box (these names correspond to the name column in the database). The name chosen will be stored in a variable called name_value. I would like to know how to search the database for the name in name_value AND return ONLY the other text in the next column called Scientific, into another variable called new_name. I hope I explained that well?
connection = sqlite3.connect("Cw.db")
crsr = connection.cursor()
crsr.execute("""CREATE TABLE Names(
Name text,
Scientific text)""")
Inserting these values: (There is more but its unnecessary to add them all)
connection = sqlite3.connect("Cw.db")
crsr = connection.cursor()
crsr.execute("""INSERT INTO Names (Name, Scientific)
VALUES
('Human', 'Homo Sapien');""")
The SELECT statement in SQL can be used to query for rows with specific values, and to specify the columns to be returned.
In your case, the code would look something like this
stmt = """\
SELECT Scientific
FROM Names
WHERE Name = ?
LIMIT 1
"""
name = 'Human'
crsr.execute(stmt, (name,))
new_name = crsr.fetchone()[0]
A few points to note:
we use a ? in the SELECT statement as a placeholder for the value that we are querying for
we set LIMIT 1 in the SELECT statement to ensure that at most only one row is returned, since you want to assign the result to a single variable.
the value(s) passed to crsr.execute must be a tuple, even if there is only one value
the return value of crsr.fetchone is a tuple, even though we are only fetching one column.
Related
I create a table with primary key and autoincrement.
with open('RAND.xml', "rb") as f, sqlite3.connect("race.db") as connection:
c = connection.cursor()
c.execute(
"""CREATE TABLE IF NOT EXISTS race(RaceID INTEGER PRIMARY KEY AUTOINCREMENT,R_Number INT, R_KEY INT,\
R_NAME TEXT, R_AGE INT, R_DIST TEXT, R_CLASS, M_ID INT)""")
I want to then insert a tuple which of course has 1 less number than the total columns because the first is autoincrement.
sql_data = tuple(b)
c.executemany('insert into race values(?,?,?,?,?,?,?)', b)
How do I stop this error.
sqlite3.OperationalError: table race has 8 columns but 7 values were supplied
It's extremely bad practice to assume a specific ordering on the columns. Some DBA might come along and modify the table, breaking your SQL statements. Secondly, an autoincrement value will only be used if you don't specify a value for the field in your INSERT statement - if you give a value, that value will be stored in the new row.
If you amend the code to read
c.executemany('''insert into
race(R_number, R_KEY, R_NAME, R_AGE, R_DIST, R_CLASS, M_ID)
values(?,?,?,?,?,?,?)''',
sql_data)
you should find that everything works as expected.
From the SQLite documentation:
If the column-name list after table-name is omitted then the number of values inserted into each row must be the same as the number of columns in the table.
RaceID is a column in the table, so it is expected to be present when you're doing an INSERT without explicitly naming the columns. You can get the desired behavior (assign RaceID the next autoincrement value) by passing an SQLite NULL value in that column, which in Python is None:
sql_data = tuple((None,) + a for a in b)
c.executemany('insert into race values(?,?,?,?,?,?,?,?)', sql_data)
The above assumes b is a sequence of sequences of parameters for your executemany statement and attempts to prepend None to each sub-sequence. Modify as necessary for your code.
I have a query which is supposed to let me input two keys, and find rows where there are matches between those two (of which there are only one for each pair in the database).
params = (searchword1, searchword2)
c.execute("SELECT primarykey, key FROM table WHERE key=? AND ? IS NOT NULL", params)
rows = c.fetchall()
print(rows)
The print statement here gives me every case where only the first condition is true (key=?/key=searchword1).
What am I doing wrong?
Additionally - what I want to do here is simply to verify whether the data entry exists or not based on the two parameters. Is there a simpler way to do this?
You cannot bind column names to a prepared statement in SQL, which would represent a security risk. However, in your case, the expression key = ? would never match if the value being bound is NULL, so you don't even need the check ? IS NOT NULL:
params = (searchword1,)
c.execute("SELECT primarykey, key FROM table WHERE key = ?", params)
rows = c.fetchall()
print(rows)
I'm trying to insert multiple rows into a table using a for-loop in python using the following code:
ID = 0
values = ['a', 'b', 'c']
for x in values:
database.execute("INSERT INTO table (ID, value) VALUES (:ID, :value)",
ID = ID, value = x)
ID += 1
What I'd expected to happen was that this piece of code would insert three rows into my table. The only problem is that it only executes the query once. So I'd only get the row " 0, 'a' ".
There aren't any error messages popping up, it just doesn't update the table with the other two values. Weirdly enough however, I can circumvent this problem by using multiple queries, like so:
ID = 0
values = ['a', 'b', 'c']
for x in values:
database.execute("INSERT INTO table (ID) VALUES (:ID)", ID = ID)
database.execute("INSERT INTO table (value) VALUES (:value)", value = x)
ID += 1
While this updates my code, this method becomes more tedious as I add columns to my table further down the line. Does anyone know why the first snippet of code doesn't work and the second one does?
The execute method takes an array as the second parameter.
execute(sql[, parameters])
Executes an SQL statement. The SQL statement may be parameterized (i. e. placeholders instead of SQL literals). The sqlite3 module
supports two kinds of placeholders: question marks (qmark style) and
named placeholders (named style).
This should work:
database.execute("INSERT INTO table (ID, value) VALUES (:ID, :value)", [ID , x])
You might want to investigte executemany while you're in the doc.
From the same doc:
commit()
This method commits the current transaction. If you don’t call this method, anything you did since the last call to commit() is not
visible from other database connections. If you wonder why you don’t
see the data you’ve written to the database, please check you didn’t
forget to call this method.
You might want to investigte executemany while you're in the doc.
i want to find the value of 'vazn' (one column of sql table) where 'id' column is equal to f1.
the table name is "billse"
"vazn" & "id1" are the columns of this table...
"f1" is a variable
f1 is a variable as following:
f1=int(enter3.get())
enter3 is an entry.
i entered the variable in enter3 that is equal to one of the existing 'id's in the sql table('bills')
this is my code:
self.cur.execute("SELECT vazn FROM billse WHERE id1='f1'")
vaznp = self.cur.fetchall()
print(vaznp)
i get 'null' when it prints vaznp
Why?
Use a prepared statement:
self.cur.execute("SELECT vazn FROM billse WHERE id1=?", f1)
vaznp = self.cur.fetchall()
print(vaznp)
Your current query is literally being interpreted as this:
SELECT vazn FROM billse WHERE id1='f1'
In other words, you are comparing the id1 column against the string 'f1', not against the value contained in that variable. Prepared statements also free you from the worry of dealing with properly escaping strings in your queries.
I have created a script that finds the last value in the first row of my database
import sqlite3
global SerialNum
conn = sqlite3.connect("MyFirstDB.db")
conn.text_factory = str
c = conn.cursor()
SerialNum = c.execute('select Serial from BI4000 where Serial in (Select max(Serial) from BI4000)')
print SerialNum
conn.commtt()
conn.close()
the program prints the result
[('00003',)]
which is the last result in the current database, all the data that will be entered into the final database will be serial numbers and so it will be in order.
My question is can I remove all the quotations/brackets/comma as I wish to asign this value to a variable.
The program that I wish to make is a testing system that adds new entries to the database, I wish to check what the last entry is in the database so the system can continue the entries from that point.
The result of the query you execute is being represented as a Python list of Python tuples.
The tuples contained in the list represent the rows returned by your query.
Each value contained in a tuple represents the corresponding field, of that specific row, in the order you selected it (in your case you selected just one field, so each tuple has only one value).
Long story short: your_variable = SerialNum[0][0]
If you want to retrieve just one column from one row, use:
c.execute('select Serial from BI4000 where Serial in (Select max(Serial) from BI4000)')
result = c.fetchone()
if result: # first row returned?
print result[0] # first column
Your query could be simplified to:
c.execute('Select max(Serial) from BI4000')