How to Capture just the value from a PostgreSQL Query - python

I am trying to capture the only the record from a PostgreSQL statement. The select statements outputs one row with column named as updated_at and the value is a timestamp- '2008-01-01 00:50:01'. I want to just capture/collect that value so when I call that variable, it just outputs '2008-01-01 00:50:01'.
Here is my code:
def get_etl_record():
pg_hook = PostgresHook(postgre_conn_id="post", schema='schema1')
connection = pg_hook.get_conn()
cursor = connection.cursor()
cursor2 = connection.cursor()
latest_update_query = "select max(updated_at) from my_table group by updated_at"
cursor.execute(latest_update_query)
#results= cursor.fetchall()
columns = [col[0] for col in cursor.description]
rows = [dict(zip(columns, row[0])) for row in cursor.fetchall()]
print(rows)
However this code doesnt give me an output.
Any ideas or suggestions?

There is no way to do what you want, but 3 ways to do very similar:
1.
cursor = connection.cursor()
cursor.execute(sql)
result = cursor.fetchone()
max_updated_at = result[0]
2.
dict_cur = connection.cursor(cursor_factory=psycopg2.extras.DictCursor)
dict_cur.execute('select max(updated_at) as max_updated_at ...')
result = dict_cur.fetchone()
max_updated_at = result['max_updated_at']
3.
nt_cur = connection.cursor(cursor_factory=psycopg2.extras.NamedTupleCursor)
nt_cur.execute('select max(updated_at) as max_updated_at ...')
result = nt_cur.fetchone()
max_updated_at = result.max_updated_at

Related

Python SQLITE not updating values

I want to update a row. So I issued the command -
conn = sqlite3.connect("W:\\webtracker\\database\\webtracker.db")
cur = conn.cursor()
cur.execute("SELECT URL FROM WebsiteDetail where screenshot_processed = false")
rows = cur.fetchall()
for row in rows:
cur.execute('''UPDATE WebsiteDetail SET screenshot_processed = true WHERE URL = ?''',(row[0],))
However, it doesnt update the value. What is the problem?
There is not error being thrown
row[0] is a string
You need to commit these changes. Your for loop should look like this:
for row in rows:
cur.execute('''UPDATE WebsiteDetail SET screenshot_processed = true WHERE URL = ?''',(row[0],))
conn.commit()

How to fetch one column data in python pymysql

How to fetch just one column as array in python with pymysql;
for example sql:
select name from users
data:
["Tom", "Ben", "Jon"]
cursor = conn.cursor() # where conn is your connection
cursor.execute('select name from users')
rows = cursor.fetchall()
result_list = [row[0] for row in rows]

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)

query from postgresql using python as dictionary

