You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
django-postgres-extra makes it easy to partition by a single foreign key field. It would be nice to add better support for subpartitioning. To walk through an example, we can start with this simple model:
class MyModel(...):
id = UUIDField(..., primary_key=True)
amount = DecimalField(...)
# fields we want to partition by
account = ForeignKeyField(...)
sub_account = ForeignKeyField(...)
Partitioning by a single field
Partitioning by the account field is straightforward.
class MyModel(...):
class PartitioningMeta:
method = PostgresPartitioningMethod.LIST
key = ["account_id"]
id = UUIDField(..., primary_key=True)
amount = DecimalField(...)
# fields to partition by
account = ForeignKeyField(...)
sub_account = ForeignKeyField(...)
Whenever a new account is created, we call add_list_partition.
Now, say we want to partition each account partition based on the sub_account field.
class PartitioningMeta:
method = PostgresPartitioningMethod.LIST
key = ["account_id", "sub_account_id"]
Running python manage.py pgmakemigrations will not cause any problems, but when running that migration with python manage.py migrate, Postgres gives back an error: cannot use "list" partition strategy with more than one column. Essentially, we can only partition by one field at a time.
Subpartitioning proposal
Add additional_pk_fields
Since Postgres requires that the field we are partitioning on is part of the table's primary key, we should be able to pass in additional PK fields for the initial creation of the table.
Alternatively, an easier but hackier approach would be to use first element of the key list as the top-level partitioning key but to use all the elements of the key list for the PK.
class PartitioningMeta:
method = PostgresPartitioningMethod.LIST
key = ["account_id", "sub_account_id"]
Either way, the generated SQL should contain:
A composite PK on id, account_id, and sub_account_id
PARTITION BY LIST (account_id)
Modify create_partition_table_name to reference partitions
def create_sub_account(...):
sub_account = SubAccount.objects.create_model(...)
with transaction.atomic():
connection.schema_editor().add_list_partition(
model=MyModel,
name=sub_account.id,
values=[sub_account.id],
existing_partition_fields=["account_id"],
# could pass `next_partition_field` if further subpartitioning is needed
)
The text was updated successfully, but these errors were encountered:
django-postgres-extra
makes it easy to partition by a single foreign key field. It would be nice to add better support for subpartitioning. To walk through an example, we can start with this simple model:Partitioning by a single field
Partitioning by the
account
field is straightforward.Whenever a new account is created, we call
add_list_partition
.Current issues with subpartitioning
Now, say we want to partition each
account
partition based on thesub_account
field.Running
python manage.py pgmakemigrations
will not cause any problems, but when running that migration withpython manage.py migrate
, Postgres gives back an error:cannot use "list" partition strategy with more than one column
. Essentially, we can only partition by one field at a time.Subpartitioning proposal
Add
additional_pk_fields
Since Postgres requires that the field we are partitioning on is part of the table's primary key, we should be able to pass in additional PK fields for the initial creation of the table.
Alternatively, an easier but hackier approach would be to use first element of the
key
list as the top-level partitioning key but to use all the elements of thekey
list for the PK.Either way, the generated SQL should contain:
id
,account_id
, andsub_account_id
PARTITION BY LIST (account_id)
Modify
create_partition_table_name
to reference partitionsExample
Modify
add_list_partition
Call add_list_partition with the additional inputs
The text was updated successfully, but these errors were encountered: