From my php page I send file upload content as
$imgData = addslashes(file_get_contents($_FILES['userImage']['tmp_name'])); $imgData= base64_encode($imgData);
then send this to payload – REST API in python
$call->send('{"payload" : { "dbstr" :"' . DEF_DB . '", "tblCode" : "' . USE_INF . '", "use_cod": "'.$use_cod.'", "use_pas": "'.$use_pas.'","use_nam": "'.$use_nam.'","use_dob": "'.$use_dob.'","use_ema": "'.$use_ema.'","use_des": "'.$use_des.'","use_pfe": "'.$imgData.'"}');
then in my python code I write like this
use_pfe = item_dict['payload']['use_pfe'] imgdata1 = use_pfe.encode("utf-8") imgdata2 = base64.b64decode(imgdata1)
Now I try inserting this to my database using sql where the image column is binary(blob) type
cursUserAU.execute("insert into " + tblCode + " (use_cod, use_pass, use_nam, use_dob, use_email, use_desig, use_profile) values ('" + use_cod +"' , '"+ use_pas +"', '"+ use_nam +"', '"+ use_dob +"', '"+ use_ema +"', '"+ use_des +"', "+ imgdata2 +")")
but this end in error… Am I doing in right way ? or there any part missing ? I dont want to save this file in any directory I just want to save this directly in db. Please help me with suggestion or any resources. Thanks in advance.
More detials is as follows
I am using adsdb python driver to connect advantage database server database.
in python
connUserAU = adsdb.connect(DataSource=datasource, ServerType='3', UserID='adssys', Password='') cursUserAU = connUserAU.cursor() sql = "insert into " + tblCode + " (use_cod, use_pass, use_nam, use_dob, use_email, use_desig, use_profile) values (?, ?, ?, ?, ?, ?, ?)" cursUserAU.execute(sql, (use_cod, use_pas, use_nam, use_dob, use_ema, use_des, imgdata)) connUserAU.commit() cursUserAU.close()
above use_profile is blob column type
here are the database column types
use_cod Char( 10 ), use_pass Char( 10 ), use_nam Char( 30 ), use_dob Date, use_email Char( 50 ), use_desig Char( 30 ), use_profile Blob, user_gender Char( 1 ), use_profile2 CIChar( 50 )
Advertisement
Answer
In your PHP code, after you make the call file_get_contents($_FILES['userImage']['tmp_name'])
, the return value is a string containing the contents of your image, which is binary data. You should not be escaping this content as if these were actual characters. So this line should just be:
$imgData = file_get_contents($_FILES['userImage']['tmp_name']);
Therefore, in your Python code, use_pfe
will be the base64-encoded image. This will be a string of ASCII characters. The line …
imgdata1 = use_pfe.encode("utf-8")
… converts use_pfe
into a byte string encoded using utf-8
encoding. But, because this is Python 2 where a byte string is the same thing as a simple character string (that is, type str
as opposed to a unicode string, that is, type unicode
) and the characters being encoded are from the ASCII character set, which can be encoded in a single byte, you end up with imgdata1
being identical to use_pfe
. In effect, this statement does nothing. However, if this were Python 3, where byte strings, type bytes
, are different from character strings, which are unicode strings, type str
, this line would be incorrect: You need to leave the input as type str
for input to the next line, which is converting the base64 string back to a byte string.
Putting this together:
PHP:
$imgData = file_get_contents($_FILES['userImage']['tmp_name']); $imgData = base64_encode($imgData);
Python:
use_pfe = item_dict['payload']['use_pfe'] imgdata2 = base64.b64decode(use_pfe)
You should be doing your table insert as follows with a Prepared Statement, which not only simplifies passing the values but also avoids the possibility of SQL Injection attacks when the values are user-supplied. The place-holders for the arguments below are ?
, which I believe is correct for your database (for MySql and PostgreSQL and most other relational databases, use %s
).
# make it more readable: sql = "insert into " + tblCode + " (use_cod, use_pass, use_nam, use_dob, use_email, use_desig, use_profile) values (?, ?, ?, ?, ?, ?, ?)" cursUserAU.execute(sql, (use_cod, use_pas, use_nam, use_dob, use_ema, use_des, imgdata2))
But the above is causing:
UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xff in position 0: ordinal not in range(128)`
Now you must provide a complete description of every column in your table tblCode
including the character set being used. Also, print out for each argument being passed, type(argument)
For example:
print type(use_cod), type(use_pas), type(use_nam), ... type(imgdata2)
But to save time, let me ask the most likely cause of the problem: Are you using a BLOB type for column use_profile
?