Null values for Oracle SQL Python - python

I have a clob datapoint that I must use .read() to add it to a list, however, sometimes this column is null, so I need a check first before using the .read() property.
I've isolated the portion that is relevant. If I just print data, the null fields print as none. Is not null seems to be the wrong code, but I'm not sure what to use.
for currentrow in data:
if currentrow[8] is not null:
Product = currentrow[8].read()
else:
Product = currentrow[8]
data = tuple([currentrow[0], currentrow[1], currentrow[2], currentrow[3], currentrow[4], currentrow[5], currentrow[6], currentrow[7], Product])
print data

From the docs:
The sole value of types.NoneType. None is frequently used to represent
the absence of a value, as when default arguments are not passed to a
function.
So you may try this:
for currentrow in data:
if currentrow[8] is not None: <-- Change this from null to None
Product = currentrow[8].read()
else:
Product = currentrow[8]
data = tuple([currentrow[0], currentrow[1], currentrow[2], currentrow[3], currentrow[4], currentrow[5], currentrow[6], currentrow[7], Product])
print data

Python uses the None singleton value as a null; NULLs from the database are translated to that object:
if currentrow[8] is not None:
You could collapse that line into just two:
for currentrow in data:
product = currentrow[8] and currentrow[8].read()
data = currentrow[:8] + (product,)
as Python's and operator short-circuits and None is false in a boolean context. Unless you set a row factory, cx_Oracle cursors produce tuples for each row, which you can slice to select just the first 8 elements, then append the 9th to create a new tuple from the two.

Related

Why is the returned value is none in this Python/MySQL search

I have this little code
cquery = "SELECT * FROM `workers` WHERE `Username` = (%s)"
cvalue = (usernameR,)
flash(cquery)
flash(cvalue)
x = c1.execute(cquery, cvalue)
flash(x)
usernameR is a string variable I got it's value from a form
x supposed to be the number of rows or some value but it returns none I need it's value for one if.
I tested it with a value that is in the table in one row so thats not the case the the value is not there or something. But if it's not there in that case the x should return 0 or something.
I cant work out what's the problem after several hours.
value of cvalue:
('Csabatron99',)
Edit for solution:
I needed to add the rowcount and fetchall to the code like this:
cquery = "SELECT * FROM `workers` WHERE `Username` = (%s)"
cvalue = (usernameR,)
flash(cquery)
flash(cvalue)
c1.execute(cquery, cvalue)
c1.fetchall()
a = c1.rowcount
cursor.execute() doesn't return anything in the normal case. If you use the multi=True argument, it returns an iterator used to get results from each of the multiple queries.
To get the number of rows returned by the query, use the rowcount attribute.
c1.execute(cquery, cvalue)
flash(c1.rowcount)

Python/SQL - How the cursor functions

In my code I have a function that needs to return either a string or None depending on what is present in the database. However at the moment the result is a list with the string answer inside, or None. Is there any change that could be made that would result in just a string or None being returned, rather than having to index the list?
Here is the code:
def retrieve_player_name(username):
param = [(username)]
command = ("""
SELECT username FROM players
WHERE username = ?
""")
result = cur.execute(command, param).fetchone()
if result is not None:
return result[0]
Thanks in advance.
A database cursors fetches entire rows, not values.
Even a row with a single value inside is still a row.
If you don't want to write row[0] multiple times, create a helper function execute_and_return_a_single_value_from_query().

SqlAlchemy in_ opeator with NULL

I would like to use the in_ operator in sqlalchemy using two values, one of them being NULL (mysql NULL), I don't know how to pass it via Python?
So I have a Python cgi that contains a bunch of parameters that I format then finally store inside a dict queryValues (the key being the column name and the value being a value sent by the user stored inside a fieldStorage)
for attr,value in queryValues.items() : #queryValues is a dict of parameters
valueWithNone = value.append(None) #I want to includ NULL
and_args_of_cr = [(and_(getattr(TableCR.c,attr).in_(valueWithNone)))]
I tried None and sqlalchemy.sql.null(), also tried putting directly in_(value,None) but value has the form ['Yes'] so I don't know how to do this.
But it's not working, how can I do this please?
The line value.append(None) is an in-place modification and does not return anything, so valueWithNone will be None. This is probably what you're after:
for attr,value in queryValues.items():
queryvalues = value[:] # Create a copy of list
queryvalues.append(None)
and_args_of_cr = [(and_(getattr(TableCR.c,attr).in_(queryvalues)))]

