tfoxy / graphene-django-optimizer

Optimize database access inside graphene queries
MIT License
428 stars 84 forks source link

Multiple fragments specifying the same relation field #21

Open ktosiek opened 5 years ago

ktosiek commented 5 years ago

When multiple fragments specify the same relation field it currently is optimized multiple times. In the example below prefetch_related will be executed twice. I think there should only be one call to select_related/prefetch_related for one output field.

Failing test case:

@pytest.mark.django_db
def test_should_optimize_when_using_overlapping_fragments():
    info = create_resolve_info(schema, '''
        query {
            items(name: "bar") {
            ...ItemFragment_1
            ...ItemFragment_2
            }
        }
        fragment ItemFragment_1 on ItemType {
            itemSet {
                id
            }
        }
        fragment ItemFragment_2 on ItemType {
            itemSet {
                id
            }
        }
    ''')
    qs = Item.objects.filter(name='bar')
    items = gql_optimizer.query(qs, info)
    optimized_items = qs.prefetch_related(
        Prefetch('item_set', queryset=Item.objects.only('id', 'item_id'))
    )
    assert_query_equality(items, optimized_items)

I've looked at the code, but I can't see a simple way to fix this. Maybe the query should be flattened before optimization?