diff --git a/pgcontents/pgmanager.py b/pgcontents/pgmanager.py index c4eea1f..ed27bdb 100644 --- a/pgcontents/pgmanager.py +++ b/pgcontents/pgmanager.py @@ -17,6 +17,8 @@ """ from __future__ import unicode_literals from itertools import chain + +from sqlalchemy.orm import Session from tornado import web from .api_utils import ( @@ -331,13 +333,14 @@ def save(self, model, path): if model['type'] not in ('file', 'directory', 'notebook'): self.do_400("Unhandled contents type: %s" % model['type']) try: - with self.engine.begin() as db: + session = Session(self.engine) + with session.begin(): if model['type'] == 'notebook': - validation_message = self._save_notebook(db, model, path) + validation_message = self._save_notebook(session, model, path) elif model['type'] == 'file': - validation_message = self._save_file(db, model, path) + validation_message = self._save_file(session, model, path) else: - validation_message = self._save_directory(db, path) + validation_message = self._save_directory(session, path) except (web.HTTPError, PathOutsideRoot): raise except FileTooLarge: diff --git a/pgcontents/query.py b/pgcontents/query.py index 0140d81..bc1437f 100644 --- a/pgcontents/query.py +++ b/pgcontents/query.py @@ -298,6 +298,7 @@ def _file_default_fields(): files.c.name, files.c.created_at, files.c.parent_name, + files.c.user_id, ] @@ -472,32 +473,32 @@ def save_file(db, user_id, path, content, max_size_bytes): """ check_content(content, max_size_bytes) directory, name = split_api_filepath(path) - with db.begin_nested() as savepoint: - try: + savepoint = db.begin_nested() + try: + res = db.execute( + files.insert().values( + name=name, + user_id=user_id, + parent_name=directory, + content=content, + ) + ) + except IntegrityError as error: + # The file already exists, so overwrite its content with the newer + # version. + if is_unique_violation(error): + savepoint.rollback() res = db.execute( - files.insert().values( - name=name, - user_id=user_id, - parent_name=directory, + files.update().where( + _file_where(user_id, path), + ).values( content=content, + created_at=func.now(), ) ) - except IntegrityError as error: - # The file already exists, so overwrite its content with the newer - # version. - if is_unique_violation(error): - savepoint.rollback() - res = db.execute( - files.update().where( - _file_where(user_id, path), - ).values( - content=content, - created_at=func.now(), - ) - ) - else: - # Unknown error. Reraise - raise + else: + # Unknown error. Reraise + raise return res diff --git a/pgcontents/utils/ipycompat.py b/pgcontents/utils/ipycompat.py index 7e59d90..f480629 100644 --- a/pgcontents/utils/ipycompat.py +++ b/pgcontents/utils/ipycompat.py @@ -3,7 +3,7 @@ """ import IPython -SUPPORTED_VERSIONS = {3, 4, 5} +SUPPORTED_VERSIONS = {3, 4, 5, 6, 7, 8} IPY_MAJOR = IPython.version_info[0] if IPY_MAJOR not in SUPPORTED_VERSIONS: raise ImportError("IPython version %d is not supported." % IPY_MAJOR) diff --git a/requirements.txt b/requirements.txt index d055913..6288799 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ Jinja2>=2.7.3 Mako>=1.0.0 MarkupSafe>=0.23 Pygments>=2.0.1 -SQLAlchemy>=1.0.5 +SQLAlchemy==1.4.52 alembic>=0.7.6 backports.ssl-match-hostname>=3.4.0.2 certifi>=14.05.14