[odrs-web] Do not try to emulate UPSERT for components



commit cee1e8759b16c697e2ca0367ec0fcd566efd7a9d
Author: Richard Hughes <richard hughsie com>
Date:   Fri Jul 5 14:29:12 2019 +0100

    Do not try to emulate UPSERT for components
    
    The app_id column is not unique (as it's variable length) and so we only ever
    add duplicates. Also, fix those up.

 app_data/migrations/versions/7c3432c40267_.py | 42 +++++++++++++++++++++++++++
 app_data/odrs/views_api.py                    | 20 ++++---------
 2 files changed, 48 insertions(+), 14 deletions(-)
---
diff --git a/app_data/migrations/versions/7c3432c40267_.py b/app_data/migrations/versions/7c3432c40267_.py
new file mode 100644
index 0000000..e0d465d
--- /dev/null
+++ b/app_data/migrations/versions/7c3432c40267_.py
@@ -0,0 +1,42 @@
+"""
+
+Revision ID: 7c3432c40267
+Revises: ef03b3a98056
+Create Date: 2019-07-05 14:29:46.410656
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '7c3432c40267'
+down_revision = 'ef03b3a98056'
+
+from odrs import db
+from odrs.models import Component
+
+def upgrade():
+
+    seen = {}
+    for component in db.session.query(Component).\
+                        order_by(Component.review_cnt.asc()).all():
+        if component.app_id not in seen:
+            seen[component.app_id] = component
+            continue
+        component_old = seen[component.app_id]
+        print('duplicate', component.app_id, component.review_cnt)
+        if component.review_cnt and component_old.review_cnt:
+            component_old.review_cnt += component.review_cnt
+        elif component.review_cnt:
+            component_old.review_cnt = component.review_cnt
+        if component.fetch_cnt and component_old.fetch_cnt:
+            component_old.fetch_cnt += component.fetch_cnt
+        elif component.fetch_cnt:
+            component_old.fetch_cnt = component.fetch_cnt
+        for review in component.reviews:
+            review.component_id = component_old.component_id
+        if component.component_id_parent and not component_old.component_id_parent:
+            component_old.component_id_parent = component.component_id_parent
+        db.session.delete(component)
+    db.session.commit()
+
+def downgrade():
+    pass
diff --git a/app_data/odrs/views_api.py b/app_data/odrs/views_api.py
index dd82590..201fc68 100644
--- a/app_data/odrs/views_api.py
+++ b/app_data/odrs/views_api.py
@@ -113,22 +113,14 @@ def api_submit():
                       'already reviewed')
         return json_error('already reviewed this app')
 
-    # this is basically a clunky UPSERT that works with MySQL
-    stmt = insert(Component).values(app_id=item['app_id'])
-    if db.session.bind.dialect.name != 'sqlite': # pylint: disable=no-member
-        stmt_ondupe = stmt.on_duplicate_key_update(review_cnt=Component.review_cnt + 1)
-    else:
-        stmt_ondupe = stmt
-    try:
-        db.session.execute(stmt_ondupe) # pylint: disable=no-member
-        db.session.commit()
-    except IntegrityError as e:
-        print('ignoring: {}'.format(str(e)))
-
     # component definately exists now!
     component = db.session.query(Component).filter(Component.app_id == item['app_id']).first()
-    if not component:
-        return json_error('cannot create component for {}'.format(item['app_id']))
+    if component:
+        component.review_cnt += 1
+    else:
+        component = Component(item['app_id'])
+        db.session.add(component)
+        db.session.commit()
 
     # create new
     review = Review()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]