You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.py 1.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. from django.db import connection, transaction
  2. from oscar.core.loading import import_module
  3. import_module('analytics.models', ['ProductRecord'], locals())
  4. import_module('catalogue.models', ['Product'], locals())
  5. class ScoreCalculator(object):
  6. # Map of field name to weight
  7. weights = {'num_views': 1,
  8. 'num_basket_additions': 3,
  9. 'num_purchases': 5}
  10. def __init__(self, logger):
  11. self.logger = logger
  12. self.cursor = connection.cursor()
  13. def run(self):
  14. self.calculate_scores()
  15. self.update_product_models()
  16. def calculate_scores(self):
  17. self.logger.info("Calculating product scores")
  18. # Build the "SET ..." part of the SQL statement
  19. weighted_sum = " + ".join(["%s*`%s`" % (weight, field) for field, weight in self.weights.items()])
  20. ctx = {'table': ProductRecord._meta.db_table,
  21. 'weighted_total': weighted_sum,
  22. 'total_weight': sum(self.weights.values())}
  23. sql = '''UPDATE `%(table)s`
  24. SET score = (%(weighted_total)s) / %(total_weight)s''' % ctx
  25. self.logger.debug(sql)
  26. self.cursor.execute(sql)
  27. transaction.commit_unless_managed()
  28. def update_product_models(self):
  29. self.logger.info("Updating product records")
  30. sql = '''UPDATE `%s` product, `%s` analytics
  31. SET product.score = analytics.score
  32. WHERE product.id = analytics.product_id''' % (Product._meta.db_table, ProductRecord._meta.db_table)
  33. self.cursor.execute(sql)
  34. transaction.commit_unless_managed()