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