citusdata / django-multitenant

Python/Django support for distributed multi-tenant databases like Postgres+Citus
MIT License
721 stars 119 forks source link

Automate create composite primary keys #17

Open saicitus opened 6 years ago

saicitus commented 6 years ago

One important pre-requisite for migration to citus is for all the models which are inherited from TenantModel, we need to replace the primary key on id column to a composite primary key (tenant_id,id). As we did this for foreign keys in this #16 (specifically in this file), we could do automate dropping single primary keys and creating composite primary keys.

benldietchef commented 5 years ago

This would be really useful for me, I don't like having to rely on manually updating my migrations. A naive version of this I've tried which does appear to work is:

    # Override
    def column_sql(self, model, field, include_default=False):
        if isinstance(field, TenantPrimaryKey):
            field.primary_key = False
        sql, params = super().column_sql(model, field, include_default)
        return sql, params

    # Override
    def create_model(self, model):
        super().create_model(model)
        for field in model._meta.local_fields:
            if isinstance(field, TenantPrimaryKey):
                tenant_column = self.quote_name(self.get_tenant_column(model))
                table_name = model._meta.db_table
                constraint_name = self.quote_name(f'{table_name}_pkey')
                quoted_table_name = self.quote_name(table_name)
                self.deferred_sql.extend([
                    f"""
                    ---
                    --- Add composite primary key to {table_name}
                    ---
                    ALTER TABLE {quoted_table_name}
                    ADD CONSTRAINT {constraint_name}
                    PRIMARY KEY ({tenant_column}, id)
                    """
                ])