From a1a6c41f76fa2e3e4ab2a9da49ba80ad97f73d4e Mon Sep 17 00:00:00 2001 From: Komarov Artem Date: Tue, 22 Mar 2016 11:14:58 +0300 Subject: [PATCH 1/2] Unique key length bug-fix for SQLAlchemy + unicode When using SQLAlchemy and Unicode fields having unique length of 256 we get a unique index length of 256 * 3 = 768 bytes, and 767 are allowed! This causes an error: "sqlalchemy.exc.ProgrammingError: (mysql.connector.errors.ProgrammingError) 1071 (42000): Specified key was too long; max key length is 767 bytes" While the length of the 255 is quite enough to store uuid4 - hashes. --- flask_session/sessions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask_session/sessions.py b/flask_session/sessions.py index 62c1a96d..06faa093 100644 --- a/flask_session/sessions.py +++ b/flask_session/sessions.py @@ -475,7 +475,7 @@ class Session(self.db.Model): __tablename__ = table id = self.db.Column(self.db.Integer, primary_key=True) - session_id = self.db.Column(self.db.String(256), unique=True) + session_id = self.db.Column(self.db.String(255), unique=True) data = self.db.Column(self.db.Text) expiry = self.db.Column(self.db.DateTime) From 2688782354c1145edfcfc7654651d793a16b6c44 Mon Sep 17 00:00:00 2001 From: Komarov Artem Date: Tue, 22 Mar 2016 11:42:33 +0300 Subject: [PATCH 2/2] Error when using Python 3 + Unicode Only pickle protocol version 0 and 1 can accurately convert the data to a string, because the storage we use the "Text" type field. In Python 3 pickle.dumps function protocol version installed by default 3. Therefore calls pickle.dumps() to explicitly specify the protocol version 0. This was done. --- flask_session/sessions.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/flask_session/sessions.py b/flask_session/sessions.py index 06faa093..4680e819 100644 --- a/flask_session/sessions.py +++ b/flask_session/sessions.py @@ -160,7 +160,7 @@ def save_session(self, app, session, response): httponly = self.get_cookie_httponly(app) secure = self.get_cookie_secure(app) expires = self.get_expiration_time(app, session) - val = self.serializer.dumps(dict(session)) + val = self.serializer.dumps(dict(session), 0) self.redis.setex(name=self.key_prefix + session.sid, value=val, time=total_seconds(app.permanent_session_lifetime)) if self.use_signer: @@ -273,10 +273,7 @@ def save_session(self, app, session, response): httponly = self.get_cookie_httponly(app) secure = self.get_cookie_secure(app) expires = self.get_expiration_time(app, session) - if not PY2: - val = self.serializer.dumps(dict(session), 0) - else: - val = self.serializer.dumps(dict(session)) + val = self.serializer.dumps(dict(session), 0) self.client.set(full_session_key, val, self._get_memcache_timeout( total_seconds(app.permanent_session_lifetime))) if self.use_signer: @@ -431,7 +428,7 @@ def save_session(self, app, session, response): httponly = self.get_cookie_httponly(app) secure = self.get_cookie_secure(app) expires = self.get_expiration_time(app, session) - val = self.serializer.dumps(dict(session)) + val = self.serializer.dumps(dict(session), 0) self.store.update({'id': store_id}, {'id': store_id, 'val': val, @@ -540,7 +537,7 @@ def save_session(self, app, session, response): httponly = self.get_cookie_httponly(app) secure = self.get_cookie_secure(app) expires = self.get_expiration_time(app, session) - val = self.serializer.dumps(dict(session)) + val = self.serializer.dumps(dict(session), 0) if saved_session: saved_session.data = val saved_session.expiry = expires