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
示例#2
0
    def get_children_table_sql(self, model, known_models, num_children,
                               shard_range):
        output = []
        opts = model._meta

        def get_child_table_sql(child_num):
            child = generate_child_partition(model, child_num)

            output, references = self.connection.creation.sql_create_model(
                child, self.style, [model, child])
            return output

        for i in shard_range:
            output.extend(get_child_table_sql(i))

        # Generate indexes for tables.
        original_db_table = opts.db_table
        for i in shard_range:
            # TODO: suffix
            opts.db_table = '%s_%s' % (original_db_table, i)
            output.extend(
                self.connection.creation.sql_indexes_for_model(
                    model, self.style))
        opts.db_table = original_db_table

        # ALTERs for check constraint on children table.
        migrations = []
        for i in shard_range:
            child = generate_child_partition(model, i)
            if isinstance(child._shards.key, basestring):
                shard_key_repr = child._shards.key
                shard_key_expr = '"%s"' % shard_key_repr
            else:
                shard_key_repr = '_'.join(child._shards.key)
                # TODO: This sums the keys for the expression right now.
                # This needs to match the logic in MasterShardOptions.get_key_from_kwargs.
                shard_key_expr = '("' + '" + "'.join(child._shards.key) + '")'

            constraint_name = "%s_%s_check_modulo" % (child._meta.db_table,
                                                      shard_key_repr)
#            output.append(self.style.SQL_KEYWORD('ALTER TABLE ') +
#                self.style.SQL_TABLE('"' + child._meta.db_table + '"') +
#                self.style.SQL_KEYWORD(' ADD CONSTRAINT ') +
#                self.style.SQL_FIELD('"'+shard_key_repr+'"')+
#                #self.style.SQL_FIELD('"' + constraint_name + '"') +
#                #self.style.SQL_KEYWORD(' CHECK ') +
#                self.style.SQL_KEYWORD(' REFERENCES ') +
#                '(%s);' % (model.parent._meta.db_table))
#'(%s %% %d = %d);' % (shard_key_expr, num_children, i))

# Temporary ALTER TABLEs to use new sequences until we've fully
# transitioned all old tables.
#migrations.append('ALTER TABLE "{0}" ALTER COLUMN id SET DEFAULT next_sharded_id(\'{0}_id_seq\', {1});'.format(child._meta.db_table, i))

        return output + migrations
    def get_children_table_sql(self, model, known_models, num_children, shard_range):
        output = []
        opts = model._meta

        def get_child_table_sql(child_num):
            child = generate_child_partition(model, child_num)

            output, references = self.connection.creation.sql_create_model(child, self.style, [model, child])
            return output

        for i in shard_range:
            output.extend(get_child_table_sql(i))

        # Generate indexes for tables.
        original_db_table = opts.db_table
        for i in shard_range:
            # TODO: suffix
            opts.db_table = "%s_%s" % (original_db_table, i)
            output.extend(self.connection.creation.sql_indexes_for_model(model, self.style))
        opts.db_table = original_db_table

        # ALTERs for check constraint on children table.
        migrations = []
        for i in shard_range:
            child = generate_child_partition(model, i)
            if isinstance(child._shards.key, basestring):
                shard_key_repr = child._shards.key
                shard_key_expr = '"%s"' % shard_key_repr
            else:
                shard_key_repr = "_".join(child._shards.key)
                # TODO: This sums the keys for the expression right now.
                # This needs to match the logic in MasterShardOptions.get_key_from_kwargs.
                shard_key_expr = '("' + '" + "'.join(child._shards.key) + '")'

            constraint_name = "%s_%s_check_modulo" % (child._meta.db_table, shard_key_repr)
            output.append(
                self.style.SQL_KEYWORD("ALTER TABLE ")
                + self.style.SQL_TABLE('"' + child._meta.db_table + '"')
                + self.style.SQL_KEYWORD(" ADD CONSTRAINT ")
                + self.style.SQL_FIELD('"' + constraint_name + '"')
                + self.style.SQL_KEYWORD(" CHECK ")
                + "(%s %% %d = %d);" % (shard_key_expr, num_children, i)
            )

            # Temporary ALTER TABLEs to use new sequences until we've fully
            # transitioned all old tables.
            migrations.append(
                "ALTER TABLE \"{0}\" ALTER COLUMN id SET DEFAULT next_sharded_id('{0}_id_seq', {1});".format(
                    child._meta.db_table, i
                )
            )

        return output + migrations
