Use _binary prefix for bytes/bytearray parameters#106
Conversation
|
It's not compatible with PyMySQL. |
8ab1e6f to
121af51
Compare
|
Ah yes, you're right! How about now? |
|
Sorry, I don't quite follow: Are you saying the |
|
First of all, So, Currently, |
121af51 to
ac63076
Compare
|
Ah ok, I hadn't realised Edit: Forgot to say I've updated the commit to include the |
|
what's the status of this PR? we encountered lots of warnings after upgrading MySQL, this cloud fix it ping @methane |
|
Sorry. I'm very busy for other projects. (like new dict impl in Python 3.6). |
|
It seems this is backwards-incompatible or buggy. It broke some tests for Django on Python 3. edit: I found this is caused by Django's redundant handling of the issue: django/django#7324. |
|
I have created issue #123 to track the regression. |
|
Apart from the regression tracked in #123, this commit is suddenly breaking all client apps who were adding the |
It can't possible. bindata = b'xyzzy'
cursor.execute("SELECT %s", (b'_binary' + bindata)) # => SELECT "_binaryxyzzy" |
Perfect compatibility is not possible, I think. I want to consult with developer of SQLAlchemy (@zzzeek) and Django ORM (who?) |
|
I'm thinking about revert this and release 1.3.9 soon. |
|
This would be much appreciated (from Django's point of view). |
|
Sorry - I originally suggested this change so am responsible for it not working properly - many apologies! I personally think that clients should not themselves add the |
|
Vilnis, that would only fix one part of the regression. In Django, we are currently adding the |
I don't have right answer about this. |
Could new versions of Django not require a minimum mysqlclient version to address this? Anyway, I do understand that of course it should be backwards compatible. Please do feel free to revert. (At the time of me suggesting the change I was trying to make PyMySQL and mysqlclient be more compatible with each other, that's all. (I assume Django doesn't have PyMySQL as a library option?) |
|
If you set now a property like |
We could do that for new versions, but all older projects will break if they set |
|
Ah yes, I see now - that all makes sense. I'll shut up and let @methane handle this since I'm just a minor contributor. .. if everyone likes the new property approach (with default being old behaviour), as suggested by @claudep, I'm happy to turn it into a review-able pull request. (It might be nice if users from #81 and #106 could at least choose to continue to use the new behaviour, in line with PyMySQL) |
|
I'm not sure just by looking at this PR because I don't know the internal flow of these symbols, on the outside we only refer to dbapi.Binary() when we are passing in a binary value to a binary data type. Someone would have to run SQLA's test suite against this version to know for sure, i may or may not have time to do that today. |
While I don't like options, I agree that adding But for now, to fix backward incompatibility quickly, I just revert prefix and released 1.3.9. |
|
Thank you for resolving it quickly. |
|
@vtermanis It'd be great to re-open this with the right fix. I think mysqlclient should do it automatically, but I get the backwards-compatibility concerns, so makes sense to have a def bytes_encoder(b, dummy=None):
return b'_binary' + string_literal(b)
def str_encoder(s, dummy=None):
return string_literal(str(s).encode('utf8'))
@sqlalchemy.event.listens_for(Pool, 'connect')
def set_encoders(dbapi_conn, conn_record):
dbapi_conn.encoders[bytes] = bytes_encoder
dbapi_conn.encoders[bytearray] = bytes_encoder
dbapi_conn.encoders[str] = str_encoder |
|
I'm happy to make another attempt with config option, unless someone devs/maintainers of this project would prefer me not to. @methane: Should I:
|
- Based on PyMySQL#106 but now disabled by default - Can be enabled via 'binary_prefix' connection parameter - Added unit tests to verify behaviour fix falsely prefixing strings with _binary type identifier (PyMySQL#123)
- Based on PyMySQL#106 but now disabled by default - Can be enabled via 'binary_prefix' connection parameter - Added unit tests to verify behaviour
- Based on #106 but now disabled by default - Can be enabled via 'binary_prefix' connection parameter - Added unit tests to verify behaviour
PyMySQL already does this via
escape_bytes()converters.py. For compatibility maybe this is a good idea? (I think this would behave the same as with PyMySQL in that nothing it only affects bytes~~/bytearray~~ + Python 3 and bytearray for both versions.)I think it's not possible to add to
Connection.encoders(via constructor) because e.g.self.encoders[bytes]is overridden after theconvargument is parsed.