SQLAlchemy execute() return ResultProxy as Tuple, not dict

I have the following code:
query = """
SELECT Coalesce((SELECT sp.param_value
FROM sites_params sp
WHERE sp.param_name = 'ci'
AND sp.site_id = s.id
ORDER BY sp.id DESC
LIMIT 1), -1) AS ci
FROM sites s
WHERE s.deleted = 0
AND s.id = 10
"""
site = db_session.execute(query)
# print site
# <sqlalchemy.engine.result.ResultProxy object at 0x033E63D0>
site = db_session.execute(query).fetchone()
print site # (u'375')
print list(site) # [u'375']
Why does SQLAlchemy return tuples, not dicts, for this query? I want to use the following style to access the results of the query:
print site.ci
# u'375'
This is an old question, but still relevant today. Getting SQL Alchemy to return a dictionary is very useful, especially when working with RESTful based APIs that return JSON.
Here is how I did it using the db_session in Python 3:
resultproxy = db_session.execute(query)
d, a = {}, []
for rowproxy in resultproxy:
# rowproxy.items() returns an array like [(key0, value0), (key1, value1)]
for column, value in rowproxy.items():
# build up the dictionary
d = {**d, **{column: value}}
a.append(d)
The end result is that the array a now contains your query results in dictionary format.
As for how this works in SQL Alchemy:
Thedb_session.execute(query) returns a ResultProxy object
The ResultProxy object is made up of RowProxy objects
The RowProxy object has an .items() method that returns key, value tuples of all the items in the row, which can be unpacked as key, value in a for operation.
And here a one-liner alternative:
[{column: value for column, value in rowproxy.items()} for rowproxy in resultproxy]
From the docs:
class sqlalchemy.engine.RowProxy(parent, row, processors, keymap)
Proxy values from a single cursor row.
Mostly follows “ordered dictionary” behavior, mapping result values to the string-based column name, the integer position of the result in the row, as well as Column instances which can be mapped to the original Columns that produced this result set (for results that correspond to constructed SQL expressions).
has_key(key)
Return True if this RowProxy contains the given key.
items()
Return a list of tuples, each tuple containing a key/value pair.
keys()
Return the list of keys as strings represented by this RowProxy.
Link: http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.RowProxy.items
Did you take a look at the ResultProxy docs?
It describes exactly what #Gryphius and #Syed Habib M suggest, namely to use site['ci'].
The ResultProxy does not "return a tuple" as you claim - it is (not surprisingly) a proxy that behaves (e.g. prints) like a tuple but also supports dictionary-like access:
From the docs:
Individual columns may be accessed by their integer position,
case-insensitive column name, or by schema.Column object. e.g.:
row = fetchone()
col1 = row[0] # access via integer position
col2 = row['col2'] # access via name
col3 = row[mytable.c.mycol] # access via Column object.
I've built a simple class to work like a database interface in our processes. Here it goes:
from sqlalchemy import create_engine
class DBConnection:
def __init__(self, db_instance):
self.db_engine = create_engine('your_database_uri_string')
self.db_engine.connect()
def read(self, statement):
"""Executes a read query and returns a list of dicts, whose keys are column names."""
data = self.db_engine.execute(statement).fetchall()
results = []
if len(data)==0:
return results
# results from sqlalchemy are returned as a list of tuples; this procedure converts it into a list of dicts
for row_number, row in enumerate(data):
results.append({})
for column_number, value in enumerate(row):
results[row_number][row.keys()[column_number]] = value
return results
You can easily convert each result row to a dictionary by using dict(site).
Then site['ci'] would be available if ci column is exists.
In order to have site.ci (according to https://stackoverflow.com/a/22084672/487460):
from collections import namedtuple
Site = namedtuple('Site', site.keys())
record = Site(*site)
This may help solve the OPs question. I think the problem he was having is that the row object only contained column values, but not the column names themselves, as is the case with ORM queries where the results have a dict attribute with both keys and values.
python sqlalchemy get column names dynamically?
The easiest way that I found is using list comprehension with calling dict() func on every RowProxy:
site = db_session.execute(query)
result = [dict(row) for row in site]
Based on Essential SQLAlchemy book:
A ResultProxy is a wrapper around a DBAPI cursor object, and its main
goal is to make it easier to use and manipulate the results of a
statement
Simple select example:
from sqlalchemy.sql import select
stmnt = select([cookies])
result_proxy = connection.execute(stmnt)
results = result_proxy.fetchall()
Results going to be like this:
# ID, cookie_name, quantity, amount
[
(1, u'chocolate chip', 12, Decimal('0.50')),
(2, u'dark chocolate chip', 1, Decimal('0.75')),
(3, u'peanut butter', 24, Decimal('0.25')),
(4, u'oatmeal raisin', 100, Decimal('1.00'))
]
It makes handling query results easier by allowing access using an index, name, or Column object.
Accessing cookie_name in different ways:
first_row = results[0]
first_row[1]
first_row.cookie_name
first_row[cookies.c.cookie_name]
These all result in u'chocolate chip' and they each reference the exact same data element in the first record of our results variable. This flexibility in access is only part of the power of the ResultProxy.
We can also leverage the ResultProxy as an iterable:
result_proxy = connection.execute(stmnt)
for record in result_proxy:
print(record.cookie_name)
This method uses list comprehensions, it receives a sql alchemy rowset object and returns the same items as a list of dictionaries:
class ResultHelper():
#classmethod
def resultproxy_to_list(cls, sql_alchemy_rowset):
return [{tuple[0]: tuple[1] for tuple in rowproxy.items()}
for rowproxy in sql_alchemy_rowset]
As you call db.execute(sql).fetchall(), you can easily use the following function to parse the return data to a dict:
def query_to_dict(ret):
if ret is not None:
return [{key: value for key, value in row.items()} for row in ret if row is not None]
else:
return [{}]

Print different value that is stored in MySQL DB

In MySQL table with myISAM I have a integer value ex.011. When I query in Python it prints me value 11 removing 0 before number. It should print the exact value that is stored in DB ex. 011 instead of 11. Any help ?
Your column is an int, so MySQLdb gives you an integer value back in the query result. However, I think you should be able to write a mySQLdb result set wrapper (or maybe find one someone else already wrote) that inspects the flags set on the columns of the result set and casts to a string appropriately.
Look at cursor.description and cursor.description_flags as well as PEP-249. I think (ie I have not actually tried it) something along the lines of the following should get you started:
def get_result_set_with_db_specified_formatting(cursor):
integer_field_types = (MySQLdb.constants.FIELD_TYPE.TINY,
MySQLdb.constants.FIELD_TYPE.SHORT,
MySQLdb.constants.FIELD_TYPE.LONG,
MySQLdb.constants.FIELD_TYPE.LONGLONG,
MySQLdb.constants.FIELD_TYPE.INT24)
rows = cursor.fetchall()
for row in rows:
for index, value in enumerate(row):
value = str(value)
if (cursor.description[index][1] in integer_field_types
and cursor.description_flags[index] & MySQLdb.constants.FLAG.ZEROFILL):
if len(value) < cursor.description[index][2]:
value = ('0' * (cursor.description[index][2] - len(value))) + value
row[index] = value
return rows
May be, simple zero filling is OK in this case?
>>> print str(11).zfill(3)
011
As I understood, it's additional part of number. If its length is not constant, you need to change data type in DB to VARCHAR.

Categories

Resources