Exemplo n.º 1
0
    def get_sequences(self, model, num_children, shard_range):
        output = []

        our_epoch = int(time.mktime(datetime(2012, 11, 1).timetuple()) * 1000)
        proc = """CREATE OR REPLACE FUNCTION next_sharded_id(varchar, int, OUT result bigint) AS $$
DECLARE
    sequence_name ALIAS FOR $1;
    shard_id ALIAS FOR $2;

    seq_id bigint;
    now_millis bigint;
BEGIN
    SELECT nextval(sequence_name::regclass) % 1024 INTO seq_id;

    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
    result := (now_millis - {our_epoch}) << 23;
    result := result | (shard_id << 10);
    result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;""".format(
            our_epoch=our_epoch
        )
        output.append(self.style.SQL_KEYWORD(proc))

        for i in shard_range:
            child = generate_child_partition(model, i)
            output.append(
                self.style.SQL_KEYWORD("CREATE SEQUENCE ")
                + self.style.SQL_TABLE(get_sharded_id_sequence_name(child))
                + ";"
            )

        return output
Exemplo n.º 2
0
    def db_type(self, *args, **kwargs):
        if not hasattr(self.model, '_shards'):
            raise ValueError("ShardedAutoField must be used with a PartitionModel.")

        if self.model._shards.is_master:
            return "bigint"

        return "bigint DEFAULT next_sharded_id('%s'::varchar, %d)" % (
            get_sharded_id_sequence_name(self.model),
            self.model._shards.num)
Exemplo n.º 3
0
    def create_sequence(self, created_models, **kwargs):
        # Sequence creation for production is handled by DDL scripts
        # (sqlpartition).  This is needed to create sequences for
        # test models.
        if self.model not in created_models:
            return

        db_alias = self.model._shards.cluster

        for child in self.model._shards.nodes:
            cursor = connections[db_alias].cursor()
            sid = transaction.savepoint(db_alias)
            sequence_name = get_sharded_id_sequence_name(child)
            try:
                cursor.execute("CREATE SEQUENCE %s;" % sequence_name)
            except DatabaseError:
                transaction.savepoint_rollback(sid, using=db_alias)
                # Sequence must already exist, ensure it gets reset
                cursor.execute("SELECT setval('%s', 1, false)" % (sequence_name,))
            else:
                print 'Created sequence %r on %r' % (sequence_name, db_alias)
                transaction.savepoint_commit(sid, using=db_alias)
            cursor.close()
Exemplo n.º 4
0
    def create_sequence(self, created_models, **kwargs):
        # Sequence creation for production is handled by DDL scripts
        # (sqlpartition).  This is needed to create sequences for
        # test models.
        if self.model not in created_models:
            return

        db_alias = self.model._shards.cluster

        for child in self.model._shards.nodes:
            cursor = connections[db_alias].cursor()
            sid = transaction.savepoint(db_alias)
            sequence_name = get_sharded_id_sequence_name(child)
            try:
                cursor.execute("CREATE SEQUENCE %s;" % sequence_name)
            except DatabaseError:
                transaction.savepoint_rollback(sid, using=db_alias)
                # Sequence must already exist, ensure it gets reset
                cursor.execute("SELECT setval('%s', 1, false)" %
                               (sequence_name, ))
            else:
                print 'Created sequence %r on %r' % (sequence_name, db_alias)
                transaction.savepoint_commit(sid, using=db_alias)
            cursor.close()