Posts: 6 Threads: 1 Joined: Oct 2024 Oct-01-2024, 04:01 PM (This post was last modified: Oct-02-2024, 09:48 AM by Larz60+.) Good day everyone. I have inherited a Python 2.7 script that pulls records from a mysql database and creates png files to export my product's images. The line that worked for years is "fh.write(str.decode('base64'))" and the table "images" has a column named "imageFull" with a Collation of 'utf8_general_ci' Last month the vendor updated the software and the table structure has changed. The column "imageFull" now has a Collation of 'utf8mb4_unicode_ci' and the write command fails. I tried updating to Python 3.13(64-bit) I can't change the column structure as it is not my application. I can't say why they are storing images in this way. The vendor has no responsibility to helping with this export script. So the question is "Do I need to use a decode other than 'base64'? Does it matter if i'm on python 2.7 or 3.13? Is there an alternate command to use for the write string? " Here is a larger chunk of the code incase it helps. try: #Convert image string to its png form print("Converting full size image...") str = row[1]#full size image fh = open(finalImageName, "wb") fh.write(str.decode('base64')) fh.close() totalSuccessLarge+=1 except: print("This large image failed...skipping and continuing process...") totalFailLarge+=1 time.sleep(5) pass try: print("Converting thumbnail size image...") str = row[2]#thumb image fh = open(finalImageName2, "wb") fh.write(str.decode('base64')) fh.close() totalSuccessThumb+=1 except: print("This thumbnail image failed...skipping and continuing process...") totalFailThumb+=1 time.sleep(5) pass Larz60+ write Oct-02-2024, 09:48 AM:Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button. BBcode Tags have been added for you. Please use BBCode tags on future posts. Posts: 6 Threads: 1 Joined: Oct 2024 Good morning. The output of the script is as follows. Part number for this image = zzz test part 1 Combined part num with .png = zzz test part 1.png Final image name 2 (where small images are saved) = C:\Python27\thumbs\zzz test part 1.png Converting full size image... 1 2 This large image failed...skipping and continuing process... Converting thumbnail size image... This thumbnail image failed...skipping and continuing process... Moving large images into their folder... PROCESS COMPLETE! Large Image Success total = 0 Large Image Failed Total = 1 Thumb Image Success total = 0 Thumb Image Failed Total = 1 Posts: 7,398 Threads: 123 Joined: Sep 2016 Try use base64 module instead of str.decode('base64'). This should work for Python 3.13. import base64 # Convert image string to bytes in base64, then decode str_data = row[1] # full-size image image_data = base64.b64decode(str_data) with open(finalImageName, "wb") as fh: fh.write(image_data) Thumbnail conversion: str_data_thumb = row[2] # thumbnail image thumb_image_data = base64.b64decode(str_data_thumb) with open(finalImageName2, "wb") as fh: fh.write(thumb_image_data) You might need to encode it back to bytes before decoding from base64. For example: str_data = row[1].encode('utf-8') # Ensure string is encoded as bytes image_data = base64.b64decode(str_data)And try not to use str as variable name,Python use this name. Posts: 6 Threads: 1 Joined: Oct 2024 Hi. Thank you for the suggestions. I beleve I implemented your changes. Unfortunately I still get the same error. try: #Convert image string to its png form print("Converting full size image...") str_data = row[1].encode('utf-8') # Ensure string is encoded as bytes image_data = base64.b64decode(str_data) #FB 19.7 was utf8_general_ci while FB 24.3 is utf8mb4_unicode_ci with open(finalImageName, "wb") as fh: fh.write(image_data) fh.close() totalSuccessLarge+=1 except: Posts: 7,398 Threads: 123 Joined: Sep 2016 I don't do consulting time,i can try to help you here on forum. Try this code. import base64 import time import mysql.connector from mysql.connector import errorcode import shutil import os import glob source_dir = "C:/python27" dst = 'C:/python27/largeSize' totalSuccessLarge = 0 totalFailLarge = 0 totalSuccessThumb = 0 totalFailThumb = 0 print("WELCOME TO SUPER MEGA AWESOME IMAGE CONVERTER!") # Load config variables configVariables = [] filepath = 'imgConvert-Config.txt' with open(filepath, 'r') as f: configVariables = f.readlines() print("Loading config file...") pw = os.environ.get('DB_PASSWORD') if not pw: raise ValueError("Database password not found in environment variables.") database = configVariables[0].strip() user = configVariables[1].strip() host = configVariables[2].strip() pathFull = configVariables[3].strip() pathSmall = configVariables[4].strip() print("Connecting to DB...") try: cnx = mysql.connector.connect(user=user, password=pw, host=host, port=3306, database=database) cursor = cnx.cursor() print("Executing queries...") sql_select_Query = "SELECT * FROM image" cursor.execute(sql_select_Query) records = cursor.fetchall() print("Total number of rows in image is - ", cursor.rowcount) for row in records: # Extract data img_id, full_size_image, thumbnail_image, record_id = row print(f"Id = {img_id}") print(f"Full Size image = {full_size_image}") print(f"Thumbnail image = {thumbnail_image}") print(f"recordID = {record_id}\n") # Get part number sql_select_Query3 = "SELECT num FROM part WHERE id = %s" cursor.execute(sql_select_Query3, (record_id,)) partNum = cursor.fetchone()[0] print(f"Part number for this image = {partNum}") # Prepare file paths finalImageName = os.path.join(dst, f"{partNum}.png") finalImageName2 = os.path.join(pathSmall, f"{partNum}.png") # Ensure directories exist os.makedirs(dst, exist_ok=True) os.makedirs(pathSmall, exist_ok=True) # Convert full-size image try: print("Converting full size image...") image_data = base64.b64decode(full_size_image) with open(finalImageName, "wb") as fh: fh.write(image_data) totalSuccessLarge += 1 except Exception as e: print(f"This large image failed... {e}") totalFailLarge += 1 continue # Convert thumbnail image try: print("Converting thumbnail size image...") thumb_image_data = base64.b64decode(thumbnail_image) with open(finalImageName2, "wb") as fh: fh.write(thumb_image_data) totalSuccessThumb += 1 except Exception as e: print(f"This thumbnail image failed... {e}") totalFailThumb += 1 continue except mysql.connector.Error as err: if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: print("Something is wrong with your username or password") elif err.errno == errorcode.ER_BAD_DB_ERROR: print("Database does not exist") else: print(err) finally: if 'cursor' in locals(): cursor.close() if 'cnx' in locals(): cnx.close() print("PROCESS COMPLETE!") print(f"Large Image Success total = {totalSuccessLarge}") print(f"Large Image Failed Total = {totalFailLarge}") print(f"Thumb Image Success total = {totalSuccessThumb}") print(f"Thumb Image Failed Total = {totalFailThumb}") Posts: 6 Threads: 1 Joined: Oct 2024 Hi. Thank you for helping. Your way of doing this is very interesting. Running this code I receive an error. Executing queries... Total number of rows in image is - 28345 Traceback (most recent call last): File "C:\Python27\imageconverter-forum.py", line 46, in <module> img_id, full_size_image, thumbnail_image, record_id = row ValueError: too many values to unpack (expected 4) Posts: 6 Threads: 1 Joined: Oct 2024 Hi again. I have some progress. If I remove the "= row" from the line "img_id, full_size_image, thumbnail_image, record_id = row" I get past this error. Then at the top under the includes I add: img_id = 0 full_size_image = "" thumbnail_image = "" record_id = 0 I get past the next error of "full_size_image" is not defined. But then I hit the next landmine of: Traceback (most recent call last): File "C:\Python27\imageconverter-forum.py", line 60, in <module> partNum = cursor.fetchone()[0] TypeError: 'NoneType' object is not subscriptable Posts: 7,398 Threads: 123 Joined: Sep 2016 Oct-02-2024, 07:56 PM (This post was last modified: Oct-02-2024, 07:57 PM by snippsat.) Try before accessing the result, check if cursor.fetchone() returned a result: cursor.execute(sql_select_Query3, (record_id,)) part_num_row = cursor.fetchone() if part_num_row: partNum = part_num_row[0] print(f"Part number for this image = {partNum}") else: print(f"No part number found for record ID {record_id}") totalFailLarge += 1 totalFailThumb += 1 continue # Skip to the next iteration Posts: 6 Threads: 1 Joined: Oct 2024 Hello. I added that change and get hundreds of lines that say: No part number found for record ID = 0 Id = 0 Full size image = thumbnail = recordID = 0 Posts: 7,398 Threads: 123 Joined: Sep 2016 Oct-03-2024, 01:30 PM (This post was last modified: Oct-03-2024, 01:30 PM by snippsat.) Your image table may has entries where recordID is 0. Since there is no part with id = 0, the query to get the partNum fails. The full_size_image and thumbnail_image fields are empty (''), which means there's no image data to process. Try this. import base64 import mysql.connector from mysql.connector import errorcode import os source_dir = "C:/python27" dst = 'C:/python27/largeSize' totalSuccessLarge = 0 totalFailLarge = 0 totalSuccessThumb = 0 totalFailThumb = 0 print("WELCOME TO SUPER MEGA AWESOME IMAGE CONVERTER!") # Load config variables configVariables = [] filepath = 'imgConvert-Config.txt' with open(filepath, 'r') as f: configVariables = f.readlines() print("Loading config file...") pw = "xxxx9999" database = configVariables[0].strip() user = configVariables[1].strip() host = configVariables[2].strip() pathFull = configVariables[3].strip() pathSmall = configVariables[4].strip() print("Connecting to DB...") try: cnx = mysql.connector.connect(user=user, password=pw, host=host, port=3306, database=database) cursor = cnx.cursor() print("Executing queries...") # Modified SQL query to filter out invalid entries sql_select_Query = """ SELECT id, full_size_image, thumbnail_image, record_id FROM image WHERE record_id > 0 AND full_size_image IS NOT NULL AND full_size_image != '' AND thumbnail_image IS NOT NULL AND thumbnail_image != '' """ cursor.execute(sql_select_Query) records = cursor.fetchall() print("Total number of valid rows in image is - ", cursor.rowcount) for row in records: img_id, full_size_image, thumbnail_image, record_id = row print(f"Id = {img_id}") print(f"Full Size image = {full_size_image}") print(f"Thumbnail image = {thumbnail_image}") print(f"recordID = {record_id}\n") # Query for part number sql_select_Query3 = "SELECT num FROM part WHERE id = %s" cursor.execute(sql_select_Query3, (record_id,)) part_num_row = cursor.fetchone() if part_num_row: partNum = part_num_row[0] print(f"Part number for this image = {partNum}") else: print(f"No part number found for record ID = {record_id}") totalFailLarge += 1 totalFailThumb += 1 continue # Skip to the next image # Prepare file paths finalImageName = os.path.join(dst, f"{partNum}.png") finalImageName2 = os.path.join(pathSmall, f"{partNum}.png") # Ensure directories exist os.makedirs(dst, exist_ok=True) os.makedirs(pathSmall, exist_ok=True) # Convert full-size image try: print("Converting full size image...") image_data = base64.b64decode(full_size_image) with open(finalImageName, "wb") as fh: fh.write(image_data) totalSuccessLarge += 1 except Exception as e: print(f"This large image failed... {e}") totalFailLarge += 1 continue # Convert thumbnail image try: print("Converting thumbnail size image...") thumb_image_data = base64.b64decode(thumbnail_image) with open(finalImageName2, "wb") as fh: fh.write(thumb_image_data) totalSuccessThumb += 1 except Exception as e: print(f"This thumbnail image failed... {e}") totalFailThumb += 1 continue except mysql.connector.Error as err: if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: print("Something is wrong with your username or password") elif err.errno == errorcode.ER_BAD_DB_ERROR: print("Database does not exist") else: print(err) finally: if 'cursor' in locals(): cursor.close() if 'cnx' in locals(): cnx.close() print("PROCESS COMPLETE!") print(f"Large Image Success total = {totalSuccessLarge}") print(f"Large Image Failed Total = {totalFailLarge}") print(f"Thumb Image Success total = {totalSuccessThumb}") print(f"Thumb Image Failed Total = {totalFailThumb}") |