This commit takes a stab at implementing support for managing SQL views
with rex.deploy.
The example usage:
```
- view: persons
definition: |
select name, email
from user
- view: persons
definition: |
select name, email
from user
union
select name, email
from patient
- view: persons
present: false
```
I've been trying to follow the code for tables but of course making this
specific to the views.
Some notes/design questions appeared:
- How things are introspected has changed, previously both tables and
views were loaded as TableImage objects. Now we load views as
ViewImage objects and we DON'T load view columns. I suspect this will
make a different when querying views with HTSQL?
- When building a model out of facts we need to check for name clashes
between tables and views as they share the same namespace in the
database.
- Should we raise an error in case the same named view appears with
different definitions? Or should we instead override the former with
the latter (dangerous)?
- Right now we load view definition with `pg_get_viewdef` function but
I'm not sure if it is suitable for comparison with view definition in
facts as db can probably mangle the original SQL. We should probably
store view definition in a COMMENT in a database.
- Do we need to support view defined with HTSQL? That would be cool.
- Would be nice to be able to specify a pk for a view (required for
HTSQL to query such view).
- We need to track dependencies:
As we use SQL for view definitions we might need to use SQL parser for
that. I'm thinking of using https://pglast.readthedocs.io/en/latest/
which wraps PostgreSQL's parser.
If we want to add HTSQL based view then we can use HTSQL to infer the
dependencies.
- view -> table, why?
- So we can require to drop view before we drop the table. It is
implemented for linked tables? Would be nice as it will allow to
validate migrations w/o accessing a database.
- view -> view, why?
- so we can require to drop dependent views before we drop the
view
- so we can change definition of a view with dependents (in this
case we need to drop and re-create a view and its dependents)