SQLALCHEMY "EncryptedType" sqlalchemy.exc.StatementError: (builtins.TypeError) data must be bytes-like

Viewed 332

Hi I understand the problem I need to send 'bytes' data, I have looked at similar problems here and can see two easy solutions 1/ bytes(name, 'utf-8') or 2/ name.encode('utf-8') I have tried both of these and can see that I am sending a bytes object but I get the same error warning.

models.py
from sqlalchemy_utils import EncryptedType
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy_utils.types.encrypted.encrypted_type import AesEngine
from flask_sqlalchemy import SQLAlchemy

class Clients(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    buyer = db.Column(EncryptedType(db.String(250), secret_key, AesEngine,'pkcs5'))
    name = db.Column(EncryptedType(db.String(250), secret_key, AesEngine,'pkcs5'))
    repeat_buyer = db.Column(db.Integer, default=0)
    Address_1 = db.Column(db.Integer, default=0)
    Address_2 = db.Column(db.Integer, default=0)

    def __repr__(self):
        return '{}'.format(self.name)

and the view

clients.py

@app.route('/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        csv_file = request.files['file']
        csv_file = TextIOWrapper(csv_file, encoding='utf-8')
        csv_reader = csv.reader(csv_file, delimiter=',')
        next(csv_reader)
        for row in csv_reader:
            client = Clients.query.order_by(Clients.id.desc()).filter(Clients.id==row[0]).first()
            if not client:
                client = Clients(id=row[0])
            client.buyer=row[1].encode('utf-8')
            client.name=row[1].encode('utf-8')
            client.repeat_buyer=row[9]
            client.Address_1=row[6]
            client.Address_2=row[7]
            db.session.add(client)
            db.session.commit()
            return
            """<html>
                    <body>          
                        <h1>Upload BB Paypal Payments</h1>
                        <form method=post enctype=multipart/form-data>
                        <input type=file name=file>
                        <input type=submit value=Upload>
                        </form>
                    </body>
                   </html>"""

I have a mysql database, I tried this same code with sqlite and it worked with no errors, I am using migrate to upgrade the db and when I added this new class I got an error "sqlalchemy_utils" not defined when I "flask db upgrade" so to over come this I manually added this line to the migrations version. I believe the error is the point the data is commited, sqlalchemy is not encoding the data as it is commited, but I dont understand why. on a simple one page app with sqlite it works, but on the full app with mysql it does not

this is the table:

+--------------+---------+------+-----+---------+---------------- 
| Field        | Type    | Null | Key | Default | Extra          
+--------------+---------+------+-----+---------+---------------- 
| id           | int(11) | NO   | PRI | NULL    | auto_increment 
| buyer        | blob    | YES  |     | NULL    |                
| name         | blob    | YES  |     | NULL    |                
| repeat_buyer | int(11) | YES  |     | NULL    |                
| Address_1    | int(11) | YES  |     | NULL    |                
| Address_2    | int(11) | YES  |     | NULL    |                
+--------------+---------+------+-----+---------+----------------

this is the data in the full error log

EDIT
[2021-07-24 16:05:50,036] ERROR in app: Exception on /dhqqdkxnnjfcnqnqqddj/clients/upload [POST]
File "/usr/lib/python3/dist-packages/cryptography/utils.py", line 35, in _check_byteslike, referer: https://erdm.fr/dhqqdkxnnjfcnqnqqddj/clients/upl$
memoryview(value), referer: 
TypeError: memoryview: a bytes-like object is required, not 'NoneType', referer: 
referer: 
During handling of the above exception, another exception occurred:, referer: 
Traceback (most recent call last):, 
File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 1671, in _execute_context, 
 dialect, self, conn, execution_options, *args, **kw,
File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/default.py", line 1077, in _init_compiled
for key in compiled_params, referer: 
File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/default.py", line 1077, in <dictcomp>, 
for key in compiled_params, referer: 
File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/sql/type_api.py", line 1374, in process, referer: 
return impl_processor(process_param(value, dialect)), referer:
File "/usr/local/lib/python3.7/dist-packages/sqlalchemy_utils/types/encrypted/encrypted_type.py", line 469, in process_bind_param, 

File "/usr/lib/python3/dist-packages/cryptography/utils.py", line 37, in _check_byteslike,
raise TypeError("{} must be bytes-like".format(name))
[SQL: INSERT INTO clients (id, buyer, name, repeat_buyer, `Address_1`, `Address_2`) VALUES (%(id)s, %(buyer)s, %(name)s, %(repeat_buyer)s, %(Address_1
[parameters: [{'Address_2': 1, 'buyer': b'john clease', 'name': b'The Old Parot', 'repeat_buyer': b'6', 'id': b'1', 'Address_1': 1}]], referer: 

If you need any more code please ask, but the code here is almost enough to try it out which I did and it worked but not with mysql! I got this code from sqlalchemy EncryptedType

Environment details

  • python3.7.2
  • sqlalachemy 1.3.10
  • SQLAlchemy-Utils==0.35.0
  • cryptography==3.4.7
  • mysql-connector-python==8.0.25
  • PyMySQL==0.9.3

EDIT: Following @snakecharmerb point I added the begining of the error code which show a first problem, I investigated this and found that no secret_key was being given, I found that my .env file was not being found with its secret key. a noob mistake, thanks for the help

Warm regards Paul

0 Answers
Related