I'm using Python 2.7 and postgresql 9.1.
Trying to get dictionary from query, I've tried the code as described here:
http://wiki.postgresql.org/wiki/Using_psycopg2_with_PostgreSQL
import psycopg2
import psycopg2.extras
conn = psycopg2.connect("dbname=mydb host=localhost user=user password=password")
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute ("select * from port")
type(cur.fetchall())
It is printing the next answer:
<type 'list'>
printing the item itself, show me that it is list.
The excepted answer was dictionary.
Edit:
Trying the next:
ans = cur.fetchall()[0]
print ans
print type(ans)
returns
[288, 'T', 51, 1, 1, '192.168.39.188']
<type 'list'>
Tnx a lot Andrey Shokhin ,
full answer is:
#!/var/bin/python
import psycopg2
import psycopg2.extras
conn = psycopg2.connect("dbname=uniart4_pr host=localhost user=user password=password")
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute ("select * from port")
ans =cur.fetchall()
ans1 = []
for row in ans:
ans1.append(dict(row))
print ans1 #actually it's return
It's normal: when you call .fetchall() method returns list of tuples. But if you write
type(cur.fetchone())
it will return only one tuple with type:
<class 'psycopg2.extras.DictRow'>
After this you can use it as list or like dictionary:
cur.execute('SELECT id, msg FROM table;')
rec = cur.fetchone()
print rec[0], rec['msg']
You can also use a simple cursor iterator:
res = [json.dumps(dict(record)) for record in cursor] # it calls .fetchone() in loop
Perhaps to optimize it further we can have
#!/var/bin/python
import psycopg2
import psycopg2.extras
def get_dict_resultset(sql):
conn = psycopg2.connect("dbname=pem host=localhost user=postgres password=Drupal#1008")
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute (sql)
ans =cur.fetchall()
dict_result = []
for row in ans:
dict_result.append(dict(row))
return dict_result
sql = """select * from tablename"""
return get_dict_resultset(sql)
If you don't want to use a psycopg2.extras.DictCursor you can create a list of dictionaries for the results using cursor.description:
# connect
connection = psycopg2.connect()
cursor = connection.cursor()
# query
cursor.execute("SELECT * FROM myTable")
# transform result
columns = list(cursor.description)
result = cursor.fetchall()
# make dict
results = []
for row in result:
row_dict = {}
for i, col in enumerate(columns):
row_dict[col.name] = row[i]
results.append(row_dict)
# display
print(result)
I use the following function fairly regularly:
def select_query_dict(connection, query, data=[]):
"""
Run generic select query on db, returns a list of dictionaries
"""
logger.debug('Running query: {}'.format(query))
# Open a cursor to perform database operations
cursor = connection.cursor()
logging.debug('Db connection succesful')
# execute the query
try:
logger.info('Running query.')
if len(data):
cursor.execute(query, data)
else:
cursor.execute(query)
columns = list(cursor.description)
result = cursor.fetchall()
logging.debug('Query executed succesfully')
except (Exception, psycopg2.DatabaseError) as e:
logging.error(e)
cursor.close()
exit(1)
cursor.close()
# make dict
results = []
for row in result:
row_dict = {}
for i, col in enumerate(columns):
row_dict[col.name] = row[i]
results.append(row_dict)
return results
In addition to just return only the query results as a list of dictionaries, I would suggest returning key-value pairs (column-name:row-value). Here my suggestion:
import psycopg2
import psycopg2.extras
conn = None
try:
conn = psycopg2.connect("dbname=uniart4_pr host=localhost user=user password=password")
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cursor:
cursor.execute("SELECT * FROM table")
column_names = [desc[0] for desc in cursor.description]
res = cursor.fetchall()
cursor.close()
return map(lambda x: dict(zip(column_names, x)), res))
except (Exception, psycopg2.DatabaseError) as e:
logger.error(e)
finally:
if conn is not None:
conn.close()
There is a built in solution to get your result as a collection of dictionary:
from psycopg2.extras import RealDictCursor
cur = conn.cursor(cursor_factory=RealDictCursor)
Modified from: https://www.peterbe.com/plog/from-postgres-to-json-strings, copyright 2013 Peter Bengtsson
For me when I convert the row to dictionary failed (solutions mentioned by others)and also could not use cursor factory.
I am using PostgreSQL 9.6.10, Below code worked for me but I am not sure if its the right way to do it.
def convert_to_dict(columns, results):
"""
This method converts the resultset from postgres to dictionary
interates the data and maps the columns to the values in result set and converts to dictionary
:param columns: List - column names return when query is executed
:param results: List / Tupple - result set from when query is executed
:return: list of dictionary- mapped with table column name and to its values
"""
allResults = []
columns = [col.name for col in columns]
if type(results) is list:
for value in results:
allResults.append(dict(zip(columns, value)))
return allResults
elif type(results) is tuple:
allResults.append(dict(zip(columns, results)))
return allResults
Way to use it:
conn = psycopg2.connect("dbname=pem host=localhost user=postgres,password=Drupal#1008")
cur = conn.cursor()
cur.execute("select * from tableNAme")
resultset = cursor.fetchall()
result = convert_to_dict(cursor.description, resultset)
print(result)
resultset = cursor.fetchone()
result = convert_to_dict(cursor.description, resultset)
print(result)
Contents of './config.py'
#!/usr/bin/python
PGCONF = {
"user": "postgres",
"password": "postgres",
"host": "localhost",
"database": "database_name"
}
contents of './main.py'
#!/usr/bin/python
from config import PGCONF
import psycopg2
import psycopg2.extras
# open connection
conn = psycopg2.connect(**PGCONF)
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
# declare lambda function
fetch_all_as_dict = lambda cursor: [dict(row) for row in cursor]
# execute any query of your choice
cur.execute("""select * from table_name limit 1""")
# get all rows as list of dicts
print(fetch_all_as_dict(cur))
# close cursor and connection
cur.close()
conn.close()

Can i store a cursor.fetchone() in a variable

Hell guys just jumped in to python and i'm having a hard time figuring this out
I have 2 queries . . query1 and query2 now how can i tell
row = cursor.fetchone() that i am refering to query1 and not query2
cursor = conn.cursor()
query1 = cursor.execute("select * FROM spam")
query2 = cursor.execute("select * FROM eggs")
row = cursor.fetchone ()
thanks guys
Once you perform the second query, the results from the first are gone. (The return value of execute isn't useful.) The correct way to work with two queries simultaneously is to have two cursors:
cursor1 = conn.cursor()
cursor2 = conn.cursor()
cursor1.execute("select * FROM spam")
cursor2.execute("select * FROM eggs")
cursor1.fetchone() #first result from query 1
cursor2.fetchone() #first result from query 2
It doesn't. The return value from cursor.execute is meaningless. Per PEP 249:
.execute(operation[,parameters])
Prepare and execute a database operation (query or
command)...
[...]
Return values are not defined.
You can't do it the way you're trying to. Do something like this instead:
cursor = conn.cursor()
cursor.execute("select * FROM spam")
results1 = cursor.fetchall()
cursor.execute("select * FROM eggs")
if results1 is not None and len(results1) > 0:
print "First row from query1: ", results1[0]
row = cursor.fetchone()
if row is not None:
print "First row from query2: ", row

Categories