From 47beaf6cdd85c75c44e997b916ad218f83f69e5c Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 1 Dec 2016 17:11:17 -0800 Subject: [PATCH] Prevent inconsistency between release and release_files tables. The work in PR #1448 was meant to replicate the information of the `requires_python` of the `release` table to the `release_files` table for efficiency when generating the list of available packages for pip. While the work on #1448 seem sufficient for warehouse itself, it need to consider that legacy-pypi also access the same database, and legacy-pypi violate some constraint. In particular when using `setup.py register` followed by `twine upload`, the file upload insert files into `release_files` after inserting into `releases`. Thus the value in releases is not propagated, leading to an inconsistency and a listing in pip missing information about python-version compatibility. While I doubt there are any packages released between the merge of #1448 and a fix, this update the tables, and bind an already existing trigger to update the information during insertion in `release_files` --- ...91f0fe9c2_update_release_file_on_insert.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 warehouse/migrations/versions/99291f0fe9c2_update_release_file_on_insert.py diff --git a/warehouse/migrations/versions/99291f0fe9c2_update_release_file_on_insert.py b/warehouse/migrations/versions/99291f0fe9c2_update_release_file_on_insert.py new file mode 100644 index 000000000000..000f61dc3024 --- /dev/null +++ b/warehouse/migrations/versions/99291f0fe9c2_update_release_file_on_insert.py @@ -0,0 +1,60 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" + +The release.requires_python and release_files.requires_python can be out of +sync if a file is uploaded after the release has been created. It's +requires_python field will stay empty. + +We need to : + - Fix potentially existing mistakes + - Create a trigger that ensure consistency + +Revision ID: 99291f0fe9c2 +Revises: be4cf6b58557 +Create Date: 2016-12-02 00:58:53.109880 +""" + +from alembic import op + + +revision = '99291f0fe9c2' +down_revision = 'be4cf6b58557' + + +def upgrade(): + + op.execute( + """ UPDATE release_files + SET requires_python = releases.requires_python + FROM releases + WHERE + release_files.name=releases.name + AND release_files.version=releases.version; + """ + ) + + # Establish a trigger such that on INSERT on release_files. + # The requires_python value is no supposed to be set directly here + # and UPDATES of the `releases` table already propagate. + # Also triggering on UPDATE might create a recursion. + op.execute( + """ CREATE TRIGGER release_files_requires_python + AFTER INSERT ON release_files + FOR EACH ROW + EXECUTE PROCEDURE update_release_files_requires_python(); + """) + + +def downgrade(): + op.execute("DROP TRIGGER release_files_requires_python ON release_files")