Add embedding disambiguation section (#290)

This commit is contained in:
Steve Chavez
2020-01-06 09:43:54 -05:00
committed by GitHub
parent e47d19d4dc
commit 4cd05681dd
4 changed files with 126 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+104
View File
@@ -746,6 +746,110 @@ Response:
}
}
.. _embed_disamb:
Embedding Disambiguation
------------------------
For doing resource embedding, PostgREST infers the relationship between two tables based on a foreign key between them.
However, in cases where there's more than one foreign key between two tables, it's not possible to infer the relationship unambiguosly
by just specifying the tables names.
Target Disambiguation
~~~~~~~~~~~~~~~~~~~~~
For example, suppose you have the following ``orders`` and ``addresses`` tables:
.. image:: _static/orders.png
And you try to embed ``orders`` with ``addresses`` (this is the **target**):
.. code-block:: http
GET /orders?select=*,addresses(*) HTTP/1.1
Since the ``orders`` table has two foreign keys to the ``addresses`` table — an order has a billing address and a shipping address —
the request is ambiguous and PostgREST will respond with an error:
.. code-block:: http
HTTP/1.1 300 Multiple Choices
If this happens, you need to disambiguate the request by adding precision to the **target**.
Instead of the **table name**, you can specify the **foreign key constraint name** or the **column name** that is part of the foreign key.
Let's try first with the **foreign key constraint name**. To make it clearer we can name it:
.. code-block:: postgresql
ALTER TABLE orders
ADD CONSTRAINT billing_address foreign key (billing_address_id) references addresses(id),
ADD CONSTRAINT shipping_address foreign key (shipping_address_id) references addresses(id);
-- Or if the constraints names were already generated by PostgreSQL we can rename them
-- ALTER TABLE orders
-- RENAME CONSTRAINT orders_billing_address_id_fkey TO billing_address,
-- RENAME CONSTRAINT orders_shipping_address_id_fkey TO shipping_address;
Now we can unambiguously embed the billing address by specifying the ``billing_address`` foreign key constraint as the **target**.
.. code-block:: http
GET /orders?select=name,billing_address(name) HTTP/1.1
[
{
"name": "Personal Water Filter",
"billing_address": {
"name": "32 Glenlake Dr.Dearborn, MI 48124"
}
}
]
Alternatively, you can specify the **column name** of the foreign key constraint as the **target**. This can be aliased to make
the result more clear.
.. code-block:: http
GET /orders?select=name,billing_address:billing_address_id(name) HTTP/1.1
[
{
"name": "Personal Water Filter",
"billing_address": {
"name": "32 Glenlake Dr.Dearborn, MI 48124"
}
}
]
Hint Disambiguation
~~~~~~~~~~~~~~~~~~~
If specifying the **target** is not enough for unambiguous embedding, you can add a **hint**. For example, let's assume we create
two VIEWs of ``addresses``: ``central_addresses`` and ``eastern_addresses``.
Since PostgREST supports :ref:`embedding_views` by detecting **source foreign keys** in the views, embedding with the foreign key
as the **target** will not be enough for an unambiguous embed:
.. code-block:: http
GET /orders?select=*,billing_address(*) HTTP/1.1
HTTP/1.1 300 Multiple Choices
For solving this case, in addition to the **target**, we can add a **hint**.
Here we specify ``central_addresses`` as the **target** and the ``billing_address`` foreign key as the **hint**:
.. code-block:: http
GET /orders?select=*,central_addresses!billing_address(*) HTTP/1.1
HTTP/1.1 200 OK
[ ... ]
Similarly to the **target**, the **hint** can be a **table name**, **foreign key constraint name** or **column name**.
.. _custom_queries:
Custom Queries
+7
View File
@@ -0,0 +1,7 @@
This files were created with https://github.com/BurntSushi/erd/.
You can go download erd from https://github.com/BurntSushi/erd/releases and then do:
```bash
./erd_static-x86-64 -i erd/film.er -o _static/film.png
```
+15
View File
@@ -0,0 +1,15 @@
[Addresses]
*id
name
city
state
postal_code
[Orders]
*id
name
+billing_address_id
+shipping_address_id
Orders *--1 Addresses
Orders *--1 Addresses