示例#4
0
    def get_sequences(self, model, num_children, shard_range):
        output = []

        our_epoch = int(time.mktime(datetime(2012, 11, 1).timetuple()) * 1000)

        for i in shard_range:
            proc = """
			delimiter //
			drop table if exists shard_seq_tbl //
			create table shard_seq_tbl ( nextval bigint not null primary key auto_increment ) engine = MyISAM //
			alter table shard_seq_tbl AUTO_INCREMENT = 10000 //
			
			drop function if exists shard_nextval //
			create function shard_nextval()
			returns bigint
			begin
			   insert into shard_seq_tbl values (NULL) ;
			   set @R_ObjectId_val=LAST_INSERT_ID() ;
			   delete from shard_seq_tbl ;
			   return @R_ObjectId_val ;
			end//
			
			drop function if exists now_msec//
			CREATE FUNCTION now_msec RETURNS STRING SONAME "now_msec.so"//
			
			drop function if exists next_sharded_id //
			CREATE function next_sharded_id ()
			RETURNS bigint
			 BEGIN
				DECLARE our_epoch bigint DEFAULT 1325419260000;
				DECLARE seq_id bigint;
				DECLARE now_millis bigint;
				DECLARE shard_id int DEFAULT {0};
				DECLARE result bigint UNSIGNED;
			
				SELECT MOD(shard_nextval(),1024) INTO seq_id;
			
				SELECT now_msec() INTO now_millis;
				set result := (now_millis - our_epoch) << 23;
				set result := result | (seq_id << 10);
				set result := result | (shard_id);
				RETURN result;
			 END//
			delimiter ;		
			"""
            output.append(self.style.SQL_KEYWORD(proc.format(i)))
            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
    def get_sequences(self, model, num_children, shard_range):
        output = []

        our_epoch = int(time.mktime(datetime(2012, 11, 1).timetuple()) * 1000)

        for i in shard_range:
			proc = """
			delimiter //
			drop table if exists shard_seq_tbl //
			create table shard_seq_tbl ( nextval bigint not null primary key auto_increment ) engine = MyISAM //
			alter table shard_seq_tbl AUTO_INCREMENT = 10000 //
			
			drop function if exists shard_nextval //
			create function shard_nextval()
			returns bigint
			begin
			   insert into shard_seq_tbl values (NULL) ;
			   set @R_ObjectId_val=LAST_INSERT_ID() ;
			   delete from shard_seq_tbl ;
			   return @R_ObjectId_val ;
			end//
			
			drop function if exists now_msec//
			CREATE FUNCTION now_msec RETURNS STRING SONAME "now_msec.so"//
			
			drop function if exists next_sharded_id //
			CREATE function next_sharded_id ()
			RETURNS bigint
			 BEGIN
				DECLARE our_epoch bigint DEFAULT 1325419260000;
				DECLARE seq_id bigint;
				DECLARE now_millis bigint;
				DECLARE shard_id int DEFAULT {0};
				DECLARE result bigint UNSIGNED;
			
				SELECT MOD(shard_nextval(),1024) INTO seq_id;
			
				SELECT now_msec() INTO now_millis;
				set result := (now_millis - our_epoch) << 23;
				set result := result | (seq_id << 10);
				set result := result | (shard_id);
				RETURN result;
			 END//
			delimiter ;		
			"""
			output.append(self.style.SQL_KEYWORD(proc.format(i)))
			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
示例#6
0
        def get_child_table_sql(child_num):
            child = generate_child_partition(model, child_num)

            output, references = self.connection.creation.sql_create_model(
                child, self.style, [model, child])
            return output
        def get_child_table_sql(child_num):
            child = generate_child_partition(model, child_num)

            output, references = self.connection.creation.sql_create_model(child, self.style, [model, child])
            return output