I'm running pyodbc connected to my db and when i run a simply query I get a load of results back such as
(7L, )(12L,) etc.
How do I replace the the 'L, ' with '' so I can pass the ids into another query
Thanks
Here's my code
import pyodbc
cnxn = pyodbc.connect('DSN=...;UID=...;PWD=...', ansi=True)
cursor = cnxn.cursor()
rows = cursor.execute("select id from orders")
for row in rows:
test = cursor.execute("select name from customer where order_id = %(id)s" %{'id':row})
print test
Use parameters:
...
test = cursor.execute("select name from customer where order_id = ?", row.id)
...
The L after the number indicates that the value is a long type.
Related
After a query with Python's psycopg2
SELECT
id,
array_agg(еnty_pub_uuid) AS ptr_entity_public
FROM table
GROUP BY id
I get returned an array:
{a630e0a3-c544-11ea-9b8c-b73c488956ba,c2f03d24-2402-11eb-ab91-3f8e49eb63e7}
How can I parse this to a list in python?
Is there a builtin function in psycopg2?
psycopg2 cares about type conversations between python and postgres:
import psycopg2
conn = psycopg2.connect("...")
cur = conn.cursor()
cur.execute(
"select user_id, array_agg(data_name) from user_circles where user_id = '81' group by user_id"
)
res = cur.fetchall()
print(res[0])
print(type(res[0][1]))
Out:
('81', ['f085b2e3-b943-429e-850f-4ecf358abcbc', '65546d63-be96-4711-a4c1-a09f48fbb7f0', '81d03c53-9d71-4b18-90c9-d33322b0d3c6', '00000000-0000-0000-0000-000000000000'])
<class 'list'>
you need to register the UUID type for python and postgres to infer types.
import psycopg2.extras
psycopg2.extras.register_uuid()
sql = """
SELECT
id,
array_agg(еnty_pub_uuid) AS ptr_entity_public
FROM table
GROUP BY id
"""
cursor = con.cursor()
cursor.execute(sql)
results = cursor.fetchall()
for r in results:
print(type(r[1]))
First of all I am trying to retrieve a list of all possible databases, that works fine.
In the second part it executes a query for each database in the list. And it will give me back the name and create_Date for each database where the create_Date is equal or greater than 01-01-2020.
So when I when do 'print(row)' it gives me exaclty what I want.
But how do I write the result of the query to an Excel file? I already import pandas as pd.
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};'f'Server={server};'f'Database=
{db};'f'UID={username};'f'PWD={password};')
cursor = cnxn.cursor()
cursor.execute("SELECT name FROM master.dbo.sysdatabases")
result = cursor.fetchall()
ams_sql02 = []
for row in result:
ams_sql02.append(row[0])
ams_sql02 = [databases.lower() for databases in ams_sql02]
cursor = cnxn.cursor()
for db in ams_sql02:
cursor.execute(f'SELECT name, convert(varchar(10),create_date,103) as dateCreated fROM
sys.databases where name = \'{db}\' and create_date > \'2020-01-01 10:13:03.290\'
order by create_date')
result = cursor.fetchall()
for row in result:
print(row)
Why not put SQL query to Excel without Python? Excel works with datasources like MS SQL Server quite well.
I have an issue when displaying a value in python retrieved from oracle table into CLOB field:
Oracle query:
SELECT EXTRACTVALUE(xmltype(t.xml), '/DCResponse/ResponseInfo/ApplicationId')
FROM table t
WHERE id = 2
Value displayed in Oracle Client
5701200
Python code
import cx_Oracle
conn = cx_Oracle.Connection("user/pwd#localhost:1521/orcl")
cursor = conn.cursor()
cursor.execute("""SELECT EXTRACTVALUE(xmltype(t.xml),'/DCResponse/ResponseInfo/ApplicationId') FROM table t where id = 2""")
for row in cursor:
print(row)
Python Console: Nothing is displayed!!! I want to show:5701200
Please Help.
Best Regards
Giancarlo
There are only a few issues with your code :
Replace cx_Oracle.Connection with cx_Oracle.connect
Be careful about the indentation related to the print(row)
Triple double-quotes, within the SELECT statement, are redundant,
replace them with Single double-quotes
Prefer Using print(row[0]) in order to return the desired number rather than
a tuple printed.
import cx_Oracle
conn = cx_Oracle.connect('user/pwd#localhost:1521/orcl')
cursor = conn.cursor()
query = "SELECT EXTRACTVALUE(xmltype(t.xml),'/DCResponse/ResponseInfo/ApplicationId')"
query += " FROM tab t "
query += " WHERE t.ID = 2 "
cursor.execute( query )
for row in cursor:
print(row[0])
Assigning a query to a variable not required, as stated in my case, but preferable to use in order to display the long SELECT statement decently.
If you want to iterate over result, use this one:
for row in cursor.execute("sql_query")
print(row)
or you can fetch each row like this:
cursor = conn.cursor()
cursor.execute("sql_query")
while True:
row = cursor.fetchone()
print(row)
I have the following function:
def credential_check(username, password):
conn = sqlite3.connect('pythontkinter.db')
c = conn.cursor()
idvalue = c.execute('''SELECT ID FROM userdetails WHERE username = "{0}"'''.format(username)).fetchall()
print(idvalue)
I wish to assign the value of ID in my userdetails table to the variable idvalue in the row where the inputted username = userdetails username, however when I use this fetchall() I get [('0',)] printed out rather than just 0.
How do I go about doing this?
Thanks
You can use fetchone() if you only want one value. However, the result will still be returned as a tuple, just without the list.
import sqlite3
conn = sqlite3.connect('test.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS testing(id TEXT)''')
conn.commit()
c.execute("""INSERT INTO testing (id) VALUES ('0')""")
conn.commit()
c.execute("""SELECT id FROM testing""")
data = c.fetchone()
print data
# --> (u'0',)
You can also use LIMIT if you want to restrict the number of returned values with fetchall().
More importantly, don't format your queries like that. Get used to using the ? placeholder as a habit so that you are not vulnerable to SQL injection.
idvalue = c.execute("""SELECT ID FROM userdetails WHERE username = ?""", (username,)).fetchone()
This subject can be already covered. If so, apologizes for that. I have a problem when fetching rows from database (with "for" and "while" loops) and executing the script from console.
I need to fetch a huge amount of rows from database and I'm building a script so that i can insert the user ID's and i'll get the account ID's of the clients and the statuses.
I have realized that when I run the script from Eclipse, full output is fetched from DB. When I run the script from console, there is a limit of rows. So, i'd like to know if i have a "while row is not None" loop... why my row becomes None if there are more rows in database??
Also: I need to solve this issue. No matter how. I'd prefer to not load the full list to a local file (if possible). But, if there is no other way... okay, please help!! This is my example.
#!/usr/bin/env python3
# encoding: utf-8
import configparser
import pymysql
from prettytable import PrettyTable
conn = pymysql.connect(host=host, user=user, passwd=password, db=database)
print()
userid = input('Insert User ID(s) > ') # userid is a list of 2000 users in comma-separated format
userids = userid.replace(" ", "").replace("'", "").replace(",", "','")
cur = conn.cursor()
cur.execute(""" SELECT user_ID, account_ID, status FROM Account WHERE user_ID IN ('%s'); """ % userids)
rows = cur.fetchall()
table = PrettyTable(["user_ID", "account_ID", "status"])
table.padding_width = 1
for line in rows:
user_ID = str(line[0])
account_ID = str(line[1])
status = str(line[2])
table.add_row([user_ID, account_ID, status])
print()
print(table)
conn.close()
print()
print()
exit()
Without modifying too much your code you could try using from_db_cursor() provided by the prettytable module like this:
#!/usr/bin/env python3
import pymysql
from prettytable import from_db_cursor
conn = pymysql.connect(host=host, user=user, passwd=password, db=database)
userid = input('Insert User ID(s) > ') # userid is a list of 2000 users in comma-separated format
userids = userid.replace(" ", "").replace("'", "").replace(",", "','")
cur = conn.cursor()
cur.execute(""" SELECT user_ID, account_ID, status FROM Account WHERE user_ID IN ('%s'); """ % userids)
table = from_db_cursor(cur, padding_width=1)
print(table)
conn.close()
But looking at the source code of prettytable my guess is that it won't change the situation much since it does more or less what you were doing explicitly in your code.
What would probably work better is to add rows one at a time to table instead of fetching all rows and looping through them to add them. Something like:
#!/usr/bin/env python3
import pymysql
from prettytable import PrettyTable
conn = pymysql.connect(host=host, user=user, passwd=password, db=database)
userid = input('Insert User ID(s) > ') # userid is a list of 2000 users in comma-separated format
userids = userid.replace(" ", "").replace("'", "").replace(",", "','")
cur = conn.cursor()
cur.execute(""" SELECT user_ID, account_ID, status FROM Account WHERE user_ID IN ('%s'); """ % userids)
row = cur.fetchone()
table = PrettyTable(["user_ID", "account_ID", "status"], padding_width=1)
while row is not None:
table.add_row(row)
row = cur.fetchone()
print(table)
conn.close()
You don't need to transform the row elements to string values since Prettytable does that internally.
But it is possible to take advantage of different features to simplify your code and to make it more pythonic:
#!/usr/bin/env python3
import re
import pymysql
from prettytable import PrettyTable
userid = input('Insert User ID(s) > ') # userid is a list of 2000 users in comma-separated format
userids = re.sub("[ ']", "", userid).replace(",", "','")
table = PrettyTable(["user_ID", "account_ID", "status"], padding_width=1)
with pymysql.connect(host=host, user=user, passwd=password, db=database) as cur:
cur.execute("""SELECT user_ID, account_ID, status FROM Account WHERE user_ID IN ('%s'); """ % userids)
map(table.add_row, cur)
print(table)
In this version:
I have used the re.sub() to do some of the substitutions (some may say that's a tad overkill but it could be useful to you in the future)
A Pymysql connection implements the context manager that provides you directly with a cursor.
Since a Pymysql cursor can provide an iterator we can use it with map() to go through all the rows even if we don't care for the result.