mysqldb converts timestamp data to None - datetime

I am using MySQLdb to talk to mysql database and I am able to retrieve dynamically all the result sets.
My problem is that once I get the result set, there are a couple columns which are declared as timestamps in mysql but when it is retrieved, it turns to None.
I have two columns, both are declared timestamps but one returns correct data while other returns None. Both utime and enddate are declared timestamps but utime does not return correctly while enddate does.
['utime', 'userstr', 'vstr_client', 'enddate']
((None, '000102030ff43260gg0809000000000004', '7.7.0', '1970-01-01 12:00:00.000000'))
def parse_data_and_description(cursor, data):
res = []
cols = [d[0] for d in cursor.description]
print cols
print data
for i in data:
res.append(OrderedDict(zip(cols, i)))
return res
def call_multi_rs(sp, args):
rs_id=0;
conn = connect()
cursor = conn.cursor()
try:
conn.autocommit(True)
cursor.execute ("CALL %s%s" % (sp, args))
while True:
rs_id+=1
data = cursor.fetchone( )
listout = parse_data_and_description(cursor, data)
print listout
if cursor.nextset( )==None:
# This means no more recordsets available
break

Finally after nobody answered or tried finding more information, I went ahead and looked for more solutions and found that the MySQLdb library converts the datatypes from sql to python and there is a bug which does not convert the timestamp.
I still do not know why one of them is converted and the other is not. If somebody can figure that out, please update this.
But here is the modification that needs to be done when connecting to the mysql database.
MySQLdb can't serialize a python datetime object
try:
import MySQLdb.converters
except ImportError:
_connarg('conv')
def connect(host='abc.dev.local', user='abc', passwd='def', db='myabc', port=3306):
try:
orig_conv = MySQLdb.converters.conversions
conv_iter = iter(orig_conv)
convert = dict(zip(conv_iter, [str,] * len(orig_conv.keys())))
print "Connecting host=%s user=%s db=%s port=%d" % (host, user, db, port)
conn = MySQLdb.connect(host, user, passwd, db, port, conv=convert)
except MySQLdb.Error, e:
print "Error connecting %d: %s" % (e.args[0], e.args[1])
return conn

I stumbled upon the same problem: Retrieving data of the DATETIME(1)-type returns None.
Some research brought up MySQLdb-Bug #325. According to that bug tracker, the issue is still open (has been for over 2 years now), but the comments provide a working solution:
In times.py of the MySQLdb package, you need to insert some lines to handle microseconds like this:
def DateTime_or_None(s):
if ' ' in s:
sep = ' '
elif 'T' in s:
sep = 'T'
else:
return Date_or_None(s)
try:
d, t = s.split(sep, 1)
if '.' in t:
t, ms = t.split('.',1)
ms = ms.ljust(6, '0')
else:
ms = 0
return datetime(*[ int(x) for x in d.split('-')+t.split(':')+[ms] ])
except (SystemExit, KeyboardInterrupt):
raise
except:
return Date_or_None(s)
def TimeDelta_or_None(s):
try:
h, m, s = s.split(':')
if '.' in s:
s, ms = s.split('.')
ms = ms.ljust(6, '0')
else:
ms = 0
h, m, s, ms = int(h), int(m), int(s), int(ms)
td = timedelta(hours=abs(h), minutes=m, seconds=s,
microseconds=ms)
if h < 0:
return -td
else:
return td
except ValueError:
# unpacking or int/float conversion failed
return None
def Time_or_None(s):
try:
h, m, s = s.split(':')
if '.' in s:
s, ms = s.split('.')
ms = ms.ljust(6, '0')
else:
ms = 0
h, m, s, ms = int(h), int(m), int(s), int(ms)
return time(hour=h, minute=m, second=s, microsecond=ms)
except ValueError:
return None
What I cannot explain, though, is your original query working on one column and not on the other.. Maybe, the second does not have any microsecond-information in it?

Related

How do you access name of a ProtoField after declaration?

