show only one data in python query - python

I write to see how I can get only one data to show by a print when I make a query in python, when I do the query it should only give me a number but I cannot show or access it.
def run_query(self, query, parameters = ()):
with sqlite3.connect(self.db_name) as conn:
cursor = conn.cursor()
result = cursor.execute(query, parameters)
conn.commit()
return result
def get_horarios(self):
query = 'SELECT hora FROM horarios where horario=1'
db_rows = self.run_query(query)
print(db_rows)

To show the first row in the results of the query:
print(db_rows.fetchone())
To show all of the results of the query:
print(db_rows.fetchall())
or
for row in db_rows.fetchall():
print(row)

The query always return a list. To access the first item, you can do:
print(db_rows[0])

Related

cx_Oracle: select query following an insert produces no result

in my python code I insert a value into a table.
In the table, there is a sequence which automatically assigns an ID.
After the insert, I want to get this it back in to my python application:
import cx_Oracle, sys
with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
with conn.cursor() as cur:
cur.execute("Insert into my_table columns(data) values ('Hello')")
conn.commit()
with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
with conn.cursor() as cur:
r = cur.execute("select id from my_table where data = 'Hello'")
print(r)
if r is None:
print("Cannot retrieve ID")
sys.exit()
Unfortunately, the result set r is always "None" even though the value has been inserted properly (checked via sqldeveloper).
What am I doing wrong?
I even open a new connection to be sure to grab the value...
After calling execute() for a SELECT statement you need to call fetchone(), fetchmany() or fetchall() as shown in the cx_Oracle documentation SQL Queries.
Or you can use an iterator:
with connection.cursor() as cursor:
try:
sql = """select systimestamp from dual"""
for r in cursor.execute(sql):
print(r)
sql = """select 123 from dual"""
(c_id,) = cursor.execute(sql).fetchone()
print(c_id)
except oracledb.Error as e:
error, = e.args
print(sql)
print('*'.rjust(error.offset+1, ' '))
print(error.message)
However to get an automatically generated ID returned without the overhead of an additional SELECT, you can change the INSERT statement to use a RETURNING INTO clause. There is an example in the cx_Oracle documentation DML RETURNING Bind Variables that shows an UPDATE. You can use similar syntax with INSERT.
With the table:
CREATE TABLE mytable
(myid NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
mydata VARCHAR2(20));
You can insert and get the generated key like:
myidvar = cursor.var(int)
sql = "INSERT INTO mytable (mydata) VALUES ('abc') RETURNING myid INTO :bv"
cursor.execute(sql, bv=myidvar)
i, = myidvar.getvalue()
print(i)
If you just want a unique identifier you get the ROWID of an inserted row without needing a bind variable. Simple access cursor.lastrowid after executing an INSERT.

Pyodbc executemany only returns last element inserted

Using the following function:
import pyodbc
def execute_side_effect_stmt(sql_stmt: str, params: list):
with get_connection() as conn:
cursor = conn.cursor()
cursor.executemany(sql_stmt, params)
columns = [column[0] for column in cursor.description]
results = cursor.fetchall()
response = []
for row in results:
response.append(dict(zip(columns, row)))
conn.commit()
if not response:
return ''
return response
With the following arguments:
sql = """INSERT INTO dbo.events
(sha, duration)
OUTPUT Inserted.id, Inserted.sha
VALUES (?, ?)"""
params = [('123',1),('456', 2), ('789', 3)]
result = execute_side_effect_stmt(sql, params)
Result only returns the id and sha of the last entry in params. Everything is inserted correctly into the database. Any insights on why only the last insert gives an output would be very welcome.
The reason is that cursor.executemany() executes the SQL statement for each element in params.
As shown in the docs, unless you set cursor.fast_executemany = True, the INSERT statement will be called len(params) times.
With cursor.fast_executemany = True, the result will be a single insert as described here
As described:
Here, all the parameters are sent to the database server in one bundle (along with the SQL statement), and the database executes the SQL against all the parameters as one database transaction. Hence, this form of executemany() should be much faster than the default executemany(). However, there are limitations to it, see fast_executemany for more details.
Your code could be modified to:
import pyodbc
def execute_side_effect_stmt(sql_stmt: str, params: list):
with get_connection() as conn:
cursor = conn.cursor()
cursor.fast_executemany = True
cursor.executemany(sql_stmt, params)
columns = [column[0] for column in cursor.description]
results = cursor.fetchall()
response = []
for row in results:
response.append(dict(zip(columns, row)))
conn.commit()
if not response:
return ''
return response

