pallets-eco / flask-debugtoolbar

A toolbar overlay for debugging Flask applications
https://flask-debugtoolbar.readthedocs.io
BSD 3-Clause "New" or "Revised" License
953 stars 146 forks source link

Python 3.3 "startswith" TypeError #64

Closed aoghina closed 10 years ago

aoghina commented 10 years ago

Hi, I'm trying to enable the Toolbar for a Flask app running on Python 3.3, and I get this:

File "[...]/python3.3/site-packages/flask_debugtoolbar/templates/base.html", line 50, in {{ panel.content()|safe }} File "[...]/python3.3/site-packages/flask_debugtoolbar/panels/sqlalchemy.py", line 98, in content 'signed_query': dump_query(query.statement, query.parameters), File "[...]/python3.3/site-packages/flask_debugtoolbar/panels/sqlalchemy.py", line 25, in dump_query if not params or not statement.lower().strip().startswith('select'): TypeError: startswith first arg must be bytes or a tuple of bytes, not str

Hoping to see a fix soon!

mgood commented 10 years ago

I wasn't able to reproduce this in my test app using SQLite. Can you provide some more details on your app & environment, including the versions of Flask-SQLAlchemy and SQLAlchemy you're using and the database driver used. It might also help to narrow it down to a small test app that exhibits the problem, such as if it happens to occur only with custom SQL queries instead of SQLAlchemy ORM queries.

aoghina commented 10 years ago

Sorry for the late reply, I'm using MySQL 5.5.34 and Python 3.3.1 on Ubuntu 13.04, here are some details:

Flask==0.10.1 Flask-DebugToolbar==0.9.0 Flask-SQLAlchemy==1.0 SQLAlchemy==0.8.2 Werkzeug==0.9.4 cymysql==0.6.7

The error happens even on the simplest (SQLAlchemy ORM) of queries. I added an "print(statement)" as first line in dump_query ("../panels/sqlalchemy.py", line 25), right before the "startswith" error is triggered. This is what I got, for a single get-by-id SQLAlchemy ORM query view:

b'SELECT resource.id AS resource_id, resource.type AS resource_type, resource.name AS resource_name \nFROM resource \nWHERE resource.id = %s'

The "statement" seems to be a "bytes literal" at this point in execution: "Bytes literals are always prefixed with 'b' or 'B'; they produce an instance of the bytes type instead of the str type", and apparently startswith cannot check if a "byte literal" starts with a str, hence the error. Some type cast probably would fix the issue, but I'm not sure where is the right place to do the cast.

mgood commented 10 years ago

Please try this fix. It should handle SQL queries passed as bytes values.

aoghina commented 10 years ago

Works great, many thanks!