How can I access the name property of a ProtoField after I declare it?
For example, something along the lines of:
myproto = Proto("myproto", "My Proto")
myproto.fields.foo = ProtoField.int8("myproto.foo", "Foo", base.DEC)
print(myproto.fields.foo.name)
Where I get the output:
Foo
An alternate method that's a bit more terse:
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* myproto")
print(string.sub(fieldString, i + 2, j - (1 + string.len("myproto")))
EDIT: Or an even simpler solution that works for any protocol:
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* ")
print(string.sub(fieldString, i + 2, j - 1))
Of course the 2nd method only works as long as there are no spaces in the field name. Since that's not necessarily always going to be the case, the 1st method is more robust. Here is the 1st method wrapped up in a function that ought to be usable by any dissector:
-- The field is the field whose name you want to print.
-- The proto is the name of the relevant protocol
function printFieldName(field, protoStr)
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* " .. protoStr)
print(string.sub(fieldString, i + 2, j - (1 + string.len(protoStr)))
end
... and here it is in use:
printFieldName(myproto.fields.foo, "myproto")
printFieldName(someproto.fields.bar, "someproto")
Ok, this is janky, and certainly not the 'right' way to do it, but it seems to work.
I discovered this after looking at the output of
print(tostring(myproto.fields.foo))
This seems to spit out the value of each of the members of ProtoField, but I couldn't figure out the correct way to access them. So, instead, I decided to parse the string. This function will return 'Foo', but could be adapted to return the other fields as well.
function getname(field)
--First, convert the field into a string
--this is going to result in a long string with
--a bunch of info we dont need
local fieldString= tostring(field)
-- fieldString looks like:
-- ProtoField(188403): Foo myproto.foo base.DEC 0000000000000000 00000000 (null)
--Split the string on '.' characters
a,b=fieldString:match"([^.]*).(.*)"
--Split the first half of the previous result (a) on ':' characters
a,b=a:match"([^.]*):(.*)"
--At this point, b will equal " Foo myproto"
--and we want to strip out that abreviation "abvr" part
--Count the number of times spaces occur in the string
local spaceCount = select(2, string.gsub(b, " ", ""))
--Declare a counter
local counter = 0
--Declare the name we are going to return
local constructedName = ''
--Step though each word in (b) separated by spaces
for word in b:gmatch("%w+") do
--If we hav reached the last space, go ahead and return
if counter == spaceCount-1 then
return constructedName
end
--Add the current word to our name
constructedName = constructedName .. word .. " "
--Increment counter
counter = counter+1
end
end

compare foreign language strings in scilab

I am trying to compare the input string with the strings present in the doc. I am using strcmp for the purpose. These are non-English strings. When the input string is English language, the output is correct. But for any Kannada (non-English language) word the output is the same. I am trying to write a program to check if the word is present in the database. Please guide me in what could be the problem.
The calling function is as below:
str_kan = handles.InputBox.String;
res = strcmp('str_kan','s1.text')
if res == 1 then handles.InputBox.String = string( ' present')
abort
else
handles.InputBox.String = string( 'not present')
abort
end
The whole program is as below:
global s1
f=figure('figure_position',[400,50],'figure_size',[640,480],'auto_resize','on','background',[33],'figure_name','Graphic window number %d','dockable','off','infobar_visible','off','toolbar_visible','off','menubar_visible','off','default_axes','on','visible','off');
handles.dummy = 0;
handles.InputBox=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tunga','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.0929487,0.6568182,0.4647436,0.1795455],'Relief','default','SliderStep',[0.01,0.1],'String','Enter a Kannada Word','Style','edit','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','InputBox','Callback','')
handles.CheckDB=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.1025641,0.4636364,0.4567308,0.1204545],'Relief','default','SliderStep',[0.01,0.1],'String','Check','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','CheckDB','Callback','CheckDB_callback(handles)')
f.visible = "on";
function CheckDB_callback(handles)
str_kan = handles.InputBox.String;
res = strcmp('str_kan','s1.text')
if res == 1 then handles.InputBox.String = string( ' present')
abort
else
handles.InputBox.String = string( 'not present')
abort
end
endfunction
Here is an example showing that, in Scilab, strcmp() does support UTF-8 extended characters:
--> strcmp(["aα" "aα" "aβ"], ["aα" "aβ" "aα"])
ans =
0. -1. 1.
The problem in the original posted code is the confusion between literal values as "Hello" and variables names as Hello="my text", as already noted by PTRK.

In Lua, how to insert numbers as 32 bits to front of a binary sequence?

I'm new to Lua when I began to use OpenResty, I want to output a image and it's x,y coordinate together as one binary sequence to the clients, looks like: x_int32_bits y_int32_bits image_raw_data. At the client, I know the first 32 bits is x, the second 32 is y, and the others are image raw data. I met some questions:
How to convert number to 32 binary bits in Lua?
How to merge two 32 bits to one 64 bits sequence?
How to insert 64 bits to front of image raw data? And how to be fastest?
file:read("*a") got string type result, is the result ASCII sequence or like "000001110000001..." string?
What I'm thinking is like below, I don't know how to convert 32bits to string format same as file:read("*a") result.
#EgorSkriptunoff thank you, you opened a window for me. I wrote some new code, would you take a look, and I have another question, is the string merge method .. inefficient and expensive? Specially when one of the string is very large. Is there an alternative way to merge the bytes string?
NEW CODE UNDER #EgorSkriptunoff 's GUIDANCE
function _M.number_to_int32_bytes(num)
return ffi.string(ffi.new("int32_t[1]", num), 4)
end
local x, y = unpack(v)
local file, err = io.open(image_path, "rb")
if nil ~= file then
local image_raw_data = file:read("*a")
if nil == image_raw_data then
ngx.log(ngx.ERR, "read file error:", err)
else
-- Is the .. method inefficient and expensive? Because the image raw data maybe large,
-- so will .. copy all the data to a new string? Is there an alternative way to merge the bytes string?
output = utils.number_to_int32_bytes(x) .. utils.number_to_int32_bytes(y) .. image_raw_data
ngx.print(output)
ngx.flush(true)
end
file:close()
end
OLD CODE:
function table_merge(t1, t2)
for k,v in ipairs(t2) do
table.insert(t1, v)
end
return t1
end
function numToBits(num, bits)
-- returns a table of bits
local t={} -- will contain the bits
for b=bits,1,-1 do
rest=math.fmod(num,2)
t[b]=rest
num=(num-rest)/2
end
if num==0 then return t else return {'Not enough bits to represent this number'} end
end
-- Need to insert x,y as 32bits respectively to front of image binary sequence
function output()
local x = 1, y = 3
local file, err = io.open("/storage/images/1.png", "rb")
if nil ~= file then
local d = file:read("*a") ------- type(d) is string, why?
if nil == d then
ngx.log(ngx.ERR, "read file error:", err)
else
-- WHAT WAY I'M THINKING -----------------
-- Convert x, y to binary table, then merge them to one binary table
data = table_merge(numToBits(x, 32), numToBits(y, 32))
-- Convert data from binary table to string
data = convert_binary_table_to_string(data) -- HOW TO DO THAT? --------
-- Insert x,y data to front of image data, is data .. d ineffective?
data = data .. d
-------------------------------------------
ngx.print(data)
ngx.flush(true)
end
file:close()
end
end