how to mock python postgres database

I try to mock my db but when I test it the result is None.
try:
con = psycopg2.connect(
host="yhvh",
database="python_db",
user="postgres",
password="pass",
)
except:
print("Unable to connect database")
# Open a cursor to perform database operation
cur = con.cursor()
def read(con):
"""
Read data in Database
"""
print("Read")
# execute the query
data ="SELECT id, name FROM employees"
cur.execute(
data
)
# fetchall - returns all entries
rows = cur.fetchall()
for r in rows:
print(f"id {r[0]} name {r[1]}")
this is the code for my testing
def test_read(self):
expected = [9, 'aaa']
with patch('psycopg2.connect') as mock_connect:
mock_con_cm = mock_connect.return_value
mock_con = mock_con_cm.__enter__.return_value
mock_cur = mock_con.cursor.return_value
mock_cur.fetchall.return_value = expected
result = db.read(mock_connect)
self.assertEqual(expected, result)
I get an assertionError: [9, 'aaa'] != None
How the result to have a value that would result is equal to expected ?
First you need to return the rows which contains the list of data from read function if not it will return None.
Then use assertListEqual(expected, result) to check the elements in the list.
Your final code will look like this.
def read(con):
"""
Read data in Database
"""
print("Read")
# execute the query
data ="SELECT id, name FROM employees"
cur.execute(
data
)
# fetchall - returns all entries
rows = cur.fetchall()
for r in rows:
print(f"id {r[0]} name {r[1]}")
return rows
And assertion should be,
self.assertListEqual(expected, result)

How to match values in a column?

I have a file temperature.txt with columns:
city
avghigh
avglow
coldmonth
coldavghigh
coldavglow
warmmonth
warmavghigh
warmavglow
I need to return the names of the cities which have the same average low temperature.
I also have this function:
def run_query(db, q, args=None):
conn = sqlite3.connect(db)
cur = conn.cursor()
if args is None:
cur.execute(q)
else:
cur.execute(q, args)
results = cur.fetchall()
cur.close()
conn.commit()
conn.close()
return results
all I got thus far (If it's correct is)
return run_query(noname.db, ('Select Cities, AvgLow from Table')
In SQL, this can be easily done using a self join on the table to get matching AvgLow for different cities like this:
Select
t.Cities,
t.AvgLow
from Table1 t
INNER JOIN Table1 t1 ON t.AvgLow = t1.AvgLow
and t.Cities <> t1.Cities
ORDER BY t.AvgLow;
SQLite Demo

MySQLdb Results

I want to be able to get all the information from MySQLdb using the SELECT * FROM query. I have the following code:
database = MySQLdb.connect("127.0.0.1", "root", "pswd", "Kazzah")
cursor = database.cursor()
cursor.execute("SELECT * FROM Accounts WHERE Email=%s AND Password=%s", (_Email, _Password))
database.commit()
numrows = cursor.rowcount
results = cursor.fetchall()
print numrows
for result in results:
print result
How can I make variables that hold each piece of info from result. If it result returns:
(28L, 'Name', 'Last', 'email#email.com', 'pswd', '10000')
I want to make a variable called ID and get the first part of the result which is 28L, and so forth with each other pieces of information.
Thank you!
Edit
To set the full set of data use this :
id, fname, lname, email, pswd, whatever = result
And for particular values, try indexing.

Categories