Skip to content

Commit

Permalink
docs: add postgres reference section to docs (close hasura#4440) (has…
Browse files Browse the repository at this point in the history
  • Loading branch information
marionschleifer authored Oct 6, 2020
1 parent af32ccf commit 048daf8
Show file tree
Hide file tree
Showing 11 changed files with 490 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ This release contains the [PDV refactor (#4111)](https://github.com/hasura/graph
- console: add `<3 hasura` section to view updates and notifications from Hasura (#5070)
- cli: add missing global flags for seeds command (#5565)
- docs: add docs page on networking with docker (close #4346) (#4811)
- docs: add postgres concepts page to docs (close #4440) (#4471)


## `v1.3.2`
Expand Down
1 change: 1 addition & 0 deletions docs/graphql/core/guides/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Guides / Tutorials / Resources
:titlesonly:

Data modelling guides <data-modelling/index>
Postgres concepts <postgres/index>
Docker networking <docker-networking>
Sample apps & boilerplates <sample-apps/index>
Integration/migration tutorials <integrations/index>
Expand Down
122 changes: 122 additions & 0 deletions docs/graphql/core/guides/postgres/constraints.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
.. meta::
:description: Use Postgres constraints with Hasura
:keywords: hasura, docs, postgres, constraints

.. _postgres_constraints:

Postgres constraints
====================

.. contents:: Table of contents
:backlinks: none
:depth: 2
:local:

Introduction
------------

`Postgres constraints <https://www.postgresql.org/docs/current/ddl-constraints.html>`__ are used to define rules for columns in a database table. They ensure that
no invalid data is entered into the database.

.. note::

For more detailed information on Postgres constraints, please refer to the `Postgres documentation <https://www.postgresql.org/docs/current/ddl-constraints.html>`__.

Postgres constraints
--------------------

There are different types of constraints that can be used with Postgres.

Primary key constraints
^^^^^^^^^^^^^^^^^^^^^^^

A ``PRIMARY KEY`` is used to identify each row of a table uniquely.

**Identify the author's id as the primary key of the authors table:**

.. code-block:: sql
:emphasize-lines: 2
CREATE TABLE authors(
id INT PRIMARY KEY,
name TEXT NOT NULL
);
Foreign key constraints
^^^^^^^^^^^^^^^^^^^^^^^

A foreign key constraint specifies that the values in a column must match the values appearing in a row of another table.
Foreign key constraints are used to create relationships between tables.

**Define the author_id in the articles table as a foreign key to the id column in the authors table:**

.. code-block:: sql
:emphasize-lines: 11
CREATE TABLE authors(
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);
CREATE TABLE articles(
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
author_id INTEGER,
FOREIGN KEY (author_id) REFERENCES authors (id)
);
Not-null constraints
^^^^^^^^^^^^^^^^^^^^

A not-null constraint allows you to specify that a column's value cannot be ``null``.

**Validate that an author's name cannot be null:**

.. code-block:: sql
:emphasize-lines: 2-3
CREATE TABLE authors(
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
Unique constraints
^^^^^^^^^^^^^^^^^^

Unique constraints prevent database entries with a duplicate value of the respective column.

**Validate that an author's email is unique:**

.. code-block:: sql
:emphasize-lines: 4
CREATE TABLE authors(
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);
Check constraints
^^^^^^^^^^^^^^^^^

Check constraints allow you to specify a ``Boolean`` expression for one or several columns.
This Boolean expression must be satisfied (equal to ``true``) by the column value for the object to be inserted.

**Validate that an author's rating is between 1 and 10:**

.. code-block:: sql
:emphasize-lines: 4
CREATE TABLE authors(
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
rating INT NOT NULL CHECK(rating > 0 AND rating <= 10)
);
Postgres constraints & Hasura
-----------------------------

Most Postgres constraints (primary key, foreign key, not-null and unique constraints) can be added to Hasura natively when :ref:`creating tables <create-tables>`.

Postgres check constraints can be used as a form of data validation in Hasura and can be added :ref:`as described here <data_validations_check_constraints>`.
56 changes: 56 additions & 0 deletions docs/graphql/core/guides/postgres/functions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.. meta::
:description: Use Postgres functions with Hasura
:keywords: hasura, docs, postgres, functions

.. _postgres_functions:

Postgres functions
==================

.. contents:: Table of contents
:backlinks: none
:depth: 1
:local:

Introduction
------------

`Postgres functions <https://www.postgresql.org/docs/current/sql-createfunction.html>`__ allow you to customize your database schema by defining a set of operations that can include several statements such as declarations, assignments and conditional workflows.
Postgres functions are similar to views but allow more procedural computations and can take arguments.

.. note::

For more information on Postgres functions, please refer to the `Postgres documentation <https://www.postgresql.org/docs/current/sql-createfunction.html>`__.

Examples
--------

**Searching articles**

We can create the following function that we can call later to search articles based on the input text argument ``search``.

.. code-block:: plpgsql
CREATE FUNCTION search_articles(search text)
RETURNS SETOF article AS $$
SELECT *
FROM article
WHERE
title ilike ('%' || search || '%')
OR content ilike ('%' || search || '%')
$$ LANGUAGE sql STABLE;
Let's break this function apart:

- Function name: ``search_articles``
- Parameters: there is one parameter where ``search`` is the name and ``text`` is the type
- Return type: ``SETOF article``
- Function body: Block from ``SELECT`` until the end of the ``WHERE`` clause
- Language: The response is returned in the ``sql`` language

Postgres functions & Hasura
---------------------------

Postgres functions can be exposed in Hasura's GraphQL schema as a top-level field or as a computed field for a table. They are typically used for performing custom business logic in the database.

Refer to :ref:`Custom SQL functions <custom_sql_functions>` and :ref:`Computed fields <computed_fields>` for more use cases and for instructions on how to create and expose Postgres functions in Hasura.
57 changes: 57 additions & 0 deletions docs/graphql/core/guides/postgres/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.. meta::
:description: Useful Postgres concepts for Hasura
:keywords: hasura, docs, postgres

.. _postgres_concepts:

Postgres concepts
=================

.. contents:: Table of contents
:backlinks: none
:depth: 2
:local:

Introduction
------------

This page introduces Postgres including benefits and caveats, and it links to sections relevant to extending your GraphQL API by using Postgres features.

About Postgres
--------------

`Postgres (or PostgreSQL) <https://www.postgresql.org/>`__ is a general-purpose object-relational database management system that uses and extends the SQL language.
Postgres is free and open source and has been developed continuously over the last 30 years. Postgres strives to be reliable, robust and performant.

Postgres supports advanced data types and advanced performance optimization, features that are otherwise only available in expensive commercial database systems.

Benefits of Postgres
--------------------

The following are benefits of Postgres compared to other database management systems:

- Postgres can be maintained easily because of its stability. The total cost of ownership is therefore low.
- Postgres is designed to be extensible i.e. you can add custom functions using different programming languages.
- You can define your own data types, index types etc.
- If you need any support, an `active community <https://www.postgresql.org/community/>`__ is available to help.

Postgres features
-----------------

The following are some Postgres features that can be used to manage your data and extend your Hasura GraphQL API:

- :ref:`Constraints <postgres_constraints>`
- :ref:`Views <postgres_views>`
- :ref:`Functions <postgres_functions>`
- :ref:`Triggers <postgres_triggers>`
- :ref:`Indexes <postgres_indexes>`

.. toctree::
:maxdepth: 1
:hidden:

Constraints <constraints>
Views <views>
Functions <functions>
Triggers <triggers>
Indexes <indexes>
48 changes: 48 additions & 0 deletions docs/graphql/core/guides/postgres/indexes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.. meta::
:description: Use Postgres indexes with Hasura
:keywords: hasura, docs, postgres, indexes

.. _postgres_indexes:

Postgres indexes
================

.. contents:: Table of contents
:backlinks: none
:depth: 1
:local:

Introduction
------------

`Postgres indexes <https://www.postgresql.org/docs/current/sql-createindex.html>`__ are a way of increasing query performance
based on columns that are queried frequently. The concept is similar to the one of an index in a book.
It helps accessing the data you're looking for more quickly by maintaining additional metadata.

.. note::

Learn more about indexes in the `Postgres documentation <https://www.postgresql.org/docs/current/sql-createindex.html>`__.

Example
-------

**Create an index on the column name in the table authors:**

Let's say the database receives a large number of requests of authors being queried by their name, for example:

.. code-block:: sql
SELECT * FROM authors WHERE name = 'J.K. Rowling';
We can now create an index on the ``name`` column of the ``authors`` table:

.. code-block:: sql
CREATE INDEX author_name_index ON authors (name);
Since the database is now able to look up the result of these queries more quickly, the performance of these queries will increase significantly.

Postgres indexes & Hasura
-------------------------

Indexes can be used to optimize query performance in Hasura. :ref:`Refer to this page <data_validation_pg_indexes>` for information about query performance and how to add Postgres indexes to Hasura.
89 changes: 89 additions & 0 deletions docs/graphql/core/guides/postgres/triggers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
.. meta::
:description: Use Postgres triggers with Hasura
:keywords: hasura, docs, postgres, triggers

.. _postgres_triggers:

Postgres triggers
=================

.. contents:: Table of contents
:backlinks: none
:depth: 1
:local:

Introduction
------------

`Postgres triggers <https://www.postgresql.org/docs/current/sql-createtrigger.html>`__ are used to invoke previously defined Postgres functions *before* or *after* a specific database event (e.g. ``INSERT``) occurs.

.. note::

For more information on Postgres triggers, please refer to the `Postgres documentation <https://www.postgresql.org/docs/current/sql-createtrigger.html>`__.

Examples
--------

**Trigger a Postgres function before an article is inserted or updated:**

Let's say we want to check if an author is active before a corresponding article can be inserted or updated.
We can do so with the following Postgres function:

.. code-block:: plpgsql
CREATE FUNCTION check_author_active()
RETURNS trigger AS $BODY$
DECLARE active_author BOOLEAN;
BEGIN
SELECT author.is_active INTO active_author FROM "authors" author WHERE author.id = NEW."author_id";
IF active_author != TRUE THEN
RAISE EXCEPTION 'Author must be active';
END IF;
RETURN NEW;
END;
$BODY$ LANGUAGE plpgsql;
Now we want to have this function executed whenever a new article is about to be inserted or updated.
We can create a Postgres trigger as follows:

.. code-block:: plpgsql
CREATE TRIGGER insert_article BEFORE INSERT OR UPDATE ON "articles" FOR EACH ROW EXECUTE PROCEDURE check_author_active();
If someone now tries to insert an article for an author that is not active, the following error will be thrown:

.. code-block:: plpgsql
unexpected : Author must be active
**Refresh a materialized view when an author gets inserted:**

Let's say we want to refresh a materialized view whenever a new author is inserted.

The following Postgres function refreshes a materialized view:

.. code-block:: plpgsql
CREATE FUNCTION refresh_materialized_view()
RETURNS trigger AS $BODY$
BEGIN
REFRESH MATERIALIZED VIEW popular_active_authors;
RETURN NULL;
END;
$BODY$ LANGUAGE plpgsql;
Now, to make sure this function gets called whenever a new author is inserted, we can create the following Postgres trigger:

.. code-block:: plpgsql
CREATE TRIGGER update_materialized_view AFTER INSERT ON "authors" FOR EACH ROW EXECUTE PROCEDURE refresh_materialized_view();
Postgres triggers & Hasura
--------------------------

Postgres triggers can be used to perform business logic such as data validation and can be added :ref:`as described here <data_validations_pg_triggers>`.

.. note::

Hasura also has :ref:`event triggers <event_triggers>` that can be used to invoke external HTTP APIs for executing custom business logic on
database events.
Loading

0 comments on commit 048daf8

Please sign in to comment.