GAE - When adding two floats whose sum is over 1000, the sum is changed to the thousands value

This was an administrative issue. It was claimed that it was our fault, and our code was broken, when the issue was elsewhere in different code that can update what ours imports. So, this is a non-problem.
We are adding to values together that are in a dictionary and storing them in a variable to then be added to the NDB datastore.
Essentially, we are importing a csv and parsing the data. If the sum of two of the values is greater than 1,000.00, the float is changed to the thousands value.
Examples:
1263.13 would change to 1
51367.42 would change to 51
218.12 would be unchanged (218.12)
We think it is an issue with storing the data, but we are having trouble reproducing the the issue, and have verified that with a small amount of data, there will be "false positives". IE: there not being an issue.
Reading csv from blob:
blob_reader = blobstore.BlobReader(blob_info.key())
raw_blob = blob_reader.read()
result = [row for row in csv.DictReader(StringIO.StringIO(raw_blob), delimiter=',')]
# loop through all rows in the data/csv
for v, row in enumerate(result):
if set_data_type(row, v) == False:
return False
else:
length = len(result) + 1
# check values for type
if check_values(row, v, length) == False:
return False
else:
# calculate numerical data for storage
calculate_vars(row, v)
if not error_log:
# if no errors, store the row in the datastore
store_data(row, v)
# if there are no errors, add to transaction log.
if not error_log:
added_records = len(result)
old_new = "Upload Success - " + str(added_records) + " records added."
transactions(module, 'Datastore', data[0], 'CSV Bulk Upload', old_new, old_new)
Calculating values:
def calculate_vars(row, v):
# calcuate values for storage based on
# data passed from the csv
try:
float_sum = float(row['float1']) + float(row['float2'])
except Exception, e:
catch_error(["Value calculation error in row ", v+1, " Error: ", e])
return False
else:
# global var
calculated_val = float_sum
Storing Value:
def store_data(row, v):
try:
entry = Datastore(
float_sum = calculated_val
)
except Exception, e:
catch_error(["StoreDataError in row ", v, e])
return False
else:
# add entry to datastore.
entry.put()
The Datastore column 'float_sum' is an ndb.FloatProperty()
What we're trying to figure out is: what could cause the floats to be truncated to the thousands digits and nothing else when the number is larger than 1,000. Obviously, we are aware that adding two floats together will not cause this normally, which is why we think it could be an issue with the datastore itself.

Length of nested array lua

I am having trouble figuring out how to get the length of a matrix within a matrix within a matrix (nested depth of 3). So what the code is doing in short is... looks to see if the publisher is already in the array, then it either adds a new column in the array with a new publisher and the corresponding system, or adds the new system to the existing array publisher
output[k][1] is the publisher array
output[k][2][l] is the system
where the first [] is the amount of different publishers
and the second [] is the amount of different systems within the same publisher
So how would I find out what the length of the third deep array is?
function reviewPubCount()
local output = {}
local k = 0
for i = 1, #keys do
if string.find(tostring(keys[i]), '_') then
key = Split(tostring(keys[i]), '_')
for j = 1, #reviewer_code do
if key[1] == reviewer_code[j] and key[1] ~= '' then
k = k + 1
output[k] = {}
-- output[k] = reviewer_code[j]
for l = 1, k do
if output[l][1] == reviewer_code[j] then
ltable = output[l][2]
temp = table.getn(ltable)
output[l][2][temp+1] = key[2]
else
output[k][1] = reviewer_code[j]
output[k][2][1] = key[2]
end
end
end
end
end
end
return output
end
The code has been fixed here for future reference: http://codepad.org/3di3BOD2#output
You should be able to replace table.getn(t) with #t (it's deprecated in Lua 5.1 and removed in Lua 5.2); instead of this:
ltable = output[l][2]
temp = table.getn(ltable)
output[l][2][temp+1] = key[2]
try this:
output[l][2][#output[l][2]+1] = key[2]
or this:
table.insert(output[l][2], key[2])

Resources