from datetime import datetime from cStringIO import StringIO import hashlib import psycopg2 from config import * db_list = [psycopg2.connect(database=db['database'], user=db['user'], host=db['host'], password=db['password']) for db in DATABASE['list']] with_prefix = lambda name: '%s%s' % (DATABASE['prefix'], name) def get_shard_number(user_id): return int(hashlib.sha1(user_id) .hexdigest(), 16) % len(db_list) # Takes one argument: model fn_get_fields = lambda m: [e for e in m._meta.fields.keys() if e != 'id'] class Core(object): @classmethod def add(cls, db_table, *args, **kw): if not hasattr(cls, 'cache'): setattr(cls, 'cache', [[] for x in xrange(len(db_list))]) kw.update(created_at=datetime.now().strftime('%Y-%m-%d %H:%M:%S')) (cls.cache[get_shard_number(kw['user'])] .append(cls.build_record(**kw))) #TODO: Please, override this method in child class @classmethod def build_record(cls, *args, **kw): return 'must be return str' @classmethod def copy_from(cls): db_table = with_prefix(cls.__name__.lower()) for (i, data) in enumerate(cls.cache): db_list[i].copy_from(StringIO('\n'.join(data)), db_table, columns=fn_get_fields(cls)) del cls.cache class Install(Core): @classmethod def build_record(cls, user, created_at, user_level='NULL', *args, **kw): return '\t'.join([locals()[e] for e in fn_get_fields(cls)]) class Visit(Core): @classmethod def build_record(cls, user, created_at, user_level='NULL', *args, **kw): return '\t'.join([locals()[e] for e in fn_get_fields(cls)]) class Exit(Core): @classmethod def build_record(cls, delta, user, created_at, user_level='NULL', *args, **kw): return '\t'.join([locals()[e] for e in fn_get_fields(cls)]) class Payment(Core): @classmethod def build_record(cls, currency, user, created_at, user_level='NULL', *args, **kw): return '\t'.join([locals()[e] for e in fn_get_fields(cls)]) class Custom(Core): @classmethod def build_record(cls, created_at, user, name, user_level='NULL', name1='NULL', name2='NULL', name3='NULL', value=0, *args, **kw): return '\t'.join([locals()[e] for e in fn_get_fields(cls)])