@with_session
    def update_locations(self, location_func):
        counter = 0
        uses_without_location = list(_current.session.query(model.DbUserUsedExperiment).filter_by(hostname = None).limit(1024).all()) # Do it iterativelly, never process more than 1024 uses
        origins = set()
        for use in uses_without_location:
            origins.add(use.origin)

        if origins:
            cached_origins = {
                # origin: result
            }
            last_month = datetime.datetime.utcnow() - datetime.timedelta(days = 31)
            for cached_origin in  _current.session.query(model.DbLocationCache).filter(model.DbLocationCache.ip.in_(origins), model.DbLocationCache.lookup_time > last_month).all():
                cached_origins[cached_origin.ip] = {
                    'city' : cached_origin.city,
                    'hostname': cached_origin.hostname,
                    'country': cached_origin.country,
                    'most_specific_subdivision' : cached_origin.most_specific_subdivision,
                }

            for use in uses_without_location:
                if use.origin in cached_origins:
                    use.city = cached_origins[use.origin]['city']
                    use.hostname = cached_origins[use.origin]['hostname']
                    use.country = cached_origins[use.origin]['country']
                    use.most_specific_subdivision = cached_origins[use.origin]['most_specific_subdivision']
                    counter += 1
                else:
                    try:
                        result = location_func(use.origin)
                    except Exception:
                        traceback.print_exc()
                        continue
                    use.city = result['city']
                    use.hostname = result['hostname']
                    use.country = result['country']
                    use.most_specific_subdivision = result['most_specific_subdivision']
                    cached_origins[use.origin] = result
                    new_cached_result = model.DbLocationCache(ip = use.origin, lookup_time = datetime.datetime.utcnow(), hostname = result['hostname'], city = result['city'], country = result['country'], most_specific_subdivision = result['most_specific_subdivision'])
                    _current.session.add(new_cached_result)
                    counter += 1

            try:
                _current.session.commit()
            except Exception:
                traceback.print_exc()

        return counter

    # Admin default
update_locations(location_func) -> number_of_updated
dataset/ETHPy150Open weblabdeusto/weblabdeusto/server/src/weblab/core/db.py/DatabaseGateway.update_locations