Add embedding disambiguation section (#290)
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -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
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user