def unfollow(cls, from_user_id, to_user_id): if from_user_id == to_user_id: return 0 # Queryset 的 delete 操作返回两个值,一个是删了多少数据,一个是具体每种类型删了多少 # 为什么会出现多种类型数据的删掉?因为可能因为 foreign key 设置了 cascade 出现级联 # 删除,也就是比如 A model 的某个属性是 B model 的 foreign key,并且设置了 # on_delete = models.CASCADE,那么当 B 的某个数据被删除的时候,A 中的关联也会被删除。 # 所以 CASCADE 是很危险的,一般最好不要用,而是用 on_delete = models.SET_NULL # 取而代之,这样至少可以避免误删除操作带来的多米诺效应 if not GateKeeper.is_switch_on('switch_friendship_to_hbase'): deleted, _ = Friendship.objects.filter( from_user_id=from_user_id, to_user_id=to_user_id, ).delete() return deleted instance = cls.get_follow_instance(from_user_id, to_user_id) if instance is None: return 0 HBaseFollowing.delete(from_user_id=from_user_id, created_at=instance.created_at) HBaseFollower.delete(to_user_id=to_user_id, created_at=instance.created_at) return 1
def get_following_user_id_set(cls, from_user_id): if not GateKeeper.is_switch_on('switch_friendship_to_hbase'): friendships = Friendship.objects.filter(from_user_id=from_user_id) else: friendships = HBaseFollowing.filter(prefix=(from_user_id, )) user_id_set = set([fs.to_user_id for fs in friendships]) return user_id_set
def test_save_and_get(self): timestamp = self.ts_now following = HBaseFollowing(from_user_id=123, to_user_id=34, created_at=timestamp) following.save() instance = HBaseFollowing.get(from_user_id=123, created_at=timestamp) self.assertEqual(instance.from_user_id, 123) self.assertEqual(instance.to_user_id, 34) self.assertEqual(instance.created_at, timestamp) following.to_user_id = 456 following.save() instance = HBaseFollowing.get(from_user_id=123, created_at=timestamp) self.assertEqual(instance.to_user_id, 456) # object does not exist, return None instance = HBaseFollowing.get(from_user_id=123, created_at=self.ts_now) self.assertEqual(instance, None)
def unfollow(cls, from_user_id, to_user_id): if from_user_id == to_user_id: return 0 if not GateKeeper.is_switch_on('switch_friendship_to_hbase'): deleted, _ = Friendship.objects.filter( from_user_id=from_user_id, to_user_id=to_user_id, ).delete() return deleted instance = cls.get_follow_instance(from_user_id, to_user_id) if instance is None: return 0 HBaseFollowing.delete(from_user_id=from_user_id, created_at=instance.created_at) HBaseFollower.delete(to_user_id=to_user_id, created_at=instance.created_at) return 1
def get_following_user_id_set(cls, from_user_id): key = FOLLOWING_PATTERN.format(user_id=from_user_id) user_id_set = cache.get(key) # set exists in cache if user_id_set is not None: return user_id_set # set doesn't exist in cache, build one from the DB if GateKeeper.is_switch_on('switch_friendship_to_hbase'): friendships = HBaseFollowing.filter(prefix=(from_user_id, None)) else: friendships = Friendship.objects.filter(from_user_id=from_user_id) user_id_set = set([fs.to_user_id for fs in friendships]) cache.set(key, user_id_set) # save in cache return user_id_set
def unfollow(cls, from_user_id, to_user_id): if from_user_id == to_user_id: return 0 if not GateKeeper.is_switch_on('switch_friendship_to_hbase'): delete, _ = Friendship.objects.filter( from_user_id=from_user_id, to_user_id=to_user_id, ).delete() return delete following = cls.get_following_instance(from_user_id=from_user_id, to_user_id=to_user_id) # fs = HBaseFollowing.filter(prefix=(from_user_id, None)) # for f in fs: # print(f.from_user_id, f.created_at, '->', f.to_user_id) # print(following) if following is None: return 0 HBaseFollowing.delete(from_user_id=from_user_id, created_at=following.created_at) HBaseFollower.delete(to_user_id=to_user_id, created_at=following.created_at) return 1
def follow(cls, from_user_id, to_user_id): if from_user_id == to_user_id: return None if not GateKeeper.is_switch_on('switch_friendship_to_hbase'): return Friendship.objects.create( from_user_id=from_user_id, to_user_id=to_user_id, ) now = ts_now_as_int() HBaseFollower.create( from_user_id=from_user_id, created_at=now, to_user_id=to_user_id, ) return HBaseFollowing.create( from_user_id=from_user_id, created_at=now, to_user_id=to_user_id, )
def follow(cls, from_user_id, to_user_id): if from_user_id == to_user_id: return None if not GateKeeper.is_switch_on('switch_friendship_to_hbase'): # create data in mysql return Friendship.objects.create( from_user_id=from_user_id, to_user_id=to_user_id, ) # create data in hbase now = int(time.time() * 1000000) HBaseFollower.create( from_user_id=from_user_id, to_user_id=to_user_id, created_at=now, ) return HBaseFollowing.create( from_user_id=from_user_id, to_user_id=to_user_id, created_at=now, )
def get_following_count(cls, from_user_id): if not GateKeeper.is_switch_on('switch_friendship_to_hbase'): return Friendship.objects.filter(from_user_id=from_user_id).count() followings = HBaseFollowing.filter(prefix=(from_user_id, )) return len(followings)
def get_follow_instance(cls, from_user_id, to_user_id): followings = HBaseFollowing.filter(prefix=(from_user_id, )) for follow in followings: if follow.to_user_id == to_user_id: return follow return None
from friendships.hbase_models import HBaseFollowing table = HBaseFollowing.get_table() def print_rows(rows): for row_key, row_data in rows: print(row_key, row_data) # rows = table.scan() rows = table.scan(row_stop=b'1000000000000000:1629391756362040', limit=2, reverse=True) #rows = table.scan(row_prefix=b'1000000000000000', limit=3) print_rows(rows)
def test_filter(self): HBaseFollowing.create(from_user_id=1, to_user_id=2, created_at=self.ts_now) HBaseFollowing.create(from_user_id=1, to_user_id=3, created_at=self.ts_now) HBaseFollowing.create(from_user_id=1, to_user_id=4, created_at=self.ts_now) followings = HBaseFollowing.filter(prefix=(1, None)) self.assertEqual(3, len(followings)) self.assertEqual(followings[0].from_user_id, 1) self.assertEqual(followings[0].to_user_id, 2) self.assertEqual(followings[1].from_user_id, 1) self.assertEqual(followings[1].to_user_id, 3) self.assertEqual(followings[2].from_user_id, 1) self.assertEqual(followings[2].to_user_id, 4) # test limit results = HBaseFollowing.filter(prefix=(1, None), limit=1) self.assertEqual(len(results), 1) self.assertEqual(results[0].to_user_id, 2) results = HBaseFollowing.filter(prefix=(1, None), limit=2) self.assertEqual(len(results), 2) self.assertEqual(results[0].to_user_id, 2) self.assertEqual(results[1].to_user_id, 3) results = HBaseFollowing.filter(prefix=(1, None), limit=4) self.assertEqual(len(results), 3) self.assertEqual(results[0].to_user_id, 2) self.assertEqual(results[1].to_user_id, 3) self.assertEqual(results[2].to_user_id, 4) results = HBaseFollowing.filter(start=(1, results[1].created_at), limit=2) self.assertEqual(len(results), 2) self.assertEqual(results[0].to_user_id, 3) self.assertEqual(results[1].to_user_id, 4) # test reverse results = HBaseFollowing.filter(prefix=(1, None), limit=2, reverse=True) self.assertEqual(len(results), 2) self.assertEqual(results[0].to_user_id, 4) self.assertEqual(results[1].to_user_id, 3) results = HBaseFollowing.filter(start=(1, results[1].created_at), limit=2, reverse=True) self.assertEqual(len(results), 2) self.assertEqual(results[0].to_user_id, 3) self.assertEqual(results[1].to_user_id, 2)
def test_save_and_get(self): now = self.ts_now() following = HBaseFollowing( from_user_id=123, created_at=now, to_user_id=456, ) following.save() following = HBaseFollowing.get(from_user_id=123, created_at=now) self.assertEqual(following.from_user_id, 123) self.assertEqual(following.created_at, now) self.assertEqual(following.to_user_id, 456) following.to_user_id = 789 following.save() self.assertEqual(following.to_user_id, 789) following = HBaseFollowing.get(from_user_id=123, created_at=now) self.assertEqual(following.to_user_id, 789) # get non-exist object get none following = HBaseFollowing.get(from_user_id=123, created_at=self.ts_now()) self.assertIsNone(following) # wrong row_keys to creat try: following = HBaseFollowing(from_user_id=123, to_user_id=456) following.save() exception_raised = False except BadRowKeyException as e: exception_raised = True self.assertEqual(str(e), 'created_at not defined') self.assertEqual(exception_raised, True)
def test_filter(self): now = self.ts_now() # dummy friendships for i in range(1, 5): HBaseFollowing.create(from_user_id=i, created_at=now, to_user_id=999) for i in range(1, 4): HBaseFollowing.create(from_user_id=999, created_at=now + i, to_user_id=i) # single instance filter following = HBaseFollowing.filter(start=(1, now), stop=(1, now)) self.assertEqual(len(following), 1) self.assertEqual(following[0].from_user_id, 1) self.assertEqual(following[0].to_user_id, 999) self.assertEqual(following[0].created_at, now) # start from non-exist id following = HBaseFollowing.filter(start=(0, now)) self.assertEqual(len(following), 7) # range query followings = HBaseFollowing.filter(start=(1, now)) self.assertEqual(len(followings), 7) followings = HBaseFollowing.filter(start=(1, now), limit=2) self.assertEqual(len(followings), 2) self.assertEqual(followings[0].from_user_id, 1) self.assertEqual(followings[0].to_user_id, 999) self.assertEqual(followings[1].from_user_id, 2) self.assertEqual(followings[1].to_user_id, 999) # reverse range query followings = HBaseFollowing.filter(start=(4, now), reverse=True) self.assertEqual(len(followings), 4) followings = HBaseFollowing.filter(start=(4, now), limit=3, reverse=True) self.assertEqual(len(followings), 3) self.assertEqual(followings[-1].from_user_id, 2) self.assertEqual(followings[-1].to_user_id, 999) self.assertEqual(followings[0].from_user_id, 4) self.assertEqual(followings[0].to_user_id, 999) # part to row_keys range query followings = HBaseFollowing.filter(start=(5, None), limit=3, reverse=True) self.assertEqual(len(followings), 3) self.assertEqual(followings[-1].from_user_id, 2) self.assertEqual(followings[-1].to_user_id, 999) self.assertEqual(followings[0].from_user_id, 4) self.assertEqual(followings[0].to_user_id, 999) followings = HBaseFollowing.filter(start=(4, None), limit=3, reverse=True) self.assertEqual(len(followings), 3) # None stays behind all values, In Table: (1, 999), (2, 299), (3, 999), ((4, None)), (4, 999) self.assertEqual(followings[-1].from_user_id, 1) self.assertEqual(followings[-1].to_user_id, 999) self.assertEqual(followings[0].from_user_id, 3) self.assertEqual(followings[0].to_user_id, 999) # prefix range query followings = HBaseFollowing.filter(prefix=(999, None), limit=4, reverse=True) self.assertEqual(len(followings), 3) self.assertEqual(followings[0].from_user_id, 999) self.assertEqual(followings[0].to_user_id, 3) self.assertEqual(followings[1].from_user_id, 999) self.assertEqual(followings[1].to_user_id, 2) self.assertEqual(followings[-1].from_user_id, 999) self.assertEqual(followings[-1].to_user_id, 1) # extra redundant field followings = HBaseFollowing.filter(start=(1, now, None)) self.assertEqual(len(followings), 7)