Print different value that is stored in MySQL DB - python

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.

Related

pyhon: repeatedly mysql query on_message in websocket not getting latest results [duplicate]

I'm wondering why my MySQL COUNT(*) query always results in ->num_rows to be equal 1.
$result = $db->query("SELECT COUNT( * ) FROM u11_users");
print $result->num_rows; // prints 1
Whereas fetching "real data" from the database works fine.
$result = $db->query("SELECT * FROM u11_users");
print $result->num_rows; // prints the correct number of elements in the table
What could be the reason for this?
Because Count(*) returns just one line with the number of rows.
Example:
Using Count(*) the result's something like the following.
array('COUNT(*)' => 20);
echo $result['COUNT(*)']; // 20
Reference
It should return one row*. To get the count you need to:
$result = $db->query("SELECT COUNT(*) AS C FROM u11_users");
$row = $result->fetch_assoc();
print $row["C"];
* since you are using an aggregate function and not using GROUP BY
that's why COUNT exists, it always returns one row with number of selected rows
http://dev.mysql.com/doc/refman/5.1/en/counting-rows.html
Count() is an aggregate function which means it returns just one row that contains the actual answer. You'd see the same type of thing if you used a function like max(id); if the maximum value in a column was 142, then you wouldn't expect to see 142 records but rather a single record with the value 142. Likewise, if the number of rows is 400 and you ask for the count(*), you will not get 400 rows but rather a single row with the answer: 400.
So, to get the count, you'd run your first query, and just access the value in the first (and only) row.
By the way, you should go with this count(*) approach rather than querying for all the data and taking $result->num_rows; because querying for all rows will take far longer since you're pulling back a bunch of data you do not need.

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)

Pyexcel changing a cell value

So I was using openpyxl for all my Excel projects, but now I have to work with .xls files, so I was forced to change library. I've chosen pyexcel cuz it seemed to be fairly easy and well documented. So I've gone through hell with creating hundreds of variables, cuz there is no .index property, or something.
What I want to do now is to read the column in the correct file, f.e "Quantity" column, and get f.e value 12 from it, then check the same column in other file, and if it is not 12, then make it 12. Easy. But I cannot find any words about changing a single cell value in their documentation. Can you help me?
I didn't get it, wouldn't it be the most simple thing?
column_name = 'Quantity'
value_to_find = 12
sheets1 = pe.get_book(file_name='Sheet1.xls')
sheets1[0].name_columns_by_row(0)
row = sheets1[0].column[column_name].index(value_to_find)
sheets2 = pe.get_book(file_name='Sheet2.xls')
sheets2[0].name_columns_by_row(0)
if sheets2[0][row, column_name] != value_to_find:
sheets2[0][row, column_name] = value_to_find
EDIT
Strange, you can only assign values if you use cell_address indexing, must be some bug. Add this function:
def index_to_letter(n):
alphabet = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
result = []
while (n > 26):
result.insert(0, alphabet[(n % 26)])
n = n // 26
result.insert(0, alphabet[n])
return ''.join(result)
And modify the last part:
sheets2[0].name_columns_by_row(0)
col_letter = index_to_letter(sheets2[0].colnames.index(column_name))
cel_address = col_letter+str(row+1)
if sheets2[0][cel_address] != value_to_find:
sheets2[0][cel_address] = value_to_find
EDIT 2
Looks like you cannot assign only when you use the column name directly, so a around would be to find the column_name's index:
sheets2[0].name_columns_by_row(0)
col_index = sheets2[0].colnames.index(column_name)
if sheets2[0][row, col_index] != value_to_find:
sheets2[0][row, col_index] = value_to_find
Excel uses 2 sets of references to a cell. Cell name ("A1") and cell vector (Row, Column).
The PyExcel documentation tutorial states it supports both methods. caiohamamura's method tries to build the cell name - you don't need to if the cells are in the same location in each file, you can use the vector.
Once you have the cell, assigning a value to a single cell is simple - you assign the value. Example:
import pyexcel
sheet = pyexcel.get_sheet(file_name="Units.xls")
print(sheet[3,2]) # this gives me "cloud, underwater"
sheet[3,2] = "cloud, underwater, special"
sheet.save_as("Units1.xls")
Note that all I had to do was "sheet[3,2] =".
This is not explicitly stated but is hinted at in the pyexcel documentation where it states that to update a whole column you do:
sheet.column["Column 2"] = [11, 12, 13]
i.e. replace a list by assigning a new list. Same logic applies to a single cell - just assign a new value.
Bonus - the [Row, column] method gets around cell locations in columns greater than 26 (i.e. 'AA' and above).
Caveat - make sure in your comparison you are comparing like-for-like i.e. int is understood to be an int and not a str. Python should implicitly converted but in some circumstances it may not - especially if you are using python 2 and Unicode is involved.

SQLite output from query into Python script

I have this Python script:
s = stdscr.getstr(0,0, 20) #input length last number
c = db.execute("""SELECT "debit" FROM "members" WHERE "barcode" = '%s' LIMIT 1""" % (s,))
for row in c:
print row
if row == '(0,)':
#display cross
print 'Tick'
else:
#display tick
print 'Cross'
Where it is asking for a barcode input, and matching the debit field in the database.
The "print row" command returns "(0,)" but when I try to match it, I always get "Cross" as the output, which is not the intended result. Is there a semantic I'm obviously not observing?
Many thanks!
The variable row is a tuple, and '(0,)' is its string representation. Your are comparing a variable with its string representation, which cannot work.
You need to compare it to the tuple value
if row == (0,):
Simply remove the quote marks.
Alternatively, you can write
if row[0] == 0:
which will avoid the creation of a tuple just for the comparison. As noted by #CL., row will never be an empty tuple so extracting row[0] is safe.

Null values for Oracle SQL 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.

Categories

Resources