initial commit
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Pyrseas.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Pyrseas.qhc"
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||
"run these through (pdf)latex."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
@@ -0,0 +1,30 @@
|
||||
Augmenter Databases
|
||||
===================
|
||||
|
||||
.. module:: pyrseas.augmentdb
|
||||
|
||||
The :mod:`augmentdb` module defines the class :class:`AugmentDatabase`.
|
||||
|
||||
Augmenter Database
|
||||
------------------
|
||||
|
||||
An :class:`AugmentDatabase` is derived from
|
||||
:class:`~pyrseas.database.Database`. It contains two "dictionary"
|
||||
objects.
|
||||
|
||||
One is the :class:`Dicts` container from its parent class. The `db`
|
||||
Dicts object, defines the database schemas, including their tables and
|
||||
other objects, by querying the system catalogs.
|
||||
|
||||
The second container is an :class:`AugDicts` object. The `adb`
|
||||
AugDicts object specifies the schemas to be augmented and the
|
||||
augmenter configuration objects. The latter objects may be supplied
|
||||
either by other Augmenter modules or from the ``augmenter``
|
||||
configuration tree on the `aug_map` supplied to the :meth:`apply`
|
||||
method.
|
||||
|
||||
.. autoclass:: AugmentDatabase
|
||||
|
||||
.. automethod:: AugmentDatabase.apply
|
||||
|
||||
.. automethod:: AugmentDatabase.from_augmap
|
||||
@@ -0,0 +1,42 @@
|
||||
Augmentation Objects
|
||||
====================
|
||||
|
||||
These objects are defined in the `aug_map` argument to the `apply`
|
||||
method of :class:`~pyrseas.augmentdb.AugmentDatabase`. They tie the
|
||||
desired augmentations, e.g., audit columns, to the tables to be
|
||||
affected, and the schemas owning the tables.
|
||||
|
||||
.. module:: pyrseas.augment.schema
|
||||
|
||||
Augmentation Schema
|
||||
-------------------
|
||||
|
||||
.. autoclass:: AugSchema
|
||||
|
||||
.. automethod:: AugSchema.apply
|
||||
|
||||
.. autoclass:: AugSchemaDict
|
||||
|
||||
.. automethod:: AugSchemaDict.from_map
|
||||
|
||||
.. automethod:: AugSchemaDict.link_current
|
||||
|
||||
.. automethod:: AugSchemaDict.link_refs
|
||||
|
||||
|
||||
.. module:: pyrseas.augment.table
|
||||
|
||||
Augmentation Table
|
||||
------------------
|
||||
|
||||
.. autoclass:: AugDbClass
|
||||
|
||||
.. autoclass:: AugTable
|
||||
|
||||
.. automethod:: AugTable.apply
|
||||
|
||||
.. autoclass:: AugClassDict
|
||||
|
||||
.. automethod:: AugClassDict.from_map
|
||||
|
||||
.. automethod:: AugClassDict.link_current
|
||||
@@ -0,0 +1,39 @@
|
||||
Casts
|
||||
=====
|
||||
|
||||
.. module:: pyrseas.dbobject.cast
|
||||
|
||||
The :mod:`cast` module defines two classes, :class:`Cast` and
|
||||
:class:`CastDict`, derived from :class:`DbObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Cast
|
||||
----
|
||||
|
||||
:class:`Cast` is derived from :class:`~pyrseas.dbobject.DbObject` and
|
||||
represents a `Postgres cast
|
||||
<https://www.postgresql.org/docs/current/static/sql-createcast.html>`_.
|
||||
|
||||
A cast is identified externally as ``cast (<source_type> AS
|
||||
<target_type>)``.
|
||||
|
||||
.. autoclass:: Cast
|
||||
|
||||
.. automethod:: Cast.extern_key
|
||||
|
||||
.. automethod:: Cast.identifier
|
||||
|
||||
.. automethod:: Cast.to_map
|
||||
|
||||
.. automethod:: Cast.create
|
||||
|
||||
Cast Dictionary
|
||||
---------------
|
||||
|
||||
:class:`CastDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of casts in a database.
|
||||
|
||||
.. autoclass:: CastDict
|
||||
|
||||
.. automethod:: CastDict.from_map
|
||||
@@ -0,0 +1,97 @@
|
||||
Augmenter Configuration Objects
|
||||
===============================
|
||||
|
||||
These configuration objects are predefined in the Augmenter modules or
|
||||
can be defined or overridden by configuration elements in the
|
||||
``augmenter`` map. Please see also :doc:`configitems` and
|
||||
:doc:`predefaug`.
|
||||
|
||||
.. module:: pyrseas.augment.function
|
||||
|
||||
Configuration Functions
|
||||
-----------------------
|
||||
|
||||
A :class:`CfgFunction` class specifies a Postgres function to be used
|
||||
by other augmenter objects. For example, this includes procedures to
|
||||
be invoked by triggers used to maintain audit columns. The
|
||||
:class:`CfgFunctionDict` class holds all the :class:`CfgFunction`
|
||||
objects, indexed by the function name and its arguments. A
|
||||
:class:`CfgFunctionSource` class represents the source code for a
|
||||
function or part of that source code. A :class:`CfgFunctionTemplate`
|
||||
class represents the source code for a function, which may include
|
||||
other elements that can be substituted in the final result. The class
|
||||
:class:`CfgFunctionSourceDict` holds all the templates currently
|
||||
defined.
|
||||
|
||||
.. autoclass:: CfgFunction
|
||||
|
||||
.. automethod:: CfgFunction.apply
|
||||
|
||||
.. autoclass:: CfgFunctionDict
|
||||
|
||||
.. automethod:: CfgFunctionDict.from_map
|
||||
|
||||
.. autoclass:: CfgFunctionSource
|
||||
|
||||
.. autoclass:: CfgFunctionTemplate
|
||||
|
||||
.. autoclass:: CfgFunctionSourceDict
|
||||
|
||||
|
||||
.. module:: pyrseas.augment.column
|
||||
|
||||
Configuration Columns
|
||||
---------------------
|
||||
|
||||
A :class:`CfgColumn` class defines a column to be added to a table by
|
||||
other augmenter objects. For example, this includes various columns
|
||||
that serve to capture audit trail information. The columns can be
|
||||
combined in various ways by the :class:`CfgAuditColumn` objects. The
|
||||
:class:`CfgColumnDict` class holds all the :class:`CfgColumn` objects,
|
||||
indexed by column name.
|
||||
|
||||
.. autoclass:: CfgColumn
|
||||
|
||||
.. automethod:: CfgColumn.apply
|
||||
|
||||
.. autoclass:: CfgColumnDict
|
||||
|
||||
.. automethod:: CfgColumnDict.from_map
|
||||
|
||||
|
||||
.. module:: pyrseas.augment.trigger
|
||||
|
||||
Configuration Triggers
|
||||
----------------------
|
||||
|
||||
A :class:`CfgTrigger` class defines a trigger to be added to a table
|
||||
by other augmentation objects. For example, this includes triggers to
|
||||
maintain audit trail columns. The :class:`CfgTriggerDict` class holds
|
||||
all the :class:`CfgTrigger` objects, indexed by trigger name.
|
||||
|
||||
.. autoclass:: CfgTrigger
|
||||
|
||||
.. automethod:: CfgTrigger.apply
|
||||
|
||||
.. autoclass:: CfgTriggerDict
|
||||
|
||||
.. automethod:: CfgTriggerDict.from_map
|
||||
|
||||
|
||||
.. module:: pyrseas.augment.audit
|
||||
|
||||
Configuration Audit Columns
|
||||
---------------------------
|
||||
|
||||
A :class:`CfgAuditColumn` class defines a set of attributes (columns,
|
||||
triggers) to be added to a table. The :class:`CfgAuditColumnDict`
|
||||
class holds all the :class:`CfgAuditColumn` objects, indexed by
|
||||
augmentation name.
|
||||
|
||||
.. autoclass:: CfgAuditColumn
|
||||
|
||||
.. automethod:: CfgAuditColumn.apply
|
||||
|
||||
.. autoclass:: CfgAuditColumnDict
|
||||
|
||||
.. automethod:: CfgAuditColumnDict.from_map
|
||||
@@ -0,0 +1,91 @@
|
||||
Common Command Line Options
|
||||
===========================
|
||||
|
||||
The Pyrseas utilities support the following command line options:
|
||||
|
||||
.. cmdoption:: -c <config-file>
|
||||
--config <config-file>
|
||||
|
||||
Specifies an additional `configuration file` to be read and merged
|
||||
with configuration information from other sources. See
|
||||
:doc:`config` for more details.
|
||||
|
||||
.. cmdoption:: -H <host>
|
||||
--host <host>
|
||||
|
||||
Specifies the `host name` of the machine on which the Postgres
|
||||
server is running. The default host name is determined by
|
||||
Postgres (normally, a Unix-domain socket or ``localhost``).
|
||||
|
||||
.. cmdoption:: -h, --help
|
||||
|
||||
Show help about the program's command line arguments, and exit.
|
||||
|
||||
.. cmdoption:: -o <file>
|
||||
--output <file>
|
||||
|
||||
Send output to the specified `file`. If this is omitted, the
|
||||
standard output is used.
|
||||
|
||||
.. cmdoption:: -p <port>
|
||||
--port <port>
|
||||
|
||||
Specifies the `port` on which the Postgres server is listening
|
||||
for connections. The default port number is determined by
|
||||
Postgres (normally, 5432).
|
||||
|
||||
.. cmdoption:: -r <path>
|
||||
--repository <path>
|
||||
|
||||
Specifies the `path` to a directory where metadata and static data
|
||||
files will be written to or read from, or where an additional
|
||||
configuration file can be found. Normally, this will be the root
|
||||
of a version control repository. If this is not specified on the
|
||||
command line or in a configuration file, it defaults to the
|
||||
current working directory.
|
||||
|
||||
.. cmdoption:: -U <username>
|
||||
--user <username>
|
||||
|
||||
Postgres `user name` to connect as. The default user name is
|
||||
determined by Postgres (normally, the name of the operating system
|
||||
user running the program).
|
||||
|
||||
.. cmdoption:: --version
|
||||
|
||||
Print the program name and version identifier and exit.
|
||||
|
||||
.. cmdoption:: -W, --password
|
||||
|
||||
Force the program to prompt for a password before connecting to a
|
||||
database. If this option is not specified and password
|
||||
authentication is required, the program will resort to libpq
|
||||
defaults, i.e., `password file
|
||||
<https://www.postgresql.org/docs/current/static/libpq-pgpass.html>`_
|
||||
or `PGPASSWORD environment variable
|
||||
<https://www.postgresql.org/docs/current/static/libpq-envars.html>`_.
|
||||
|
||||
Short options (those only one character long) can be concatenated with
|
||||
their value arguments, e.g.::
|
||||
|
||||
dbtoyaml -p5433 dbname
|
||||
|
||||
Several short options can be joined together, using only a single -
|
||||
prefix, as long as only the last option (or none of them) requires a
|
||||
value.
|
||||
|
||||
Long options (those with names longer than a single-character) can be
|
||||
separated from their arguments by a '=' or passed as two separate
|
||||
arguments. For example::
|
||||
|
||||
dbtoyaml --port=5433 dbname
|
||||
|
||||
or::
|
||||
|
||||
dbtoyaml --port 5433 dbname
|
||||
|
||||
Long options can be abbreviated as long as the abbreviation is
|
||||
unambiguous::
|
||||
|
||||
dbtoyaml --pass dbname
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
Collations
|
||||
==========
|
||||
|
||||
.. module:: pyrseas.dbobject.collation
|
||||
|
||||
The :mod:`collation` module defines two classes, :class:`Collation`
|
||||
and :class:`CollationDict`, derived from :class:`DbSchemaObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Collation
|
||||
---------
|
||||
|
||||
:class:`Collation` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a `Postgres
|
||||
collation
|
||||
<https://www.postgresql.org/docs/current/static/collation.html>`_.
|
||||
|
||||
.. autoclass:: Collation
|
||||
|
||||
.. automethod:: Collation.create
|
||||
|
||||
Collation Dictionary
|
||||
--------------------
|
||||
|
||||
:class:`CollationDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of collations in a database.
|
||||
|
||||
.. autoclass:: CollationDict
|
||||
|
||||
.. automethod:: CollationDict.from_map
|
||||
@@ -0,0 +1,52 @@
|
||||
Columns
|
||||
=======
|
||||
|
||||
.. module:: pyrseas.dbobject.column
|
||||
|
||||
The :mod:`column` module defines two classes, :class:`Column` derived
|
||||
from :class:`DbSchemaObject` and :class:`ColumnDict`, derived from
|
||||
:class:`DbObjectDict`.
|
||||
|
||||
Column
|
||||
------
|
||||
|
||||
:class:`Column` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a column of a
|
||||
table, or an attribute of a composite type. Its :attr:`keylist`
|
||||
attributes are the schema name and the table name.
|
||||
|
||||
A :class:`Column` has the following attributes: :attr:`name`,
|
||||
:attr:`type`, :attr:`not_null`, :attr:`default` and
|
||||
:attr:`collation`. The :attr:`number` attribute is also present but is
|
||||
not made visible externally.
|
||||
|
||||
.. autoclass:: Column
|
||||
|
||||
.. automethod:: Column.to_map
|
||||
|
||||
.. automethod:: Column.add
|
||||
|
||||
.. automethod:: Column.add_privs
|
||||
|
||||
.. automethod:: Column.diff_privileges
|
||||
|
||||
.. automethod:: Column.comment
|
||||
|
||||
.. automethod:: Column.drop
|
||||
|
||||
.. automethod:: Column.rename
|
||||
|
||||
.. automethod:: Column.alter
|
||||
|
||||
Column Dictionary
|
||||
-----------------
|
||||
|
||||
Class :class:`ColumnDict` is a dictionary derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict` and represents the collection
|
||||
of columns in a database, across multiple tables. It is indexed by the
|
||||
schema name and table name, and each value is a list of
|
||||
:class:`Column` objects.
|
||||
|
||||
.. autoclass:: ColumnDict
|
||||
|
||||
.. automethod:: ColumnDict.from_map
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Pyrseas documentation build configuration file, created by
|
||||
# sphinx-quickstart on Fri Dec 17 22:06:15 2010.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = "Pyrseas"
|
||||
copyright = "2010-2022, Joe Abbate"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
import re
|
||||
from pyrseas import __version__ as release
|
||||
version = re.match(r'\d+\.\d+(?:\.\d+)?', release).group()
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
if 'dev' in release:
|
||||
release = release[:release.find('dev') + 3]
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of documents that shouldn't be included in the build.
|
||||
#unused_docs = []
|
||||
|
||||
# List of directories, relative to source directory, that shouldn't be searched
|
||||
# for source files.
|
||||
exclude_trees = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_use_modindex = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = ''
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Pyrseasdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Pyrseas.tex', u'Pyrseas Documentation',
|
||||
u'Joe Abbate', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
||||
@@ -0,0 +1,88 @@
|
||||
Configuration
|
||||
=============
|
||||
|
||||
The Pyrseas utilities allow you to configure various options through a
|
||||
number of YAML specification files, none of which are required--but
|
||||
the system configuration file is provided by the normal installation.
|
||||
|
||||
If a configuration parameter is specified in more than one file, the
|
||||
latter file in the list of files below overrides any earlier
|
||||
specification. Any configuration item specified on the command line
|
||||
takes precedence over any such item in a configuration file.
|
||||
|
||||
Configuration File Name
|
||||
-----------------------
|
||||
|
||||
The default configuration file name is ``config.yaml``. If desired,
|
||||
you can override this with the environment variable
|
||||
``PYRSEAS_CONFIG_FILE``, but be aware that this will affect all three
|
||||
levels below.
|
||||
|
||||
System Configuration
|
||||
--------------------
|
||||
|
||||
The system configuration file is distributed with Pyrseas and is
|
||||
normally installed in the ``pyrseas`` library directory.
|
||||
|
||||
If desired, you can override this using the ``PYRSEAS_SYS_CONFIG``
|
||||
environment variable. This can be defined as a full path, including a
|
||||
file name, or a directory location, in which case the default file
|
||||
name as mentioned above under `Configuration File Name`_ will be
|
||||
appended to the path.
|
||||
|
||||
Currently, this file includes specifications for functions, triggers
|
||||
and other objects used by the :program:`dbaugment` utility. It also
|
||||
includes the default directory path for storing multiple YAML files in
|
||||
a VCS repository, and the path to data files for use by the data
|
||||
import and export facilities.
|
||||
|
||||
User Configuration
|
||||
------------------
|
||||
|
||||
Each user can have his or her own configuration file. The default
|
||||
location for this depends on the platform. Under Linux, BSD, OS/X and
|
||||
other Unix variants, place the file under your home directory, in the
|
||||
subdirectory ``.config/pyrseas/``. Under Windows, put the file in
|
||||
``%APPDATA%\pyrseas\``.
|
||||
|
||||
You can override the location of the user configuration file using the
|
||||
``PYRSEAS_USER_CONFIG`` environment variable. This can be defined as
|
||||
a full path, including a file name, or a directory location, in which
|
||||
case the default file name as mentioned above under `Configuration
|
||||
File Name`_ will be appended to the path.
|
||||
|
||||
If present, the user configuration file will be merged with the system
|
||||
configuration.
|
||||
|
||||
It is recommended that the user configuration file only be used for
|
||||
non-project-specific purposes. For example, if you frequently use
|
||||
Pyrseas against a remote database or on a non-standard port, you can
|
||||
specify the host or port in your personal configuration file.
|
||||
|
||||
Repository Configuration
|
||||
------------------------
|
||||
|
||||
A configuration file can be placed in a version control repository or
|
||||
project directory, so that it can be under version control together
|
||||
with other Pyrseas files such as the output from ``dbtoyaml
|
||||
--multiple-files``. The default location for the repository can be
|
||||
specified in the user configuration, using the keys ``repository`` and
|
||||
``path``, for example::
|
||||
|
||||
repository:
|
||||
path: /home/user/project/repo
|
||||
|
||||
You can also use the :option:`--repository` command line option to
|
||||
specify (or override) the directory path to the root of the repository
|
||||
and the utilities will look for a configuration file in that location.
|
||||
|
||||
If present, the repository configuration file will be merged with the
|
||||
system and user configuration information.
|
||||
|
||||
Command Line Configuration
|
||||
--------------------------
|
||||
|
||||
The utilities also allow you to specify a fourth configuration file on
|
||||
the command line, using the :option:`--config` command line option.
|
||||
Again, if the file exists, its information will be merged with
|
||||
previously read files.
|
||||
@@ -0,0 +1,175 @@
|
||||
Configuration Items
|
||||
===================
|
||||
|
||||
The following lists the various sections allowed in a configuration
|
||||
file and the items that are recognized by the Pyrseas utilities.
|
||||
|
||||
Augmenter
|
||||
---------
|
||||
|
||||
This section is used by the :program:`dbaugment` utility (see
|
||||
:doc:`dbaugment`). Most of these are specified in the system
|
||||
configuration file delivered with Pyrseas, but can also be included or
|
||||
overridden in user or repository configuration files.
|
||||
|
||||
- audit_columns: This section defines combinations of columns and
|
||||
triggers to be added to tables. Both columns and triggers are
|
||||
specified as YAML lists (to be consistent with :program:`dbtoyaml`
|
||||
YAML output), although normally a single trigger will be necessary
|
||||
per column combination. The columns and triggers should reference
|
||||
previously defined items in the ``columns`` and ``triggers``
|
||||
sections (see below). See :doc:`predefaug` for audit columns
|
||||
defined in the system ``config.yaml``.
|
||||
|
||||
- columns: This section defines prototype columns to be added to a
|
||||
table by Augmenter. For each column, a valid `Postgres data type
|
||||
<https://www.postgresql.org/docs/current/static/datatype.html>`_
|
||||
should be included.
|
||||
|
||||
You can also add a ``not_null`` constraint and a ``default``
|
||||
specification. See :doc:`predefaug` for columns defined in the
|
||||
system ``config.yaml``. In a repository or user configuration file,
|
||||
you can also specify an alternate name for a previously defined
|
||||
column. For example, if you prefer that the ``modified_timestamp``
|
||||
columns be named ``last_update``, you can add the following to a
|
||||
configuration file::
|
||||
|
||||
augmenter:
|
||||
columns:
|
||||
modified_timestamp:
|
||||
name: last_update
|
||||
|
||||
- function_templates: This section defines the source text for the
|
||||
trigger functions (see below) using a template language. Any text
|
||||
enclosed in double braces, e.g., ``{{modified_by_user}}``, will be
|
||||
replaced, typically by a previously defined column or its alternate
|
||||
name (see above).
|
||||
|
||||
- functions: This section defines prototype trigger functions to be
|
||||
invoked by audit columns or other augmentations. The following
|
||||
items can be specified for each function:
|
||||
|
||||
- description: Text for a `COMMENT
|
||||
<https://www.postgresql.org/docs/current/static/sql-comment.html>`_
|
||||
statement on the function.
|
||||
|
||||
- language: Procedural language, e.g., ``plpgsql``, in which the
|
||||
function is written.
|
||||
|
||||
- returns: Value should be ``trigger``.
|
||||
|
||||
- security_definer: Indicates whether the function is to be executed
|
||||
with the privileges of the user that created it. This is usually
|
||||
needed for audit column trigger functions.
|
||||
|
||||
- source: This is usually a reference to a function template (see
|
||||
above) enclosed in double braces, e.g.,
|
||||
``{{functempl_audit_default}}``. However, in user or repository
|
||||
configurations, this can also be the actual text of the function.
|
||||
|
||||
See :doc:`predefaug` for functions defined in the system
|
||||
configuration file.
|
||||
|
||||
- schema pyrseas: This section currently defines three functions that
|
||||
may be installed in the ``pyrseas`` schema if the ``full`` audit
|
||||
columns specifications is added for Augmenter processing.
|
||||
|
||||
- schemas and tables: Multiple ``schema schema-name`` sections can be
|
||||
present, typically in a repository configuration file. Each such
|
||||
section can include ``table table-name`` items, and under each the
|
||||
``audit_columns`` specifications to be added to the given table.
|
||||
For example::
|
||||
|
||||
augmenter:
|
||||
schema public:
|
||||
table t1:
|
||||
audit_columns: default
|
||||
|
||||
- triggers: This section defines the prototype triggers to be used
|
||||
with audit columns and other augmentations. The following items can
|
||||
be specified for each trigger:
|
||||
|
||||
- events: This is a list that can include one or more of ``insert``,
|
||||
``update`` or ``delete`` (the latter is not used for audit columns
|
||||
but may be used in future augmentations).
|
||||
|
||||
- level: This can take the values ``row`` or ``statement`` (usually
|
||||
the former).
|
||||
|
||||
- name: This specifies the name to be given to a trigger. It can be
|
||||
a template using ``{{table_name}}`` which will then be replaced
|
||||
with the actual table name on which the trigger will act.
|
||||
|
||||
- procedure: This is the invocation name, e.g., ``audit_default()``
|
||||
of the function to be called when the trigger fires.
|
||||
|
||||
- timing: This can take the values ``before`` or ``after`` (usually
|
||||
the former).
|
||||
|
||||
Database
|
||||
--------
|
||||
|
||||
This section is primarily for a user configuration file. If you
|
||||
frequently connect to a particular host, port or as a given user, that
|
||||
are *not* the Postgres defaults, adding corresponding entries to your
|
||||
user configuration file allows you to automatically override the
|
||||
defaults. If for a given invocation you need to connect to or as a
|
||||
different host, port or user, you can still override the configuration
|
||||
using the command line options (see :doc:`cmdargs`):
|
||||
|
||||
- host: Name of the host to connect. Please refer to the `Postgres
|
||||
connection host documentation
|
||||
<https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-HOST>`_
|
||||
for details and defaults.
|
||||
|
||||
- port: Port number to connect to. See the `Postgres connection port
|
||||
documentation
|
||||
<https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-PORT>`_
|
||||
for more.
|
||||
|
||||
- username: Name of the user to connect as. View the `Postgres
|
||||
connection user documentation
|
||||
<https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-USER>`_
|
||||
for more.
|
||||
|
||||
Datacopy
|
||||
--------
|
||||
|
||||
This section is normally in a user or repository configuration file.
|
||||
It is used by :program:`dbtoyaml` and :program:`yamltodb` to determine
|
||||
which tables should be exported from or imported to the database. It
|
||||
consists of schema names, using the format `schema schema_name`,
|
||||
followed by lists of table names. For example::
|
||||
|
||||
datacopy:
|
||||
schema public:
|
||||
- t1
|
||||
- t2
|
||||
schema s1:
|
||||
- t3
|
||||
|
||||
Repository
|
||||
----------
|
||||
|
||||
This section is used by all utilities (but :program:`dbaugment` does
|
||||
not fully support it). The "repository" is intended to be a version
|
||||
control, e.g., Git, Mercurial, or Subversion, repository.
|
||||
|
||||
- data: Path, relative to the root of the repository, where
|
||||
:program:`dbtoyaml` and :program:`yamltodb` place or expect the
|
||||
files containing data exported from or imported to the database. The
|
||||
tables to be exported or imported are specified in the ``Datacopy``
|
||||
section. The default value (defined in the system ``config.yaml``)
|
||||
is **metadata**.
|
||||
|
||||
- metadata: Path, relative to the root of the repository, where
|
||||
:program:`dbtoyaml` and :program:`yamltodb` place or expect the YAML
|
||||
specification files for the database objects when the
|
||||
`--multiple-files` option is used. The default value (defined
|
||||
in the system ``config.yaml``) is **metadata**.
|
||||
|
||||
- path: Absolute path to the root of the repository. This should
|
||||
normally be specified in a user configuration file, or in a file
|
||||
given with the :option:`--config` option. If not specified, this
|
||||
defaults to the current working directory from which the utility is
|
||||
run.
|
||||
@@ -0,0 +1,109 @@
|
||||
Constraints
|
||||
===========
|
||||
|
||||
.. module:: pyrseas.dbobject.constraint
|
||||
|
||||
The :mod:`constraint` module defines six classes: :class:`Constraint`
|
||||
derived from :class:`DbSchemaObject`, classes
|
||||
:class:`CheckConstraint`, :class:`PrimaryKey`, :class:`ForeignKey` and
|
||||
:class:`UniqueConstraint` derived from :class:`Constraint`, and
|
||||
:class:`ConstraintDict` derived from :class:`DbObjectDict`.
|
||||
|
||||
Constraint
|
||||
----------
|
||||
|
||||
Class :class:`Constraint` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a constraint
|
||||
on a database table. Its :attr:`keylist` attributes are the schema
|
||||
name, the table name and the constraint name.
|
||||
|
||||
.. autoclass:: Constraint
|
||||
|
||||
.. automethod:: Constraint.key_columns
|
||||
|
||||
.. automethod:: Constraint.add
|
||||
|
||||
.. automethod:: Constraint.drop
|
||||
|
||||
.. automethod:: Constraint.comment
|
||||
|
||||
Check Constraint
|
||||
----------------
|
||||
|
||||
:class:`CheckConstraint` is derived from :class:`Constraint` and represents
|
||||
a CHECK constraint.
|
||||
|
||||
.. autoclass:: CheckConstraint
|
||||
|
||||
.. automethod:: CheckConstraint.to_map
|
||||
|
||||
.. automethod:: CheckConstraint.add
|
||||
|
||||
.. automethod:: CheckConstraint.drop
|
||||
|
||||
.. automethod:: CheckConstraint.alter
|
||||
|
||||
Primary Key
|
||||
-----------
|
||||
|
||||
:class:`PrimaryKey` is derived from :class:`Constraint` and represents
|
||||
a primary key constraint.
|
||||
|
||||
.. autoclass:: PrimaryKey
|
||||
|
||||
.. automethod:: PrimaryKey.to_map
|
||||
|
||||
.. automethod:: PrimaryKey.alter
|
||||
|
||||
Foreign Key
|
||||
-----------
|
||||
|
||||
:class:`ForeignKey` is derived from :class:`Constraint` and represents
|
||||
a foreign key constraint.
|
||||
|
||||
The following shows a foreign key segment of a map returned by
|
||||
:meth:`to_map` and expected as argument by
|
||||
:meth:`ConstraintDict.from_map` exemplifying various possibilities::
|
||||
|
||||
{'t1_fgn_key1':
|
||||
{
|
||||
'columns': ['c2', 'c3'],
|
||||
'on_delete': 'restrict',
|
||||
'on_update': 'set null',
|
||||
'references':
|
||||
{'columns': ['pc2', 'pc1'], 'schema': 's1', 'table': 't2'}
|
||||
}
|
||||
}
|
||||
|
||||
.. autoclass:: ForeignKey
|
||||
|
||||
.. automethod:: ForeignKey.ref_columns
|
||||
|
||||
.. automethod:: ForeignKey.to_map
|
||||
|
||||
.. automethod:: ForeignKey.add
|
||||
|
||||
.. automethod:: ForeignKey.alter
|
||||
|
||||
Unique Constraint
|
||||
-----------------
|
||||
|
||||
:class:`UniqueConstraint` is derived from :class:`Constraint` and
|
||||
represents a UNIQUE, non-primary key constraint.
|
||||
|
||||
.. autoclass:: UniqueConstraint
|
||||
|
||||
.. automethod:: UniqueConstraint.to_map
|
||||
|
||||
.. automethod:: UniqueConstraint.alter
|
||||
|
||||
Constraint Dictionary
|
||||
---------------------
|
||||
|
||||
Class :class:`ConstraintDict` is a dictionary derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict` and represents the collection
|
||||
of constraints in a database.
|
||||
|
||||
.. autoclass:: ConstraintDict
|
||||
|
||||
.. automethod:: ConstraintDict.from_map
|
||||
@@ -0,0 +1,33 @@
|
||||
Conversions
|
||||
===========
|
||||
|
||||
.. module:: pyrseas.dbobject.conversion
|
||||
|
||||
The :mod:`conversion` module defines two classes, :class:`Conversion`
|
||||
and :class:`ConversionDict`, derived from :class:`DbSchemaObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Conversion
|
||||
----------
|
||||
|
||||
:class:`Conversion` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a `Postgres
|
||||
conversion between character set encodings
|
||||
<https://www.postgresql.org/docs/current/static/sql-createconversion.html>`_.
|
||||
|
||||
.. autoclass:: Conversion
|
||||
|
||||
.. automethod:: Conversion.to_map
|
||||
|
||||
.. automethod:: Conversion.create
|
||||
|
||||
Conversion Dictionary
|
||||
---------------------
|
||||
|
||||
:class:`ConversionDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of conversions in a database.
|
||||
|
||||
.. autoclass:: ConversionDict
|
||||
|
||||
.. automethod:: ConversionDict.from_map
|
||||
@@ -0,0 +1,90 @@
|
||||
Databases
|
||||
=========
|
||||
|
||||
.. module:: pyrseas.database
|
||||
|
||||
The :mod:`database` module defines class :class:`Database`.
|
||||
|
||||
Database
|
||||
--------
|
||||
|
||||
A :class:`Database` can be viewed as a tree of database objects. The
|
||||
tree may have one or two main branches. A tree with one main branch
|
||||
is used by :program:`dbtoyaml` to hold the representation of the
|
||||
database, as read from the Postgres catalogs. :program:`yamltodb`
|
||||
uses a second main branch to hold the representation as read from the
|
||||
YAML input specification.
|
||||
|
||||
Each main branch consists of multiple subtrees for different kinds of
|
||||
objects. For example, the Schemas (Postgres namespaces) subtree has
|
||||
all the Postgres schema objects, the Procedures subtree has all the
|
||||
Postgres functions and aggregates. The objects in the subtrees are
|
||||
connected in implicit or explicit manners to related objects. For
|
||||
example, the objects in the ``schema public`` are implicitly
|
||||
accessible from the corresponding :class:`Schema` object because they
|
||||
all share ``public`` as the first part of their internal key (see
|
||||
:meth:`DbObject.key`). As another example, a table has explicit
|
||||
links to constraints and indexes defined on it.
|
||||
|
||||
A :class:`Database` is initialized from a
|
||||
:class:`~pyrseas.database.CatDbConnection` object (a specialized class
|
||||
derived from :class:`~pyrseas.lib.dbconn.DbConnection`). It consists of
|
||||
one or two :class:`Dicts` (the main branches in the above
|
||||
discussion). A :class:`Dicts` object holds various dictionary objects
|
||||
derived from :class:`~pyrseas.dbobject.DbObjectDict`, e.g.,
|
||||
:class:`~pyrseas.dbobject.schema.SchemaDict`,
|
||||
:class:`~pyrseas.dbobject.table.ClassDict`, and
|
||||
:class:`~pyrseas.dbobject.column.ColumnDict`. The key for each
|
||||
dictionary is a Python tuple (or a single value in the case of
|
||||
:class:`SchemaDict` and other non-schema objects). For example, the
|
||||
:class:`~pyrseas.dbobject.table.ClassDict` dictionary is indexed by
|
||||
(`schema name`, `table name`)--in this context `table name` may
|
||||
actually be a `sequence name`, a `view name` or a `materialized view
|
||||
name`. In addition, object instances in each dictionary are linked to
|
||||
related objects in other dictionaries, e.g., columns are linked to the
|
||||
tables where they belong.
|
||||
|
||||
The :attr:`db` :class:`Dicts` object --always present-- instantiates
|
||||
the database schemas, including their tables and other objects, by
|
||||
querying the system catalogs. The :attr:`ndb` :class:`Dicts` object
|
||||
instantiates the schemas based on the :obj:`input_map` supplied to the
|
||||
:meth:`diff_map` method.
|
||||
|
||||
The :meth:`to_map` method returns and the :meth:`diff_map` method
|
||||
takes as input, a Python dictionary (equivalent to a YAML or JSON
|
||||
object) as shown below. It uses 'schema `schema_name`' as the key for
|
||||
each schema. The value corresponding to each 'schema `schema_name`' is
|
||||
another dictionary using 'sequences', 'tables', etc., as keys and more
|
||||
dictionaries as values. For example::
|
||||
|
||||
{'schema public':
|
||||
{'sequence seq1': { ... },
|
||||
'sequence seq2': { ... },
|
||||
'table t1': { ... },
|
||||
'table t2': { ... },
|
||||
'table t3': { ... },
|
||||
'view v1': { ... }
|
||||
},
|
||||
'schema s1': { ... },
|
||||
'schema s2': { ... }
|
||||
}
|
||||
|
||||
Refer to :class:`~pyrseas.dbobject.table.Sequence`,
|
||||
:class:`~pyrseas.dbobject.table.Table` and
|
||||
:class:`~pyrseas.dbobject.table.View` for details on the lower level
|
||||
dictionaries.
|
||||
|
||||
.. autoclass:: Database
|
||||
|
||||
Methods :meth:`from_catalog` and :meth:`from_map` are for internal
|
||||
use. Methods :meth:`to_map` and :meth:`diff_map` are the external API.
|
||||
|
||||
.. automethod:: Database.from_catalog
|
||||
|
||||
.. automethod:: Database.from_map
|
||||
|
||||
.. automethod:: Database.map_from_dir
|
||||
|
||||
.. automethod:: Database.to_map
|
||||
|
||||
.. automethod:: Database.diff_map
|
||||
@@ -0,0 +1,108 @@
|
||||
dbaugment - Augment a database
|
||||
==============================
|
||||
|
||||
Name
|
||||
----
|
||||
|
||||
dbaugment -- Augment a Postgres database in predefined ways
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
dbaugment [option...] dbname [spec]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
:program:`dbaugment` is a utility for augmenting a Postgres database
|
||||
with various standard attributes and procedures, such as automatically
|
||||
maintained audit columns. The augmentations are defined in a
|
||||
YAML-formatted ``spec`` file.
|
||||
|
||||
The following is an example of a specification file::
|
||||
|
||||
augmenter:
|
||||
columns:
|
||||
modified_date:
|
||||
not_null: true
|
||||
type: date
|
||||
schema public:
|
||||
table t1:
|
||||
audit_columns: default
|
||||
table t3:
|
||||
audit_columns: modified_only
|
||||
|
||||
The specification file lists each schema, and within it, each table to
|
||||
be augmented. Under each table the following values are currently
|
||||
recognized:
|
||||
|
||||
- audit_columns: This indicates that audit trail columns are to be
|
||||
added to the table, e.g., a timestamp column recording when a row
|
||||
was last modified.
|
||||
|
||||
The first section of the specification file, under the ``augmenter``
|
||||
header, lists configuration information. This is in addition to the
|
||||
built-in configuration objects (see :ref:`predef-aug`).
|
||||
|
||||
:program:`dbaugment` first reads the database catalogs. It also
|
||||
initializes itself from predefined configuration information.
|
||||
:program:`dbaugment` then reads the specification file, which may
|
||||
include additional configuration objects, and outputs a YAML file,
|
||||
including the existing catalog information together with the desired
|
||||
enhancements. The YAML file is suitable for input to
|
||||
:program:`yamltodb` to generate the SQL statements to implement the
|
||||
changes.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
:program:`dbaugment` accepts the following command-line arguments (in
|
||||
addition to the :doc:`cmdargs`):
|
||||
|
||||
**dbname**
|
||||
|
||||
Specifies the name of the database whose schema is to augmented.
|
||||
|
||||
**spec**
|
||||
|
||||
Location of the file with the augmenter specifications. If this
|
||||
is omitted, the specification is read from the program's standard
|
||||
input.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
To augment a database called ``moviesdb`` according to the
|
||||
specifications in the file ``movies.yaml``::
|
||||
|
||||
dbaugment moviesdb movies.yaml
|
||||
|
||||
To add a column named ``updated`` to table ``public.film`` to hold the
|
||||
date and time each row was inserted or updated, create a YAML
|
||||
specification file, say ``film.yaml`` as follows::
|
||||
|
||||
augmenter:
|
||||
columns:
|
||||
modified_timestamp:
|
||||
name: updated
|
||||
schema public:
|
||||
table film:
|
||||
audit_columns: modified_only
|
||||
|
||||
The first four lines configure the predefined ``modified_timestamp``
|
||||
audit column to use the name ``updated`` instead. The last three
|
||||
lines direct ``dbaugment`` to apply the predefined ``modified_only``
|
||||
audit column to the ``film`` table.
|
||||
|
||||
Then run the following command to generate the resulting database
|
||||
specification, alter the table and create the needed trigger and
|
||||
function.
|
||||
|
||||
dbaugment moviesdb film.yaml | yamltodb moviesdb -u
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
:ref:`predef-aug`
|
||||
@@ -0,0 +1,101 @@
|
||||
Database Objects
|
||||
================
|
||||
|
||||
.. module:: pyrseas.dbobject
|
||||
|
||||
The :mod:`dbobject` module defines two low-level classes and an
|
||||
intermediate class. Most Pyrseas classes are derived from either
|
||||
:class:`DbObject` or :class:`DbObjectDict`.
|
||||
|
||||
Database Object
|
||||
---------------
|
||||
|
||||
A :class:`DbObject` represents a database object such as a schema,
|
||||
table, or column, defined in a Postgres `system catalog
|
||||
<https://www.postgresql.org/docs/current/static/catalogs.html>`_. It is
|
||||
initialized from a dictionary of attributes. Derived classes should
|
||||
define a :attr:`keylist` that is a list of attribute names that
|
||||
uniquely identify each object instance within the database.
|
||||
|
||||
.. autoclass:: DbObject
|
||||
|
||||
.. autoattribute:: DbObject.objtype
|
||||
|
||||
.. autoattribute:: DbObject.keylist
|
||||
|
||||
.. automethod:: DbObject.key
|
||||
|
||||
The following methods are generally used to map objects for external
|
||||
output:
|
||||
|
||||
.. automethod:: DbObject.extern_key
|
||||
|
||||
.. automethod:: DbObject.query
|
||||
|
||||
.. automethod:: DbObject.extern_filename
|
||||
|
||||
.. automethod:: DbObject.identifier
|
||||
|
||||
.. automethod:: DbObject.to_map
|
||||
|
||||
.. automethod:: DbObject.map_privs
|
||||
|
||||
The following methods generate SQL statements from the object
|
||||
properties and sometimes from a second object:
|
||||
|
||||
.. automethod:: DbObject.comment
|
||||
|
||||
.. automethod:: DbObject.alter_owner
|
||||
|
||||
.. automethod:: DbObject.drop
|
||||
|
||||
.. automethod:: DbObject.rename
|
||||
|
||||
.. automethod:: DbObject.alter
|
||||
|
||||
.. automethod:: DbObject.diff_privileges
|
||||
|
||||
.. automethod:: DbObject.diff_description
|
||||
|
||||
|
||||
Database Object Dictionary
|
||||
--------------------------
|
||||
|
||||
A :class:`DbObjectDict` represents a collection of :class:`DbObject`'s
|
||||
and is derived from the Python built-in type :class:`dict`. If a
|
||||
:class:`~pyrseas.lib.dbconn.DbConnection` object is used for
|
||||
initialization, an internal method is called to initialize the
|
||||
dictionary from the database catalogs. The :class:`DbObjectDict`
|
||||
:meth:`fetch` method fetches all objects using the `query` method
|
||||
defined by derived classes. Derived classes should also define a
|
||||
:attr:`cls` attribute for the associated :class:`DbObject` class,
|
||||
e.g., :class:`~pyrseas.schema.SchemaDict` sets :attr:`cls` to
|
||||
:class:`~pyrseas.schema.Schema`.
|
||||
|
||||
.. autoclass:: DbObjectDict
|
||||
|
||||
.. autoattribute:: DbObjectDict.cls
|
||||
|
||||
.. automethod:: DbObjectDict.to_map
|
||||
|
||||
.. automethod:: DbObjectDict.fetch
|
||||
|
||||
|
||||
Schema Object
|
||||
-------------
|
||||
|
||||
A :class:`DbSchemaObject` is derived from :class:`DbObject`. It is
|
||||
used as a base class for objects owned by a schema and to define
|
||||
certain common methods. This is different from the
|
||||
:class:`~pyrseas.schema.Schema` that represents the schema (Postgres
|
||||
namespace) itself.
|
||||
|
||||
.. autoclass:: DbSchemaObject
|
||||
|
||||
.. automethod:: DbSchemaObject.identifier
|
||||
|
||||
.. automethod:: DbSchemaObject.qualname
|
||||
|
||||
.. automethod:: DbSchemaObject.unqualify
|
||||
|
||||
.. automethod:: DbSchemaObject.rename
|
||||
@@ -0,0 +1,293 @@
|
||||
dbtoyaml - Database to YAML
|
||||
===========================
|
||||
|
||||
Name
|
||||
----
|
||||
|
||||
dbtoyaml -- extract the schema of a Postgres database in YAML format
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
dbtoyaml [option...] dbname
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
:program:`dbtoyaml` is a utility for extracting the schema of a
|
||||
Postgres database to a `YAML <http://yaml.org>`_ formatted
|
||||
specification. By default, the specification is output as a single
|
||||
output stream, which can be redirected or explicitly sent to a file.
|
||||
As an alternative, the ``--multiple-files`` option allows you to break
|
||||
down the specification into multiple files, in general, one for each
|
||||
object (see `Multiple File Output`_).
|
||||
|
||||
Note that `JSON <http://json.org/>`_ is an official
|
||||
subset of YAML version 1.2, so the :program:`dbtoyaml` output should
|
||||
also be compatible with JSON tools.
|
||||
|
||||
A sample of the output format is as follows::
|
||||
|
||||
schema public:
|
||||
owner: postgres
|
||||
privileges:
|
||||
- postgres:
|
||||
- all
|
||||
- PUBLIC:
|
||||
- all
|
||||
table t1:
|
||||
check_constraints:
|
||||
t1_c2_check:
|
||||
columns:
|
||||
- c2
|
||||
expression: (c2 > 123)
|
||||
columns:
|
||||
- c1:
|
||||
not_null: true
|
||||
type: integer
|
||||
- c2:
|
||||
type: smallint
|
||||
- c3:
|
||||
default: 'false'
|
||||
type: boolean
|
||||
- c4:
|
||||
type: text
|
||||
foreign_keys:
|
||||
t1_c2_fkey:
|
||||
columns:
|
||||
- c2
|
||||
references:
|
||||
columns:
|
||||
- c21
|
||||
schema: s1
|
||||
table: t2
|
||||
owner: alice
|
||||
primary_key:
|
||||
t1_pkey:
|
||||
columns:
|
||||
- c1
|
||||
schema s1:
|
||||
owner: bob
|
||||
privileges:
|
||||
- bob:
|
||||
- all
|
||||
- alice:
|
||||
- all
|
||||
table t2:
|
||||
columns:
|
||||
- c21:
|
||||
not_null: true
|
||||
type: integer
|
||||
- c22:
|
||||
type: character varying(16)
|
||||
owner: bob
|
||||
primary_key:
|
||||
t2_pkey:
|
||||
columns:
|
||||
- c21
|
||||
privileges:
|
||||
- bob:
|
||||
- all
|
||||
- PUBLIC:
|
||||
- select
|
||||
- alice:
|
||||
- insert:
|
||||
grantable: true
|
||||
- delete:
|
||||
grantable: true
|
||||
- update:
|
||||
grantable: true
|
||||
- carol:
|
||||
grantor: alice
|
||||
privs:
|
||||
- insert
|
||||
|
||||
|
||||
The above should be mostly self-explanatory. The example database has
|
||||
two tables, named ``t1`` and ``t2``, the first --owned by user
|
||||
'alice'-- in the ``public`` schema and the second --owned by user
|
||||
'bob'-- in a schema named ``s1`` (also owned by 'bob').
|
||||
The ``columns:`` specifications directly under each table list each
|
||||
column in that table, in the same order as shown by Postgres. The
|
||||
specifications ``primary_key:``, ``foreign_keys:`` and
|
||||
``check_constraints:`` define PRIMARY KEY, FOREIGN KEY and CHECK
|
||||
constraints for a given table. Additional specifications (not shown)
|
||||
define unique constraints and indexes.
|
||||
|
||||
User 'bob' has granted all privileges to 'alice' on the ``s1`` schema.
|
||||
On table ``t2``, he also granted SELECT to PUBLIC; INSERT, UPDATE and
|
||||
DELETE to 'alice' with GRANT OPTION; and she has in turn granted
|
||||
INSERT to user 'carol'.
|
||||
|
||||
:program:`dbtoyaml` currently supports extracting information about
|
||||
nearly all types of Postgres database objects. See :ref:`api-ref`
|
||||
for a list of supported objects.
|
||||
|
||||
The behavior and options of ``dbtoyaml`` are patterned after the
|
||||
`pg_dump utility
|
||||
<https://www.postgresql.org/docs/current/static/app-pgdump.html>`_
|
||||
since it is most analogous to using ``pg_dump --schema-only``.
|
||||
|
||||
Multiple File Output
|
||||
--------------------
|
||||
|
||||
.. program:: dbtoyaml
|
||||
|
||||
The :option:`--multiple-files` option breaks down the output into
|
||||
multiple files under a given root directory. The root is created if
|
||||
it does not exist. The root directory name defaults to ``metadata``
|
||||
in the system configuration file. The location of the root directory
|
||||
defaults to the configuration item ``repository.path`` or can be
|
||||
specified using the `--repository` option (see :doc:`config`
|
||||
and :doc:`cmdargs` for further details).
|
||||
|
||||
The first level contains ``schema.<name>`` subdirectories,
|
||||
``schema.<name>.yaml`` files and ``<objtype>.<name>.yaml`` files,
|
||||
where ``<name>`` is the name of the corresponding objects and
|
||||
``<objtype>`` is the type of top-level (non-schema) object. Note that
|
||||
non-schema refers to Postgres extensions, casts, languages or
|
||||
foreign data wrappers.
|
||||
|
||||
The second level, i.e., the ``schema.<name>`` subdirectories contain
|
||||
``<objtype>.<name>.yaml`` files for each object in the particular
|
||||
schema (but see below for caveats).
|
||||
|
||||
Object Name Conflicts
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The names of Postgres objects can include characters that are not
|
||||
allowed in filesystem object names. The most common example is the
|
||||
division operator ('/'), but even table names can include
|
||||
non-alphanumeric characters, if the identifiers are quoted.
|
||||
|
||||
In addition, one can define two or more objects with the same base
|
||||
name, e.g., function ``foo(integer)`` and function ``foo(text)``, or a
|
||||
table named ``"My Table"`` and another named ``"my table"`` or
|
||||
``"MY TABLE"``. On certain operating systems, i.e., Windows, it is not
|
||||
possible to create two files in the same directory that differ only in
|
||||
the case of their characters.
|
||||
|
||||
In order to deal with the aforementioned issues, ``dbtoyaml`` places
|
||||
certain objects in common files and transforms object identifiers so
|
||||
that they are suitable for use in files and directories. For example,
|
||||
the information for all user-defined casts are written to the file
|
||||
``cast.yaml`` in the root directory. Functions with the same name but
|
||||
different arguments are written to a single file, e.g.,
|
||||
``function.foo.yaml`` in the first example above. Identifiers are
|
||||
also converted to all lowercase, non-alphanumeric characters
|
||||
(excluding underscore) are converted to underscores and, by default,
|
||||
schema object names are truncated to 32 characters.
|
||||
|
||||
If two object names, thus transformed, map to the same string, then
|
||||
the objects' information is written to the same file, e.g.,
|
||||
``table.my_table.yaml`` in the second example above. If you prefer to
|
||||
change the default truncation length, please define the environment
|
||||
variable ``PYRSEAS_MAX_IDENT_LEN`` to some integer value (up to 63).
|
||||
|
||||
Version Control and Dropped Objects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It is expected that the output of ``dbtoyaml --multiple-files`` will
|
||||
be placed under version control. Further invocations should then
|
||||
update the files in the same directory tree. However, if an object is
|
||||
dropped from the database ``dbtoyaml`` would normally only output
|
||||
files for new or changed objects--and thus keep the dropped object
|
||||
file under version control. To deal with dropped objects, ``dbtoyaml
|
||||
-m`` outputs a special YAML "index" file, named
|
||||
``database.<dbname>.yaml`` in the root directory. When ``dbtoyaml
|
||||
-m`` is run a second time, it looks for this "index" file and if
|
||||
found, proceeds to delete the previous run's ``.yaml`` files before
|
||||
outputting new ones.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
:program:`dbtoyaml` accepts the following command-line arguments (in
|
||||
addition to the :doc:`cmdargs`):
|
||||
|
||||
dbname
|
||||
|
||||
Specifies the name of the database whose schema is to be extracted.
|
||||
|
||||
.. cmdoption:: -m, --multiple-files
|
||||
|
||||
Extracts the schema to a two-level directory tree. See `Multiple
|
||||
File Output`_ above.
|
||||
|
||||
.. cmdoption:: -n <schema>
|
||||
--schema <schema>
|
||||
|
||||
Extracts only a schema matching `schema`. By default, all schemas
|
||||
are extracted. Multiple schemas can be extracted by using multiple
|
||||
``-n`` switches. Note that normally all objects that belong to the
|
||||
schema are extracted as well, unless excluded otherwise.
|
||||
|
||||
.. cmdoption:: -N <schema>
|
||||
--exclude-schema <schema>
|
||||
|
||||
Does not extract schema matching `schema`. This can be given more
|
||||
than once to exclude several schemas.
|
||||
|
||||
.. cmdoption:: -O, --no-owner
|
||||
|
||||
Do not output object ownership information. By default, as seen
|
||||
in the sample output above, database objects (schemas, tables,
|
||||
etc.) that can be owned by some user, are shown with an "owner:
|
||||
*username*" element. The :option:`-O` switch suppresses all those
|
||||
lines.
|
||||
|
||||
NOTE: If you specify `--no-owner`, you will most likely also want
|
||||
to specify :option:`--no-privileges`. If the former is used
|
||||
without the latter the resulting YAML output will have privilege
|
||||
information without user data, which will cause errors if the YAML
|
||||
is then fed to :doc:`yamltodb`.
|
||||
|
||||
.. cmdoption:: -t <table>
|
||||
--table <table>
|
||||
|
||||
Extract only tables matching `table`. Multiple tables can be
|
||||
extracted by using multiple :option:`-t` switches. Note that
|
||||
selecting a table may cause other objects, such as an owned
|
||||
sequence, to be extracted as well
|
||||
|
||||
.. cmdoption:: -T <table>
|
||||
--exclude-table <table>
|
||||
|
||||
Do not extract tables matching `table`. Multiple tables can be
|
||||
excluded by using multiple :option:`-T` switches.
|
||||
|
||||
.. cmdoption:: -x, --no-privileges
|
||||
|
||||
Do not output access privilege information. By default, as seen
|
||||
in the sample output above, if specific GRANTs have been issued on
|
||||
various objects (schemas, tables, etc.), the privileges are shown
|
||||
under each object. The :option:`-x` switch suppresses all those
|
||||
lines.
|
||||
|
||||
See also the NOTE under :option:`--no-owner`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
To extract a database called ``moviesdb`` into a file::
|
||||
|
||||
dbtoyaml moviesdb > moviesdb.yaml
|
||||
|
||||
To extract only the schema named ``store``::
|
||||
|
||||
dbtoyaml --schema=store moviesdb > moviesdb.yaml
|
||||
|
||||
To extract the tables named ``film`` and ``genre``::
|
||||
|
||||
dbtoyaml -t film -t genre moviesdb -o moviesdb.yaml
|
||||
|
||||
To extract objects, to standard output, except those in schemas
|
||||
``product`` and ``store``::
|
||||
|
||||
dbtoyaml -N product -N store moviesdb
|
||||
|
||||
To extract objects to a directory under version control::
|
||||
|
||||
dbtoyaml moviesdb -m movies/dbspec
|
||||
@@ -0,0 +1,97 @@
|
||||
.. _development:
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
The following details the tools needed to contribute to the
|
||||
development of Pyrseas. If you have any doubts or questions, please
|
||||
open an issue on GitHub (https://github.com/perseas/Pyrseas/issues).
|
||||
In addition, see *Version Control* below on how to set up a GitHub
|
||||
account to participate in development.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- Git
|
||||
|
||||
- Python
|
||||
|
||||
- Postgres
|
||||
|
||||
- Psycopg3
|
||||
|
||||
- PyYAML
|
||||
|
||||
- Tox
|
||||
|
||||
Version Control
|
||||
---------------
|
||||
|
||||
Pyrseas uses `Git <https://git-scm.com/>`_ to control changes to its
|
||||
source code. As mentioned under :ref:`download`, the master Git
|
||||
`repository <https://github.com/perseas/Pyrseas>`_ is located at GitHub.
|
||||
|
||||
To install Git, either `download and install
|
||||
<https://git-scm.com/download>`_ the latest stable release for your
|
||||
platform or follow the `Pro Git` `installation instructions
|
||||
<https://git-scm.com/book/en/Getting-Started-Installing-Git>`_. For
|
||||
most Linux users, ``apt-get`` or ``yum`` (depending on Linux flavor)
|
||||
will be the simplest means to install the ``git-core`` package. For
|
||||
Windows, downloading the installer and selecting ``Git Bash`` gives
|
||||
you not only Git but a Bash shell, which is handy if you're coming
|
||||
from a Linux/Unix background.
|
||||
|
||||
Once Git is installed, change to a suitable directory and clone the
|
||||
master repository::
|
||||
|
||||
git clone https://github.com/perseas/Pyrseas.git
|
||||
|
||||
To be able to create a fork on GitHub, open an issue or participate in
|
||||
Pyrseas development, you'll first have to `create a GitHub account
|
||||
<https://github.com/join>`_.
|
||||
|
||||
Programming Language
|
||||
--------------------
|
||||
|
||||
To contribute to Pyrseas, you need a version of `Python
|
||||
<https://www.python.org>`_. You can develop using Python 3.7 or higher.
|
||||
|
||||
If Python is not already available on your machine, either `download
|
||||
and install one or both <https://www.python.org/downloads/>`_ of the
|
||||
production releases for your platform, follow the applicable
|
||||
installation instructions given in `The Hitchhiker’s Guide to Python!
|
||||
<http://docs.python-guide.org/en/latest/>`_ or install it from your
|
||||
platform's package management system.
|
||||
|
||||
Database Installation
|
||||
---------------------
|
||||
|
||||
To participate in Pyrseas development, you'll also need one or more
|
||||
installations of `Postgres <https://www.postgresql.org>`_, versions
|
||||
13, 12, 11 or 10. If you only have limited space, it is
|
||||
preferable to install one of the latest two versions.
|
||||
|
||||
The versions can be obtained as binary packages or installers from the
|
||||
`Postgres.org website <https://www.postgresql.org/download/>`_. The
|
||||
site also includes instructions for installing from package management
|
||||
systems or building it from source.
|
||||
|
||||
To access Postgres from Python, you have to install the `Psycopg
|
||||
<https://www.psycopg.org/>`_ version 3 adapter. You can either follow the
|
||||
instructions in `Psycopg's site
|
||||
<https://www.psycopg.org/psycopg3/docs/basic/install.html>`_, or install it from
|
||||
your package management system.
|
||||
|
||||
Other Libraries and Tools
|
||||
-------------------------
|
||||
|
||||
The ``dbtoyaml`` and ``yamltodb`` utilities use the `PyYAML
|
||||
<http://pyyaml.org/wiki/PyYAML>`_ library. You can install it from
|
||||
the PyYAML site, or possibly from your package management system. For
|
||||
Windows 64-bit, please read the note under :ref:`installer`.
|
||||
|
||||
To easily run the Pyrseas tests against various Python/Postgres
|
||||
version combinations, you will need `pytest
|
||||
<https://pytest.readthedocs.io/en/latest/>`_ and `Tox
|
||||
<https://tox.readthedocs.io/en/latest/>`_. Please refer to
|
||||
:ref:`testing` for more information.
|
||||
@@ -0,0 +1,33 @@
|
||||
Event Triggers
|
||||
==============
|
||||
|
||||
.. module:: pyrseas.dbobject.eventtrig
|
||||
|
||||
The :mod:`eventtrig` module defines two classes, :class:`EventTrigger` and
|
||||
:class:`EventTriggerDict`, derived from :class:`DbObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Event Trigger
|
||||
--------------
|
||||
|
||||
:class:`EventTrigger` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObject` and represents an `event trigger
|
||||
<https://www.postgresql.org/docs/current/static/event-triggers.html>`_
|
||||
available from Postgres 9.3 onwards.
|
||||
|
||||
.. autoclass:: EventTrigger
|
||||
|
||||
.. automethod:: EventTrigger.to_map
|
||||
|
||||
.. automethod:: EventTrigger.create
|
||||
|
||||
Event Trigger Dictionary
|
||||
------------------------
|
||||
|
||||
:class:`EventTriggerDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of event triggers in a database.
|
||||
|
||||
.. autoclass:: EventTriggerDict
|
||||
|
||||
.. automethod:: EventTriggerDict.from_map
|
||||
@@ -0,0 +1,33 @@
|
||||
Extensions
|
||||
==========
|
||||
|
||||
.. module:: pyrseas.dbobject.extension
|
||||
|
||||
The :mod:`extension` module defines two classes, :class:`Extension`
|
||||
and :class:`ExtensionDict`, derived from :class:`DbObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Extension
|
||||
---------
|
||||
|
||||
:class:`Extension` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObject` and represents a `Postgres
|
||||
extension
|
||||
<https://www.postgresql.org/docs/current/static/extend-extensions.html>`_.
|
||||
|
||||
.. autoclass:: Extension
|
||||
|
||||
.. automethod:: Extension.create
|
||||
|
||||
.. automethod:: Extension.alter
|
||||
|
||||
Extension Dictionary
|
||||
--------------------
|
||||
|
||||
:class:`ExtensionDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of extensions in a database.
|
||||
|
||||
.. autoclass:: ExtensionDict
|
||||
|
||||
.. automethod:: ExtensionDict.from_map
|
||||
@@ -0,0 +1,142 @@
|
||||
Foreign Data Objects
|
||||
====================
|
||||
|
||||
.. module:: pyrseas.dbobject.foreign
|
||||
|
||||
The :mod:`foreign` module defines nine classes related to Postgres
|
||||
foreign data wrappers (FDWs), namely: :class:`DbObjectWithOptions`
|
||||
derived from :class:`DbObject`, classes :class:`ForeignDataWrapper`,
|
||||
:class:`ForeignServer` and :class:`UserMapping` derived from
|
||||
:class:`DbObjectWithOptions`, :class:`ForeignTable` derived from
|
||||
:class:`DbObjectWithOptions` and :class:`Table`, classes
|
||||
:class:`ForeignDataWrapperDict`, :class:`ForeignServerDict` and
|
||||
:class:`UserMappingDict` derived from :class:`DbObjectDict`, and
|
||||
:class:`ForeignTableDict` derived from :class:`ClassDict`.
|
||||
|
||||
Database Object With Options
|
||||
----------------------------
|
||||
|
||||
:class:`DbObjectWithOptions` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObject`. It is a helper class for dealing
|
||||
with the OPTIONS clauses common to the foreign data objects.
|
||||
|
||||
.. autoclass:: DbObjectWithOptions
|
||||
|
||||
.. automethod:: DbObjectWithOptions.to_map
|
||||
|
||||
.. automethod:: DbObjectWithOptions.options_clause
|
||||
|
||||
.. automethod:: DbObjectWithOptions.diff_options
|
||||
|
||||
.. automethod:: DbObjectWithOptions.alter
|
||||
|
||||
Foreign Data Wrapper
|
||||
--------------------
|
||||
|
||||
:class:`ForeignDataWrapper` is derived from `DbObjectWithOptions` and
|
||||
represents a `Postgres foreign data wrapper
|
||||
<https://www.postgresql.org/docs/current/static/sql-createforeigndatawrapper.html>`_.
|
||||
See also `Foreign Data
|
||||
<https://www.postgresql.org/docs/current/static/ddl-foreign-data.html>`_
|
||||
and `Writing A Foreign Data Wrapper
|
||||
<https://www.postgresql.org/docs/current/static/fdwhandler.html>`_.
|
||||
|
||||
.. autoclass:: ForeignDataWrapper
|
||||
|
||||
.. automethod:: ForeignDataWrapper.to_map
|
||||
|
||||
.. automethod:: ForeignDataWrapper.create
|
||||
|
||||
Foreign Data Wrapper Dictionary
|
||||
-------------------------------
|
||||
|
||||
:class:`ForeignDataWrapperDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of foreign data wrappers in a database.
|
||||
|
||||
.. autoclass:: ForeignDataWrapperDict
|
||||
|
||||
.. automethod:: ForeignDataWrapperDict.from_map
|
||||
|
||||
Foreign Server
|
||||
--------------
|
||||
|
||||
:class:`ForeignServer` is derived from :class:`DbObjectWithOptions`
|
||||
and represents a `Postgres foreign server
|
||||
<https://www.postgresql.org/docs/current/static/sql-createserver.html>`_.
|
||||
|
||||
.. autoclass:: ForeignServer
|
||||
|
||||
.. automethod:: ForeignServer.identifier
|
||||
|
||||
.. automethod:: ForeignServer.to_map
|
||||
|
||||
.. automethod:: ForeignServer.create
|
||||
|
||||
Foreign Server Dictionary
|
||||
-------------------------
|
||||
|
||||
:class:`ForeignServerDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a Python dictionary
|
||||
that represents the collection of foreign servers in a database.
|
||||
|
||||
.. autoclass:: ForeignServerDict
|
||||
|
||||
.. automethod:: ForeignServerDict.from_map
|
||||
|
||||
.. automethod:: ForeignServerDict.to_map
|
||||
|
||||
User Mapping
|
||||
------------
|
||||
|
||||
:class:`UserMapping` is derived from :class:`DbObjectWithOptions` and
|
||||
represents a `mapping of a Postgres user to a foreign server
|
||||
<https://www.postgresql.org/docs/current/static/sql-createusermapping.html>`_.
|
||||
|
||||
.. autoclass:: UserMapping
|
||||
|
||||
.. automethod:: UserMapping.extern_key
|
||||
|
||||
.. automethod:: UserMapping.identifier
|
||||
|
||||
.. automethod:: UserMapping.create
|
||||
|
||||
User Mapping Dictionary
|
||||
-----------------------
|
||||
|
||||
:class:`UserMappingDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of user mappings in a database.
|
||||
|
||||
.. autoclass:: UserMappingDict
|
||||
|
||||
.. automethod:: UserMappingDict.from_map
|
||||
|
||||
.. automethod:: UserMappingDict.to_map
|
||||
|
||||
Foreign Table
|
||||
-------------
|
||||
|
||||
:class:`ForeignTable` is derived from :class:`DbObjectWithOptions` and
|
||||
:class:`~pyrseas.dbobject.table.Table`. It represents a `Postgres
|
||||
foreign table
|
||||
<https://www.postgresql.org/docs/current/static/sql-createforeigntable.html>`_.
|
||||
|
||||
.. autoclass:: ForeignTable
|
||||
|
||||
.. automethod:: ForeignTable.to_map
|
||||
|
||||
.. automethod:: ForeignTable.create
|
||||
|
||||
.. automethod:: ForeignTable.drop
|
||||
|
||||
Foreign Table Dictionary
|
||||
------------------------
|
||||
|
||||
:class:`ForeignTableDict` is derived from
|
||||
:class:`~pyrseas.dbobject.table.ClassDict`. It is a dictionary that
|
||||
represents the collection of foreign tables in a database.
|
||||
|
||||
.. autoclass:: ForeignTableDict
|
||||
|
||||
.. automethod:: ForeignTableDict.from_map
|
||||
@@ -0,0 +1,65 @@
|
||||
Functions
|
||||
=========
|
||||
|
||||
.. module:: pyrseas.dbobject.function
|
||||
|
||||
The :mod:`function` module defines four classes: class :class:`Proc`
|
||||
derived from :class:`DbSchemaObject`, classes :class:`Function` and
|
||||
:class:`Aggregate` derived from :class:`Proc`, and class
|
||||
:class:`ProcDict` derived from :class:`DbObjectDict`.
|
||||
|
||||
Procedure
|
||||
---------
|
||||
|
||||
Class :class:`Proc` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a regular or
|
||||
aggregate function.
|
||||
|
||||
.. autoclass:: Proc
|
||||
|
||||
.. automethod:: Proc.extern_key
|
||||
|
||||
.. automethod:: Proc.identifier
|
||||
|
||||
Function
|
||||
--------
|
||||
|
||||
:class:`Function` is derived from :class:`Proc` and represents a
|
||||
`Postgres user-defined function
|
||||
<https://www.postgresql.org/docs/current/static/xfunc.html>`_.
|
||||
|
||||
|
||||
.. autoclass:: Function
|
||||
|
||||
.. automethod:: Function.to_map
|
||||
|
||||
.. automethod:: Function.create
|
||||
|
||||
.. automethod:: Function.alter
|
||||
|
||||
.. automethod:: Function.drop
|
||||
|
||||
Aggregate Function
|
||||
------------------
|
||||
|
||||
:class:`Aggregate` is derived from :class:`Proc` and represents a
|
||||
`Postgres user-defined aggregate function
|
||||
<https://www.postgresql.org/docs/current/static/sql-createaggregate.html>`_.
|
||||
|
||||
.. autoclass:: Aggregate
|
||||
|
||||
.. automethod:: Aggregate.to_map
|
||||
|
||||
.. automethod:: Aggregate.create
|
||||
|
||||
Procedure Dictionary
|
||||
--------------------
|
||||
|
||||
:class:`ProcDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of regular and aggregate functions in a
|
||||
database.
|
||||
|
||||
.. autoclass:: ProcDict
|
||||
|
||||
.. automethod:: ProcDict.from_map
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
Pyrseas
|
||||
=======
|
||||
|
||||
Pyrseas provides utilities to describe a PostgreSQL database schema as
|
||||
YAML, to verify the schema against the same or a different database
|
||||
and to generate SQL that will modify the schema to match the YAML
|
||||
description.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Outputs a YAML/JSON description of a PostgreSQL database's tables
|
||||
and other objects (metadata), suitable for storing in a version
|
||||
control repository
|
||||
|
||||
- Generates SQL statements to modify a database so that it will match
|
||||
an input YAML/JSON specification
|
||||
|
||||
- Generates an augmented YAML description of a PostgreSQL database
|
||||
from its catalogs and an augmentation specification.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- `PostgreSQL <https://www.postgresql.org/>`_ 10 or higher
|
||||
|
||||
- `Python <https://www.python.org/>`_ 3.7 or higher
|
||||
|
||||
- `Psycopg3 <https://www.psycopg.org/psycopg3/>`_ 3.1 or higher
|
||||
|
||||
- `PyYAML <https://pyyaml.org/>`_ 5.3 or higher
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
overview
|
||||
install
|
||||
config
|
||||
configitems
|
||||
devel
|
||||
testing
|
||||
issues
|
||||
predefaug
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
dbaugment
|
||||
dbtoyaml
|
||||
yamltodb
|
||||
cmdargs
|
||||
|
||||
.. _api-ref:
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
Currently, the only external APIs are the class
|
||||
:class:`~pyrseas.database.Database` and the methods
|
||||
:meth:`~pyrseas.database.Database.to_map` and
|
||||
:meth:`~pyrseas.database.Database.diff_map` of the latter. Other
|
||||
classes and methods are documented mainly for developer use.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
dbobject
|
||||
database
|
||||
schema
|
||||
|
||||
Non-schema Objects
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
cast
|
||||
eventtrig
|
||||
extension
|
||||
foreign
|
||||
language
|
||||
|
||||
Tables and Related Objects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
table
|
||||
column
|
||||
constraint
|
||||
indexes
|
||||
rule
|
||||
|
||||
Functions, Operators and Triggers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
function
|
||||
operator
|
||||
operfamily
|
||||
operclass
|
||||
trigger
|
||||
|
||||
Types and Other Schema Objects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
collation
|
||||
conversion
|
||||
textsearch
|
||||
type
|
||||
|
||||
Augmenter API Reference
|
||||
-----------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
augmentdb
|
||||
cfgobjects
|
||||
augobjects
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
@@ -0,0 +1,43 @@
|
||||
Indexes
|
||||
=======
|
||||
|
||||
.. module:: pyrseas.dbobject.index
|
||||
|
||||
The :mod:`index` module defines two classes, :class:`Index` and
|
||||
:class:`IndexDict`, derived from :class:`DbSchemaObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
Class :class:`Index` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents an index on a
|
||||
database table, other than a primary key or unique constraint
|
||||
index. Its :attr:`keylist` attributes are the schema name, the table
|
||||
name and the index name. Note that index names are supposed to be
|
||||
unique with a given schema so the table name doesn't have to be part
|
||||
of the :attr:`keylist`, but has been retained to facilitate certain
|
||||
operations.
|
||||
|
||||
.. autoclass:: Index
|
||||
|
||||
.. automethod:: Index.key_expressions
|
||||
|
||||
.. automethod:: Index.to_map
|
||||
|
||||
.. automethod:: Index.create
|
||||
|
||||
.. automethod:: Index.alter
|
||||
|
||||
.. automethod:: Index.drop
|
||||
|
||||
Index Dictionary
|
||||
----------------
|
||||
|
||||
Class :class:`IndexDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict` and represents the collection
|
||||
of indexes in a database.
|
||||
|
||||
.. autoclass:: IndexDict
|
||||
|
||||
.. automethod:: IndexDict.from_map
|
||||
@@ -0,0 +1,182 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
For the latest release, use::
|
||||
|
||||
pip install Pyrseas
|
||||
|
||||
For development::
|
||||
|
||||
git clone git://github.com/perseas/Pyrseas.git
|
||||
cd Pyrseas
|
||||
python setup.py install
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Pyrseas provides tools for `Postgres <https://www.postgresql.org>`_,
|
||||
so obviously you need **Postgres** to start with. Pyrseas has been
|
||||
tested with PG 10, 11, 12 and 13 and we'll certainly keep up
|
||||
with future releases. Please refer to the `Postgres download page
|
||||
<https://www.postgresql.org/download>`_ to find a distribution for the
|
||||
various Linux, Unix and Windows platforms supported.
|
||||
|
||||
You will also need **Python**. Pyrseas was originally developed using
|
||||
`Python <http://www.python.org>` 2 and then ported to Python 3 and
|
||||
tested against versions from 3.7 through 3.9. On Linux or \*BSD,
|
||||
Python may already be part of your distribution or may be available as
|
||||
a package. For Windows and Mac OS please refer to the `Python
|
||||
download page <http://www.python.org/downloads/>`_ for installers and
|
||||
instructions.
|
||||
|
||||
Pyrseas talks to the Postgres DBMS via the **Psycopg adapter**.
|
||||
Pyrseas has been tested with `psycopg <https://www.psycopg.org/psycopg3/>`_
|
||||
3.1. Psycopg may be available as a package on most Linux or
|
||||
\*BSD distributions and can also be downloaded or installed from PyPI.
|
||||
Please refer to the `Psycopg download page
|
||||
<http://www.psycopg.org/psycopg3/docs/basic/install.html>`_ for more details.
|
||||
|
||||
.. note:: If you install Pyrseas using ``pip`` (see below) and you
|
||||
have not already installed Psycopg, e.g., when installing into a
|
||||
``virtualenv`` environment created with ``--no-site-packages``, you
|
||||
may need to have installed the Postgres and Python development
|
||||
packages, and a C compiler, as ``pip`` may download and attempt to
|
||||
build and install psycopg before installing Pyrseas.
|
||||
|
||||
The Pyrseas utilities rely on **PyYAML**, a `YAML <https://yaml.org>`_
|
||||
library. This may be available as a package for your operating system
|
||||
or it can be downloaded from the `Python Package Index (PyPI)
|
||||
<https://pypi.org/project/PyYAML/>`_.
|
||||
|
||||
.. _download:
|
||||
|
||||
Downloading
|
||||
-----------
|
||||
|
||||
Pyrseas is available at the following locations:
|
||||
|
||||
- `Python Package Index <https://pypi.org/project/Pyrseas>`_
|
||||
- `Postgres Extension Network (PGXN) <https://pgxn.org/dist/pyrseas/>`_
|
||||
- `GitHub repository <https://github.com/perseas/Pyrseas>`_
|
||||
|
||||
You can download the distribution from PyPI in gzip-compressed tar or
|
||||
ZIP archive format, but you can download *and* install it using
|
||||
``Pip``. See `Python Installer`_ below for details.
|
||||
|
||||
PGXN provides a ZIP archive which you can download or you can download
|
||||
*and* install using the PGXN client (see `PGXN Client`_ below).
|
||||
|
||||
The GitHub repository holds the Pyrseas source code, tagged according
|
||||
to the various releases, e.g., v0.9.0, and including unreleased
|
||||
modifications. To access it, you need `Git <https://git-scm.com/>`_
|
||||
which is available as a package in most OS distributions or can be
|
||||
downloaded from the `Git download page
|
||||
<https://git-scm.com/download>`_. You can fetch the Pyrseas sources by
|
||||
issuing the following command::
|
||||
|
||||
git clone https://github.com/perseas/Pyrseas.git
|
||||
|
||||
This will create a ``Pyrseas`` directory tree (you can use a different
|
||||
target name by adding it to the above commands). To list available
|
||||
releases, change to the subdirectory and invoke ``git tag``. To
|
||||
switch to a particular release, use::
|
||||
|
||||
git checkout vn.n.n
|
||||
|
||||
where *vn.n.n* is the release identifier. Use ``git checkout master``
|
||||
to revert to the main (master) branch. To fetch the latest updates,
|
||||
use::
|
||||
|
||||
git pull
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Extracting Sources
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once you have downloaded an archive from PyPI or PGXN, you need to
|
||||
extract the sources. For a gzip-compressed tar file, use::
|
||||
|
||||
tar xzf Pyrseas-n.n.n.tar.gz
|
||||
|
||||
where *n.n.n* is the release version. For a ZIP archive, use::
|
||||
|
||||
unzip Pyrseas-n.n.n.zip
|
||||
|
||||
Both commands above will create a directory ``Pyrseas-n.n.n`` and you
|
||||
will want to ``cd`` to it before proceeding with the installation.
|
||||
|
||||
Installing
|
||||
~~~~~~~~~~
|
||||
|
||||
If you have superuser or similar administrative privileges, you can
|
||||
install Pyrseas for access by multiple users on your system. On Linux
|
||||
and other Unix-flavored systems, you can install from the extracted
|
||||
``Pyrseas-n.n.n`` source directory or from the root directory of the
|
||||
``git`` clone, using the following command::
|
||||
|
||||
sudo python setup.py install
|
||||
|
||||
That will install the :doc:`dbtoyaml </dbtoyaml>` and :doc:`yamltodb
|
||||
</yamltodb>` utility scripts in a directory such as
|
||||
``/usr/local/bin``. The library sources and bytecode files will be
|
||||
placed in a ``pyrseas`` subdirectory under ``site-packages`` or
|
||||
``dist-packages``, e.g.,
|
||||
``/usr/local/lib/python3.6/dist-packages/pyrseas``.
|
||||
|
||||
On Windows, from an account with Administrator privileges, you can
|
||||
use::
|
||||
|
||||
python setup.py install
|
||||
|
||||
That will install the Pyrseas utilities in the ``Scripts`` folder of
|
||||
your Python installation. The source and bytecode files will go in
|
||||
the ``site-packages`` folder, e.g.,
|
||||
``C:\Python37\Lib\site-packages\pyrseas``.
|
||||
|
||||
.. _installer:
|
||||
|
||||
Python Installer
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
You can also download and install Pyrseas using `pip
|
||||
<https://pypi.org/project/pip/>`_. For example, on Linux do::
|
||||
|
||||
sudo pip install Pyrseas
|
||||
|
||||
If this is the first time you are installing a Python package, please
|
||||
do yourself a favor and read and follow the instructions in the
|
||||
"Distribute & Pip" subsection of the "Installing Python on ..."
|
||||
section for your platform of the `The Hitchhiker’s Guide to Python!
|
||||
<http://docs.python-guide.org/en/latest/index.html>`_.
|
||||
|
||||
.. note:: On FreeBSD, it has been reported that it is necessary to
|
||||
install the Python ``distribute`` package, prior to
|
||||
installing Pyrseas with ``pip``. This may also be necessary
|
||||
on other BSD variants.
|
||||
|
||||
.. note:: On Windows 64-bit, it has been reported that it is necessary
|
||||
to obtain unofficial versions of the ``distribute`` and
|
||||
``PyYAML`` packages, available at `University of California,
|
||||
Irvine <https://www.lfd.uci.edu/~gohlke/pythonlibs/>`_. For
|
||||
a detailed tutorial, see `this post
|
||||
<http://dbadailystuff.com/2012/07/04/install-pyrseas-in-windows/>`_.
|
||||
|
||||
``Pip`` can also be used in a Python `virtualenv
|
||||
<http://virtualenv.pypa.io/en/latest/>`_ environment, in which case
|
||||
you *don't* need to prefix the commands with ``sudo``.
|
||||
|
||||
``Pip`` also provides the ability to uninstall Pyrseas.
|
||||
|
||||
PGXN Client
|
||||
~~~~~~~~~~~
|
||||
|
||||
The PGXN `client <https://pypi.org/project/pgxnclient/>`_ (available
|
||||
at PyPI) can be used to download and install Pyrseas from PGXN. Usage
|
||||
is::
|
||||
|
||||
pgxn install pyrseas
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
Known Issues
|
||||
============
|
||||
|
||||
The following summarizes notable deficiencies in the current release
|
||||
of the Pyrseas utilities. For further details please refer to the
|
||||
discussions in the `Pyrseas issue tracker
|
||||
<https://github.com/perseas/Pyrseas/issues>`_. Suggestions or patches
|
||||
to deal with these issues are welcome.
|
||||
|
||||
Coverage of Postgres Objects
|
||||
----------------------------
|
||||
|
||||
An important Pyrseas objective is to support creating, altering or
|
||||
dropping nearly any Postgres object accessible through SQL, including
|
||||
adding, modifying or removing any attributes or features of those
|
||||
objects. At present, we believe Pyrseas covers roughly over 90% of
|
||||
the Postgres object/attribute universe. Please refer to the `Feature
|
||||
Matrix <https://pyrseas.wordpress.com/feature-matrix/>`_ for details.
|
||||
|
||||
This is a continuing effort since Postgres keeps adding new features
|
||||
in each release, such as the table PARTITIONING syntax in PG 10. We
|
||||
have documented current limitations in the issue tracker, see, for
|
||||
example, issues `135 <https://github.com/perseas/Pyrseas/issues/135>`_
|
||||
and `178 <https://github.com/perseas/Pyrseas/issues/178>`_. Please
|
||||
open an issue on the tracker if you find objects or features needing
|
||||
additional support.
|
||||
|
||||
Object Dependencies
|
||||
-------------------
|
||||
|
||||
The first releases of :program:`yamltodb` used a generally fixed
|
||||
traversal order when generating SQL. This caused problems with
|
||||
complex dependencies between objects (e.g., views that depended on
|
||||
functions that depended on types). Release 0.8 introduced a
|
||||
topological sort of objects based on their dependencies. The
|
||||
resulting dependency graph is now used to drive SQL generation. This
|
||||
should eliminate most object dependency problems seen with the
|
||||
previous architecture. However, certain issues still remain.
|
||||
Specifically, if an object depends on a Postgres internally-defined
|
||||
object, or on an object defined by a Postgres extension, the Pyrseas
|
||||
utilities may not behave as expected (see issue `175
|
||||
<https://github.com/perseas/Pyrseas/issues/175>`_ for additional
|
||||
discussion).
|
||||
|
||||
Object renaming
|
||||
---------------
|
||||
|
||||
Pyrseas provides support for generating SQL statements to rename
|
||||
various database objects, e.g., ALTER TABLE t1 RENAME TO t2, using an
|
||||
'oldname' tag which can be added to objects that support SQL RENAME.
|
||||
The tag has to be added manually to a YAML specification for yamltodb
|
||||
to act on it and cannot be kept in the YAML file for subsequent runs.
|
||||
This is not entirely satisfactory for storing the YAML file in a
|
||||
version control system.
|
||||
|
||||
Memory utilization
|
||||
------------------
|
||||
|
||||
The yamltodb utility compares the existing and input metadata by
|
||||
constructing parallel, in-memory representations of the database
|
||||
catalogs and the input YAML specification. If the database has a
|
||||
large number of objects, e.g., in the thousands of tables, the
|
||||
utility's memory usage may be noticeable.
|
||||
|
||||
|
||||
Multiline Strings
|
||||
-----------------
|
||||
|
||||
The text of function source code, view definitions or object COMMENTs
|
||||
present a problem when they span multiple lines. The default YAML
|
||||
output format is to enclose the entire string in double quotes, to
|
||||
show newlines that are part of the text as escaped characters (i.e.,
|
||||
``\n``) and to break the text into lines with a
|
||||
backslash-newline-indentation-backslash pattern. For example::
|
||||
|
||||
source: "\n SELECT inventory_id\n FROM inventory\n WHERE film_id =\
|
||||
\ $1\n AND store_id = $2\n AND inventory_in_stock(inventory_id);\n"
|
||||
|
||||
This is not very readable, but it does allow YAML to read it back and
|
||||
correctly reconstruct the original string. To improve readability,
|
||||
Pyrseas 0.7 introduced special processing for these strings. By using
|
||||
YAML notation, the same string is represented as follows::
|
||||
|
||||
source: |2
|
||||
|
||||
SELECT inventory_id
|
||||
FROM inventory
|
||||
WHERE film_id = $1
|
||||
AND store_id = $2
|
||||
AND NOT inventory_in_stock(inventory_id);
|
||||
|
||||
Note also that if your function source code has trailing spaces at the
|
||||
end of lines, they would normally be represented in the original
|
||||
default format. However, in the interest of readability,
|
||||
:program:`dbtoyaml` will remove the trailing spaces from the text.
|
||||
|
||||
Index and Partitioning Expressions
|
||||
----------------------------------
|
||||
|
||||
Postgres allows users to create `indexes using expressions
|
||||
<https://www.postgresql.org/docs/current/static/indexes-expressional.html>`_.
|
||||
A user can also mix expressions with regular columns. The Postgres
|
||||
catalogs store the index information in a bespoke fashion: an array of
|
||||
column numbers where a zero indicates an expression and a list of
|
||||
expression trees (an internal format) for the expressions, with
|
||||
additional arrays for collation information, operator classes and
|
||||
index options such as ``ASC`` or ``DESC``. Although the
|
||||
``pg_get_indexdef`` system catalog function can be used to obtain a
|
||||
full ``CREATE INDEX`` statement, Pyrseas has chosen to specify each
|
||||
column or expression separately in the YAML definitions. This has
|
||||
not been satisfactory in complex cases (see for example issue `170
|
||||
<https://github.com/perseas/Pyrseas/issues/170>`_) and is an area
|
||||
requiring further attention. A similar situation exists for table
|
||||
partitioning using expressions.
|
||||
@@ -0,0 +1,35 @@
|
||||
Procedural Languages
|
||||
====================
|
||||
|
||||
.. module:: pyrseas.dbobject.language
|
||||
|
||||
The :mod:`language` module defines two classes, :class:`Language` and
|
||||
:class:`LanguageDict`, derived from :class:`DbObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Procedural Language
|
||||
-------------------
|
||||
|
||||
:class:`Language` is derived from :class:`~pyrseas.dbobject.DbObject`
|
||||
and represents a procedural language.
|
||||
|
||||
|
||||
.. autoclass:: Language
|
||||
|
||||
.. automethod:: Language.to_map
|
||||
|
||||
.. automethod:: Language.drop
|
||||
|
||||
.. automethod:: Language.create
|
||||
|
||||
Language Dictionary
|
||||
-------------------
|
||||
|
||||
:class:`LanguageDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of procedural languages in a
|
||||
database. Internal languages ('internal', 'c' and 'sql') are excluded.
|
||||
|
||||
.. autoclass:: LanguageDict
|
||||
|
||||
.. automethod:: LanguageDict.from_map
|
||||
@@ -0,0 +1,36 @@
|
||||
Operators
|
||||
=========
|
||||
|
||||
.. module:: pyrseas.dbobject.operator
|
||||
|
||||
The :mod:`operator` module defines two classes: class
|
||||
:class:`Operator` derived from :class:`DbSchemaObject` and class
|
||||
:class:`OperatorDict` derived from :class:`DbObjectDict`.
|
||||
|
||||
Operator
|
||||
---------
|
||||
|
||||
:class:`Operator` is derived from :class:`DbSchemaObject` and
|
||||
represents a `Postgres user-defined operator
|
||||
<https://www.postgresql.org/docs/current/static/xoper.html>`_.
|
||||
|
||||
.. autoclass:: Operator
|
||||
|
||||
.. automethod:: Operator.extern_key
|
||||
|
||||
.. automethod:: Operator.qualname
|
||||
|
||||
.. automethod:: Operator.identifier
|
||||
|
||||
.. automethod:: Operator.create
|
||||
|
||||
Operator Dictionary
|
||||
-------------------
|
||||
|
||||
:class:`OperatorDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of operators in a database.
|
||||
|
||||
.. autoclass:: OperatorDict
|
||||
|
||||
.. automethod:: OperatorDict.from_map
|
||||
@@ -0,0 +1,36 @@
|
||||
Operator Classes
|
||||
================
|
||||
|
||||
.. module:: pyrseas.dbobject.operclass
|
||||
|
||||
The :mod:`operclass` module defines two classes: class
|
||||
:class:`OperatorClass` derived from :class:`DbSchemaObject` and class
|
||||
:class:`OperatorClassDict` derived from :class:`DbObjectDict`.
|
||||
|
||||
Operator Class
|
||||
--------------
|
||||
|
||||
:class:`OperatorClass` is derived from :class:`DbSchemaObject` and
|
||||
represents a `Postgres operator class
|
||||
<https://www.postgresql.org/docs/current/static/sql-createopclass.html>`_.
|
||||
|
||||
.. autoclass:: OperatorClass
|
||||
|
||||
.. automethod:: OperatorClass.extern_key
|
||||
|
||||
.. automethod:: OperatorClass.identifier
|
||||
|
||||
.. automethod:: OperatorClass.to_map
|
||||
|
||||
.. automethod:: OperatorClass.create
|
||||
|
||||
Operator Class Dictionary
|
||||
-------------------------
|
||||
|
||||
:class:`OperatorClassDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of operator classes in a database.
|
||||
|
||||
.. autoclass:: OperatorClassDict
|
||||
|
||||
.. automethod:: OperatorClassDict.from_map
|
||||
@@ -0,0 +1,35 @@
|
||||
Operator Families
|
||||
=================
|
||||
|
||||
.. module:: pyrseas.dbobject.operfamily
|
||||
|
||||
The :mod:`operfamily` module defines two classes: class
|
||||
:class:`OperatorFamily` derived from :class:`DbSchemaObject` and class
|
||||
:class:`OperatorFamilyDict` derived from :class:`DbObjectDict`.
|
||||
|
||||
Operator Family
|
||||
---------------
|
||||
|
||||
:class:`OperatorFamily` is derived from :class:`DbSchemaObject` and
|
||||
represents a `Postgres operator family
|
||||
<https://www.postgresql.org/docs/current/static/sql-createopfamily.html>`_,
|
||||
a grouping of related operator classes.
|
||||
|
||||
.. autoclass:: OperatorFamily
|
||||
|
||||
.. automethod:: OperatorFamily.extern_key
|
||||
|
||||
.. automethod:: OperatorFamily.identifier
|
||||
|
||||
.. automethod:: OperatorFamily.create
|
||||
|
||||
Operator Family Dictionary
|
||||
--------------------------
|
||||
|
||||
:class:`OperatorFamilyDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of operator families in a database.
|
||||
|
||||
.. autoclass:: OperatorFamilyDict
|
||||
|
||||
.. automethod:: OperatorFamilyDict.from_map
|
||||
@@ -0,0 +1,117 @@
|
||||
.. -*- coding: utf-8 -*-
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
Pyrseas provides utilities to maintain a `PostgreSQL
|
||||
<https://www.postgresql.org/>`_ database schema. Its purpose is to
|
||||
enhance and follow through on the concepts of the `Andromeda Project
|
||||
<http://www.andromeda-project.org/>`_.
|
||||
|
||||
Whereas Andromeda expects the database designer or developer to
|
||||
provide a single `YAML <http://yaml.org/>`_ specification file of the
|
||||
database to be created, Pyrseas allows the development database to be
|
||||
created using the familiar SQL CREATE statements. The developer can
|
||||
then run the `dbtoyaml` utility to generate the YAML specification
|
||||
from the database. The spec can then be stored in any desired version
|
||||
control (VCS) repository. Similarly, she can add columns or modify
|
||||
tables or other objects using SQL ALTER statements and regenerate the
|
||||
YAML spec with dbtoyaml.
|
||||
|
||||
When ready to create or upgrade a test or production database, the
|
||||
`yamltodb` utility can be used with the YAML spec as input, to generate
|
||||
a script of SQL CREATE or ALTER statements to modify the database so
|
||||
that it matches the input spec.
|
||||
|
||||
A third tool, `dbaugment`, can be used to add custom attributes and
|
||||
supporting objects to a given schema. For example, an `updated`
|
||||
column can be added to various tables, together with trigger functions
|
||||
to ensure the columns are automatically modified as changes are made.
|
||||
|
||||
Use Cases
|
||||
---------
|
||||
|
||||
The following sections discuss the main scenarios where Pyrseas
|
||||
tools may be helpful.
|
||||
|
||||
Version Control
|
||||
---------------
|
||||
|
||||
The case for implementing a tool to facilitate version control over
|
||||
SQL databases was made in a couple of blog posts: `Version
|
||||
Control, Part 1: Pre-SQL
|
||||
<https://pyrseas.wordpress.com/2011/02/01/version-control-part-i-pre-sql/>`_
|
||||
and `Version Control, Part 2: SQL Databases
|
||||
<https://pyrseas.wordpress.com/2011/02/07/version-control-part-2-sql-databases/>`_. In
|
||||
summary, SQL data definition commands are generally incompatible with
|
||||
traditional version control approaches which usually require
|
||||
comparisons (diffs) between revisions of source files.
|
||||
|
||||
A refinement of the approach described in the aforementioned blog
|
||||
posts will be of interest to users with many objects in their database
|
||||
schemas, i.e., many tables, views, functions, and other more complex
|
||||
objects. Instead of storing a complete database specification in a
|
||||
single YAML file, by using the `--multiple-files` option to
|
||||
:program:`dbtoyaml`, the specification can be broken down into files
|
||||
corresponding, generally, to a single database object. This allows a
|
||||
VCS **diff** facility to easily highlight database changes. Please
|
||||
refer to the :doc:`dbtoyaml` and :doc:`yamltodb` utilities for further
|
||||
details.
|
||||
|
||||
The Pyrseas version control tools are not designed to be the ultimate
|
||||
SQL database version control solution. Instead, they are aimed at
|
||||
assisting two or more developers or DBAs in sharing changes to the
|
||||
underlying database as they implement a database application. The
|
||||
sharing can occur through a distributed or centralized VCS. The
|
||||
Pyrseas tools may even be used by a single DBA in conjunction with a
|
||||
distributed VCS to quickly explore alternative designs. The tools can
|
||||
also help to share changes with a conventional QA team, but may
|
||||
require additional controls for final releases and production
|
||||
installations.
|
||||
|
||||
Supplementary Actions
|
||||
---------------------
|
||||
|
||||
In many instances, a database schema needs to be supplemented by
|
||||
rarely-modified data kept in certain tables, e.g., a
|
||||
codes-descriptions table. The data import and export features,
|
||||
controlled by `datacopy` configuration parameter (see
|
||||
:doc:`configitems` for details) facilitates this need.
|
||||
|
||||
In other cases, DBAs may want to standardize certain additional table
|
||||
columns or processing. For example, they may want to capture the user
|
||||
and time of modification of a certain set of tables using a common
|
||||
procedure. The :doc:`dbaugment` utility was introduced to support
|
||||
these needs.
|
||||
|
||||
Generating SQL by determining what changed between one schema version
|
||||
and another is sometimes not sufficient. Although the change may be
|
||||
as simple as adding a column to a table and adding a referential
|
||||
constraint to the new column, if the tables already have data, it may
|
||||
not be possible to run the SQL generated by :program:`yamltodb`. This
|
||||
requires manual intervention by the DBAs or developers. The project
|
||||
would like to assist with these types of changes. The blog post `The
|
||||
Future of Pyrseas: Part 1
|
||||
<https://pyrseas.wordpress.com/2016/06/09/the-future-of-pyrseas-part-1/>`_
|
||||
is a first step in discussing this requirement.
|
||||
|
||||
Naming
|
||||
------
|
||||
|
||||
The project name comes from `Python <https://www.python.org/>`_, the
|
||||
programming language, and `Perseas
|
||||
<https://en.wikipedia.org/wiki/Perseus>`_ [#]_, the Greek mythological
|
||||
hero who rescued Andromeda from a sea monster [#]_. It is hoped that
|
||||
Pyrseas will rescue the Andromeda project <grin>. You can pronounce
|
||||
Pyrseas like the hero.
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#] The common English name for Perseas is Perseus and the Ancient
|
||||
Greek name is Perseos. However, in modern Greek Περσέας_ is the
|
||||
more common spelling for the mythical hero.
|
||||
|
||||
.. _Περσέας: https://en.wiktionary.org/wiki/%CE%A0%CE%B5%CF%81%CF%83%CE%AD%CE%B1%CF%82
|
||||
|
||||
.. [#] He is better known for having killed Medusa.
|
||||
@@ -0,0 +1,93 @@
|
||||
.. _predef-aug:
|
||||
|
||||
Predefined Database Augmentations
|
||||
=================================
|
||||
|
||||
These augmentations are specified in the ``config.yaml`` configuration
|
||||
file distributed with Pyrseas' :program:`dbaugment`.
|
||||
|
||||
Columns
|
||||
-------
|
||||
|
||||
These are predefined column specifications that can be added to
|
||||
tables, e.g., in various audit column combinations (see `Audit
|
||||
Columns`_ below).
|
||||
|
||||
- created_by_ip_address: An INET column to record the IP address which
|
||||
originated the current row.
|
||||
|
||||
- created_by_user: A VARCHAR(63) column to record the user, e.g.,
|
||||
CURRENT_USER, who created the current row.
|
||||
|
||||
- created_date: A DATE column that defaults to CURRENT_DATE.
|
||||
|
||||
- created_timestamp: A TIMESTAMP WITH TIME ZONE column to record the
|
||||
date and time when the current row was created.
|
||||
|
||||
- modified_by_ip_address: An INET column to record the IP address
|
||||
which originated the last modification to the current row.
|
||||
|
||||
- modified_by_user: A VARCHAR(63) column to record the user, e.g.,
|
||||
CURRENT_USER, who last modified the current row.
|
||||
|
||||
- modified_timestamp: A TIMESTAMP WITH TIME ZONE column to record the
|
||||
date and time when the current row was last modified.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
The following are predefined trigger functions which are used to
|
||||
implement various augmentations. The source for each function,
|
||||
written in PL/pgSQL, is specified in a function template, named with a
|
||||
``functempl_`` prefixed to the function name.
|
||||
|
||||
- Audit when modified (``audit_modified``): This function provides the
|
||||
CURRENT_TIMESTAMP value for audit columns.
|
||||
|
||||
- Default audit (``audit_default``): This function provides the
|
||||
CURRENT_USER and CURRENT_TIMESTAMP for audit columns.
|
||||
|
||||
- Full audit (``audit_full``): For SQL INSERTs, this function provides
|
||||
values for the user who created the row, the CURRENT_TIMESTAMP and
|
||||
the IP address for both the ``created_`` and ``modified_`` audit
|
||||
columns. For UPDATEs, it retains the existing values in the
|
||||
``created_`` columns and supplies current values for the
|
||||
``modified_`` columns.
|
||||
|
||||
In addition, the following helper functions are defined in schema
|
||||
``pyrseas``:
|
||||
|
||||
- get_session_variable
|
||||
- set_session_variable
|
||||
|
||||
A variant of ``get_session_variable`` is invoked by the ``audit_full``
|
||||
function to retrieve the actual (logged-on) user and IP address. In
|
||||
web applications, the user that connects to the database is typically
|
||||
the system user running the web server, rather than the application
|
||||
(logged on) user. The application can invoke the
|
||||
``pyrseas.set_session_variable`` function to supply the application
|
||||
user and IP address so that the audit trail will reflect the
|
||||
application context corrrectly.
|
||||
|
||||
Audit Columns
|
||||
-------------
|
||||
|
||||
These are predefined combinations of columns to be added to tables to
|
||||
record audit trail information. They may also include triggers to be
|
||||
invoked to maintain the column values.
|
||||
|
||||
- created_date_only: This is the simplest audit trail that adds a
|
||||
``created_date`` column which defaults to the CURRENT_DATE.
|
||||
|
||||
- modified_only: This is another simple audit trail. It adds a
|
||||
``modified_timestamp`` column which is supplied by a trigger named
|
||||
`table_name`\_20_audit_modified_only.
|
||||
|
||||
- default: This is the default for audit columns. It adds the columns
|
||||
``modified_by_user`` and ``modified_timestamp`` and a trigger named
|
||||
`table_name`\_20_audit_default to fill in the columns.
|
||||
|
||||
- full: This is the most extensive audit trail combination. It adds
|
||||
``created_`` and ``modified_`` columns for user, IP address and
|
||||
timestamp. It also adds a trigger named
|
||||
`table_name`\_20_audit_full.
|
||||
@@ -0,0 +1,35 @@
|
||||
Rules
|
||||
=====
|
||||
|
||||
.. module:: pyrseas.dbobject.rule
|
||||
|
||||
The :mod:`rule` module defines two classes, :class:`Rule` and
|
||||
:class:`RuleDict`, derived from :class:`DbSchemaObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Rule
|
||||
----
|
||||
|
||||
:class:`Rule` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a `Postgres
|
||||
rewrite rule
|
||||
<https://www.postgresql.org/docs/current/static/rules.html>`_.
|
||||
|
||||
.. autoclass:: Rule
|
||||
|
||||
.. automethod:: Rule.identifier
|
||||
|
||||
.. automethod:: Rule.to_map
|
||||
|
||||
.. automethod:: Rule.create
|
||||
|
||||
Rule Dictionary
|
||||
---------------
|
||||
|
||||
:class:`RuleDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of rewrite rules in a database.
|
||||
|
||||
.. autoclass:: RuleDict
|
||||
|
||||
.. automethod:: RuleDict.from_map
|
||||
@@ -0,0 +1,57 @@
|
||||
Schemas
|
||||
=======
|
||||
|
||||
.. module:: pyrseas.dbobject.schema
|
||||
|
||||
The :mod:`schema` module defines two classes, :class:`Schema` and
|
||||
:class:`SchemaDict`, derived from :class:`DbObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Schema
|
||||
------
|
||||
|
||||
:class:`Schema` is derived from :class:`~pyrseas.dbobject.DbObject`
|
||||
and represents a database schema or Postgres namespace, i.e., a
|
||||
collection of tables and other objects. The 'public' schema is
|
||||
currently treated specially as in most contexts an unqualified object
|
||||
is assumed to be part of it, e.g., table "t" is usually shorthand for
|
||||
table "public.t." The 'pyrseas' schema, if present, is excluded as it
|
||||
is only intended for use by :program:`dbaugment` or other Pyrseas
|
||||
internal purposes.
|
||||
|
||||
.. autoclass:: Schema
|
||||
|
||||
.. automethod:: Schema.extern_dir
|
||||
|
||||
.. automethod:: Schema.to_map
|
||||
|
||||
.. automethod:: Schema.create
|
||||
|
||||
.. automethod:: Schema.drop
|
||||
|
||||
.. automethod:: Schema.data_import
|
||||
|
||||
Schema Dictionary
|
||||
-----------------
|
||||
|
||||
:class:`SchemaDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of schemas in a database. Certain internal
|
||||
schemas (information_schema, pg_catalog, etc.) owned by the 'postgres'
|
||||
user are excluded.
|
||||
|
||||
.. autoclass:: SchemaDict
|
||||
|
||||
Method :meth:`from_map` is called from :class:`Database`
|
||||
:meth:`~pyrseas.database.Database.from_map` to start a recursive
|
||||
interpretation of the input map. The :obj:`inmap` argument is the same
|
||||
as input to the :meth:`~pyrseas.database.Database.diff_map` method of
|
||||
:class:`Database`. The :obj:`newdb` argument is the holder of
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`-derived dictionaries which is
|
||||
filled in as the recursive interpretation proceeds.
|
||||
|
||||
.. automethod:: SchemaDict.from_map
|
||||
|
||||
.. automethod:: SchemaDict.to_map
|
||||
|
||||
.. automethod:: SchemaDict.data_import
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
Tables, Views and Sequences
|
||||
===========================
|
||||
|
||||
.. module:: pyrseas.dbobject.table
|
||||
|
||||
The :mod:`table` and :mod:`view` modules define six classes,
|
||||
:class:`DbClass` derived from :class:`DbSchemaObject`, classes
|
||||
:class:`Sequence`, :class:`Table` and :class:`View` derived from
|
||||
:class:`DbClass`, :class:`MaterializedView` derived from
|
||||
:class:`View`, and :class:`ClassDict`, derived from
|
||||
:class:`DbObjectDict`.
|
||||
|
||||
Database Class
|
||||
--------------
|
||||
|
||||
Class :class:`DbClass` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a table, view
|
||||
or sequence as defined in the Postgres `pg_class` catalog.
|
||||
|
||||
.. autoclass:: DbClass
|
||||
|
||||
Sequence
|
||||
--------
|
||||
|
||||
Class :class:`Sequence` is derived from :class:`DbClass` and
|
||||
represents a `sequence generator
|
||||
<https://www.postgresql.org/docs/current/static/sql-createsequence.html>`_.
|
||||
Its :attr:`keylist` attributes are the schema name and the sequence
|
||||
name.
|
||||
|
||||
The map returned by :meth:`to_map` and expected as argument by
|
||||
:meth:`ClassDict.from_map` has the following structure::
|
||||
|
||||
{'sequence seq1':
|
||||
{'cache_value': 1,
|
||||
'data_type': 'integer',
|
||||
'increment_by': 1,
|
||||
'max_value': None,
|
||||
'min_value': None,
|
||||
'owner_column': 'c1',
|
||||
'owner_table': 't1',
|
||||
'start_value': 1
|
||||
}
|
||||
}
|
||||
|
||||
.. autoclass:: Sequence
|
||||
|
||||
.. automethod:: Sequence.get_attrs
|
||||
|
||||
.. automethod:: Sequence.get_dependent_table
|
||||
|
||||
.. automethod:: Sequence.to_map
|
||||
|
||||
.. automethod:: Sequence.create
|
||||
|
||||
.. automethod:: Sequence.add_owner
|
||||
|
||||
.. automethod:: Sequence.alter
|
||||
|
||||
.. automethod:: Sequence.drop
|
||||
|
||||
Table
|
||||
-----
|
||||
|
||||
Class :class:`Table` is derived from :class:`DbClass` and represents a
|
||||
database table. Its :attr:`keylist` attributes are the schema name and
|
||||
the table name.
|
||||
|
||||
The map returned by :meth:`to_map` and expected as argument by
|
||||
:meth:`ClassDict.from_map` has a structure similar to the following::
|
||||
|
||||
{'table t1':
|
||||
{'columns':
|
||||
[
|
||||
{'c1': {'type': 'integer', 'not_null': True}},
|
||||
{'c2': {'type': 'text'}},
|
||||
{'c3': {'type': 'smallint'}},
|
||||
{'c4': {'type': 'date', 'default': 'now()'}}
|
||||
],
|
||||
'description': "this is the comment for table t1",
|
||||
'primary_key':
|
||||
{'t1_prim_key':
|
||||
{'columns': ['c1', 'c2']}
|
||||
},
|
||||
'foreign_keys':
|
||||
{'t1_fgn_key1':
|
||||
{'columns': ['c2', 'c3'],
|
||||
'references':
|
||||
{'table': 't2', 'columns': ['pc2', 'pc1']}
|
||||
},
|
||||
't1_fgn_key2':
|
||||
{'columns': ['c2'],
|
||||
'references': {'table': 't3', 'columns': ['qc1']}
|
||||
}
|
||||
},
|
||||
'unique_constraints': {...},
|
||||
'indexes': {...}
|
||||
}
|
||||
}
|
||||
|
||||
The values for :obj:`unique_constraints` and :obj:`indexes` follow a
|
||||
pattern similar to :obj:`primary_key`, but there can be more than one
|
||||
such specification.
|
||||
|
||||
.. autoclass:: Table
|
||||
|
||||
.. automethod:: Table.column_names
|
||||
|
||||
.. automethod:: Table.to_map
|
||||
|
||||
.. automethod:: Table.create
|
||||
|
||||
.. automethod:: Table.drop
|
||||
|
||||
.. automethod:: Table.diff_options
|
||||
|
||||
.. automethod:: Table.alter
|
||||
|
||||
.. automethod:: Table.alter_drop_columns
|
||||
|
||||
.. automethod:: Table.data_export
|
||||
|
||||
.. automethod:: Table.data_import
|
||||
|
||||
Class Dictionary
|
||||
----------------
|
||||
|
||||
Class :class:`ClassDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict` and represents the collection
|
||||
of tables, views and sequences in a database.
|
||||
|
||||
.. autoclass:: ClassDict
|
||||
|
||||
.. automethod:: ClassDict.from_map
|
||||
|
||||
|
||||
.. module:: pyrseas.dbobject.view
|
||||
|
||||
View
|
||||
----
|
||||
|
||||
Class :class:`View` is derived from :class:`DbClass` and represents a
|
||||
database view. Its :attr:`keylist` attributes are the schema name and
|
||||
the view name.
|
||||
|
||||
The map returned by :meth:`to_map` and expected as argument by
|
||||
:meth:`ClassDict.from_map` has a structure similar to the following::
|
||||
|
||||
{'view v1':
|
||||
{'columns': [{'c1': {'type': 'integer'}},
|
||||
{'c2': {'type': 'date'}}],
|
||||
'definition': " SELECT ...;",
|
||||
'description': "this is the comment for view v1"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.. autoclass:: View
|
||||
|
||||
.. automethod:: View.to_map
|
||||
|
||||
.. automethod:: View.create
|
||||
|
||||
.. automethod:: View.alter
|
||||
|
||||
Materialized View
|
||||
-----------------
|
||||
|
||||
Class :class:`MaterializedView` is derived from :class:`View` and
|
||||
represents a `materialized view
|
||||
<https://www.postgresql.org/docs/current/static/sql-creatematerializedview.html>`_. Its
|
||||
:attr:`keylist` attributes are the schema name and the view name.
|
||||
|
||||
.. autoclass:: MaterializedView
|
||||
|
||||
.. automethod:: MaterializedView.to_map
|
||||
|
||||
.. automethod:: MaterializedView.create
|
||||
@@ -0,0 +1,175 @@
|
||||
.. _testing:
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
The majority of Pyrseas' capabilities are exercised and verified via
|
||||
unit tests written using `pytest
|
||||
<https://docs.pytest.org/en/latest/>`_. The tests can be run from the
|
||||
command line by most users, e.g.,
|
||||
|
||||
::
|
||||
|
||||
pytest-3 tests/dbobject/test_table.py
|
||||
pytest-3 tests/dbobject/test_trigger.py -k test_create_trigger
|
||||
pytest-3 tests/functional
|
||||
|
||||
The first ``pytest-3`` command above runs all tests related to tables,
|
||||
mapping, creating, dropping, etc. The second one executes a single
|
||||
test to generate SQL to create a trigger. The third runs all the
|
||||
functional tests. Please review the `pytest documentation
|
||||
<https://docs.pytest.org/en/latest/usage.html>`_ for further options.
|
||||
|
||||
Environment Variables
|
||||
---------------------
|
||||
|
||||
By default, the tests use a Postgres database named ``pyrseas_testdb``
|
||||
which is created if it doesn't already exist. The tests are run as the
|
||||
logged in user, using the ``USER`` Unix/Linux environment variable (or
|
||||
``USERNAME`` under Windows). They access Postgres on the local host
|
||||
using the default port number (5432).
|
||||
|
||||
The following four environment variables can be used to change the
|
||||
defaults described above:
|
||||
|
||||
- PYRSEAS_TEST_DB
|
||||
- PYRSEAS_TEST_USER
|
||||
- PYRSEAS_TEST_HOST
|
||||
- PYRSEAS_TEST_PORT
|
||||
|
||||
Restrictions
|
||||
------------
|
||||
|
||||
Unless the test database exists and the user running the tests has
|
||||
access to it, the user role will need CREATEDB privilege.
|
||||
|
||||
Most tests do not require special privileges. However, certain tests
|
||||
may require Postgres SUPERUSER privilege. Such tests will normally be
|
||||
skipped if the user lacks the privilege.
|
||||
|
||||
Most tests do not require installation of supporting Postgres
|
||||
packages. However, a few tests rely on the availability of Postgres
|
||||
``contrib`` modules such as the `spi module
|
||||
<https://www.postgresql.org/docs/current/static/contrib-spi.html>`_ or
|
||||
procedural languages such as ``plperl``, ``plpython3u`` or ``plr``.
|
||||
|
||||
On Windows, it is necessary to install Perl in order to run some of
|
||||
the tests (most Linux or Unix variants already include it as part of
|
||||
their normal distribution). The last time we checked, a suitable
|
||||
choice appeared to be Strawberry Perl which can be downloaded from
|
||||
http://strawberryperl.com/releases.html. However, the default
|
||||
installation is placed in ``C:\strawberry`` and can hold a single Perl
|
||||
version. Furthermore, some Postgres versions may be linked with
|
||||
non-current Perl versions. It is recommended that the latest Perl
|
||||
version be installed as this will usually give the fewest test
|
||||
failures. See `this blog post
|
||||
<https://pyrseas.wordpress.com/2012/10/17/testing-python-and-postgresql-on-windows-part-5/>`_
|
||||
for more details.
|
||||
|
||||
The COLLATION tests require the
|
||||
``fr_FR.utf8`` locale (or ``French.France.1252`` language on Windows)
|
||||
to be installed.
|
||||
|
||||
Testing Checklist
|
||||
-----------------
|
||||
|
||||
The following is a summary list of steps needed to test Pyrseas on a
|
||||
new machine. Refer to :ref:`development` for details on how to
|
||||
accomplish a given installation task. "Package manager" refers to the
|
||||
platform's package management system utility such as ``apt-get`` or
|
||||
``yum``. Installation from PyPI can be done with ``pip``. Some
|
||||
operations require administrative or superuser privileges, at either
|
||||
the operating system or Postgres level.
|
||||
|
||||
- Install Git using package manager or from
|
||||
https://git-scm.com/download (on Windows, prefer Git Bash)
|
||||
|
||||
- ``git clone git://github.com/perseas/Pyrseas.git``
|
||||
|
||||
- Install Python 3.7 or higher, using package manager or from
|
||||
installers at https://www.python.org/downloads/.
|
||||
|
||||
- Install Postgres 13, 12, 11 or 10, using package manager or
|
||||
binary installers at https://www.postgresql.org/download/
|
||||
|
||||
.. note:: On Linux, make sure you install the contrib and plperl
|
||||
packages, e.g., on Debian, postgresql-contrib-n and
|
||||
postgresql-plperl-n (where `n` is the Postgres
|
||||
version number)
|
||||
|
||||
- Install Psycopg, using package manager, or from PyPI
|
||||
(https://pypi.org/project/psycopg/).
|
||||
|
||||
.. note:: On Windows, you may first want to install a version of
|
||||
Microsoft Visual Studio from `here`_. An alternative
|
||||
that may work is `MinGW <http://mingw.org/>`_. See
|
||||
`these blog`_ `posts`_ for more details.
|
||||
|
||||
.. _here: https://www.microsoft.com/en-us/download/developer-tools.aspx
|
||||
|
||||
.. _these blog: https://pyrseas.wordpress.com/2012/09/25/testing-python-and-postgresql-on-windows-part-2/
|
||||
|
||||
.. _posts: https://pyrseas.wordpress.com/2012/09/28/testing-python-and-postgresql-on-windows-part-3/
|
||||
|
||||
- Install PyYAML, using package manager, or from PyPI
|
||||
(https://pypi.org/project/PyYAML/) or
|
||||
http://pyyaml.org/download/pyyaml/.
|
||||
|
||||
- Install pytest, using package manager, or from PyPI
|
||||
(https://pypi.org/project/pytest/).
|
||||
|
||||
- Install Tox, using package manager, or from PyPI
|
||||
(https://pypi.org/project/tox/)
|
||||
|
||||
- On Windows, install Perl (see discussion above under
|
||||
"Restrictions"). On Linux, usually Perl is already available.
|
||||
|
||||
- As **postgres** user, using psql or pgAdmin, create a test user,
|
||||
e.g., your name. The user running tests must have at a minimum
|
||||
createdb privilege, in order to create the test database. To run
|
||||
*all* the tests, the user also needs superuser privilege.
|
||||
|
||||
- Create a Postgres password file, e.g., on Linux: ``~/.pgpass``, on
|
||||
Windows: ``%APPDATA%\postgresql\pgpass.conf``.
|
||||
|
||||
- Create directories to hold tablespaces, e.g., ``/extra/pg/13.0/ts1``
|
||||
on Linux, ``C:\\extra\\pg\\13.0\\ts1`` on Windows. The directories
|
||||
need to be owned by the **postgres** user. This may be tricky on
|
||||
older Windows versions, but the command ``cacls <dir> /E /G
|
||||
postgres:F`` should suffice. Using ``psql``, create tablespaces
|
||||
**ts1** and **ts2**, e.g., ``CREATE TABLESPACE ts1 LOCATION
|
||||
'<directory>'`` (on Windows, you'll have to use, e.g.,
|
||||
``E'C:\\dir\\ts1'``, to specify the directory).
|
||||
|
||||
- Install the locale ``fr_FR.utf8`` on Linux/Unix or the language
|
||||
``French.France.1252`` on Windows.
|
||||
|
||||
- On Debian and derivatives, this can be done with the command::
|
||||
|
||||
sudo dpkg-reconfigure locales
|
||||
|
||||
- On Windows, open the Control Panel, select Date, Time, Language,
|
||||
and Regional Options, then Regional and Language Options (or Add
|
||||
other languages), click on the Advanced tab in the dialog and
|
||||
then choose “French (France)” from the dropdown. Finally, click
|
||||
OK and respond to any subsequent prompts to install the locale,
|
||||
including rebooting the machine.
|
||||
|
||||
- Change to the Pyrseas source directory (created by the second step above).
|
||||
|
||||
- Define the ``PYTHONPATH`` environment variable to the Pyrseas source
|
||||
directory, e.g., on Linux, ``export PYTHONPATH=$PWD``, on
|
||||
Windows, ``set PYTHONPATH=%USERPROFILE%\somedir\Pyrseas``.
|
||||
|
||||
- Define the ``PG1N0_PORT`` environment variables (where ``1N``
|
||||
represents the major Posgres version, e.g., 15, 11) to point to the
|
||||
corresponding Postgres connection ports.
|
||||
|
||||
- Invoke ``tox``. This will create virtualenvs in a ``.tox``
|
||||
subdirectory,
|
||||
install Pyrseas and its prerequisites (Psycopg and PyYAML) into
|
||||
each virtualenv and run the unit tests for each combination of
|
||||
Postgres and Python.
|
||||
|
||||
If you find any problems with the instructions above, please open an
|
||||
issue on `GitHub <https://github.com/perseas/Pyrseas/issues>`_.
|
||||
@@ -0,0 +1,102 @@
|
||||
Text Search Objects
|
||||
===================
|
||||
|
||||
.. module:: pyrseas.dbobject.textsearch
|
||||
|
||||
The :mod:`textsearch` module defines eight classes: classes
|
||||
:class:`TSConfiguration`, :class:`TSDictionary`, :class:`TSParser` and
|
||||
:class:`TSTemplate` derived from :class:`DbSchemaObject`, and classes
|
||||
:class:`TSConfigurationDict`, :class:`TSDictionaryDict`,
|
||||
:class:`TSParserDict` and :class:`TSTemplateDict` derived from
|
||||
:class:`DbObjectDict`.
|
||||
|
||||
Text Search Configuration
|
||||
-------------------------
|
||||
|
||||
:class:`TSConfiguration` is derived from :class:`DbSchemaObject` and
|
||||
represents a `Postgres text search configuration
|
||||
<https://www.postgresql.org/docs/current/static/sql-createtsconfig.html>`_.
|
||||
|
||||
.. autoclass:: TSConfiguration
|
||||
|
||||
.. automethod:: TSConfiguration.to_map
|
||||
|
||||
.. automethod:: TSConfiguration.create
|
||||
|
||||
Text Search Configuration Dictionary
|
||||
------------------------------------
|
||||
|
||||
:class:`TSConfigurationDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of text search configurations in a database.
|
||||
|
||||
.. autoclass:: TSConfigurationDict
|
||||
|
||||
.. automethod:: TSConfigurationDict.from_map
|
||||
|
||||
Text Search Dictionary
|
||||
----------------------
|
||||
|
||||
:class:`TSDictionary` is derived from :class:`DbSchemaObject` and
|
||||
represents a `Postgres text search dictionary
|
||||
<https://www.postgresql.org/docs/current/static/textsearch-dictionaries.html>`_.
|
||||
|
||||
.. autoclass:: TSDictionary
|
||||
|
||||
.. automethod:: TSDictionary.create
|
||||
|
||||
Text Search Dictionary Dictionary
|
||||
---------------------------------
|
||||
|
||||
:class:`TSDictionaryDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a Python dictionary
|
||||
that represents the collection of text search dictionaries in a
|
||||
database.
|
||||
|
||||
.. autoclass:: TSDictionaryDict
|
||||
|
||||
.. automethod:: TSDictionaryDict.from_map
|
||||
|
||||
Text Search Parser
|
||||
------------------
|
||||
|
||||
:class:`TSParser` is derived from :class:`DbSchemaObject` and
|
||||
represents a `Postgres text search parser
|
||||
<https://www.postgresql.org/docs/current/static/sql-createtsparser.html>`_.
|
||||
|
||||
.. autoclass:: TSParser
|
||||
|
||||
.. automethod:: TSParser.create
|
||||
|
||||
Text Search Parser Dictionary
|
||||
-----------------------------
|
||||
|
||||
:class:`TSParserDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of text search parsers in a database.
|
||||
|
||||
.. autoclass:: TSParserDict
|
||||
|
||||
.. automethod:: TSParserDict.from_map
|
||||
|
||||
Text Search Template
|
||||
--------------------
|
||||
|
||||
:class:`TSTemplate` is derived from :class:`DbSchemaObject` and
|
||||
represents a `Postgres text search template
|
||||
<https://www.postgresql.org/docs/current/static/sql-createtstemplate.html>`_.
|
||||
|
||||
.. autoclass:: TSTemplate
|
||||
|
||||
.. automethod:: TSTemplate.create
|
||||
|
||||
Text Search Template Dictionary
|
||||
-------------------------------
|
||||
|
||||
:class:`TSTemplateDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of text search templates in a database.
|
||||
|
||||
.. autoclass:: TSTemplateDict
|
||||
|
||||
.. automethod:: TSTemplateDict.from_map
|
||||
@@ -0,0 +1,35 @@
|
||||
Triggers
|
||||
========
|
||||
|
||||
.. module:: pyrseas.dbobject.trigger
|
||||
|
||||
The :mod:`trigger` module defines two classes, :class:`Trigger` and
|
||||
:class:`TriggerDict`, derived from :class:`DbSchemaObject` and
|
||||
:class:`DbObjectDict`, respectively.
|
||||
|
||||
Trigger
|
||||
-------
|
||||
|
||||
:class:`Trigger` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a Postgres
|
||||
`regular or constraint trigger
|
||||
<https://www.postgresql.org/docs/current/static/sql-createtrigger.html>`_.
|
||||
|
||||
.. autoclass:: Trigger
|
||||
|
||||
.. automethod:: Trigger.identifier
|
||||
|
||||
.. automethod:: Trigger.to_map
|
||||
|
||||
.. automethod:: Trigger.create
|
||||
|
||||
Trigger Dictionary
|
||||
------------------
|
||||
|
||||
:class:`TriggerDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of triggers in a database.
|
||||
|
||||
.. autoclass:: TriggerDict
|
||||
|
||||
.. automethod:: TriggerDict.from_map
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
Types and Domains
|
||||
=================
|
||||
|
||||
.. module:: pyrseas.dbobject.dbtype
|
||||
|
||||
The :mod:`dbtype` module defines seven classes, :class:`DbType`
|
||||
derived from :class:`DbSchemaObject`, :class:`BaseType`,
|
||||
:class:`Composite`, :class:`Enum`, :class:`Domain` and :class:`Range`
|
||||
derived from :class:`DbType`, and :class:`TypeDict` derived from and
|
||||
:class:`DbObjectDict`.
|
||||
|
||||
Database Type
|
||||
-------------
|
||||
|
||||
Class :class:`DbType` is derived from
|
||||
:class:`~pyrseas.dbobject.DbSchemaObject` and represents a SQL type or
|
||||
domain as defined in the Postgres `pg_type` catalog.
|
||||
|
||||
.. autoclass:: DbType
|
||||
|
||||
Base Type
|
||||
---------
|
||||
|
||||
:class:`BaseType` is derived from :class:`~pyrseas.dbobject.DbType`
|
||||
and represents a Postgres `user-defined base type
|
||||
<https://www.postgresql.org/docs/current/static/xtypes.html>`_.
|
||||
|
||||
The map returned by :meth:`to_map` and expected as argument by
|
||||
:meth:`TypeDict.from_map` has the following structure (not all fields
|
||||
need be present)::
|
||||
|
||||
{'type t1':
|
||||
{'alignment': 'double',
|
||||
'analyze': 'analyze_func',
|
||||
'category': 'U',
|
||||
'delimiter': ',',
|
||||
'input': 'input_func',
|
||||
'internallength': 'variable',
|
||||
'output': 'output_func',
|
||||
'preferred': 'true',
|
||||
'receive': 'receive_func',
|
||||
'send': 'send_func',
|
||||
'storage': 'plain'
|
||||
'typmod_in': 'typmod_in_func',
|
||||
'typmod_out': 'typmod_out_func'
|
||||
}
|
||||
}
|
||||
|
||||
.. autoclass:: BaseType
|
||||
|
||||
.. automethod:: BaseType.to_map
|
||||
|
||||
.. automethod:: BaseType.create
|
||||
|
||||
.. automethod:: BaseType.drop
|
||||
|
||||
Composite
|
||||
---------
|
||||
|
||||
:class:`Composite` is derived from :class:`~pyrseas.dbobject.DbType`
|
||||
and represents a standalone `composite type
|
||||
<https://www.postgresql.org/docs/current/static/rowtypes.html>`_.
|
||||
|
||||
.. autoclass:: Composite
|
||||
|
||||
.. automethod:: Composite.to_map
|
||||
|
||||
.. automethod:: Composite.create
|
||||
|
||||
.. automethod:: Composite.alter
|
||||
|
||||
Enum
|
||||
----
|
||||
|
||||
:class:`Enum` is derived from :class:`~pyrseas.dbobject.DbType` and
|
||||
represents an `enumerated type
|
||||
<https://www.postgresql.org/docs/current/static/datatype-enum.html>`_.
|
||||
|
||||
.. autoclass:: Enum
|
||||
|
||||
.. automethod:: Enum.create
|
||||
|
||||
Domain
|
||||
------
|
||||
|
||||
:class:`Domain` is derived from :class:`~pyrseas.dbobject.DbType` and
|
||||
represents a `domain
|
||||
<https://www.postgresql.org/docs/current/static/sql-createdomain.html>`_.
|
||||
|
||||
.. autoclass:: Domain
|
||||
|
||||
.. automethod:: Domain.to_map
|
||||
|
||||
.. automethod:: Domain.create
|
||||
|
||||
Range
|
||||
-----
|
||||
|
||||
:class:`Range` is derived from :class:`~pyrseas.dbobject.DbType` and
|
||||
represents a `Postgres range type
|
||||
<https://www.postgresql.org/docs/current/static/rangetypes.html>`_.
|
||||
|
||||
.. autoclass:: Range
|
||||
|
||||
.. automethod:: Range.to_map
|
||||
|
||||
.. automethod:: Range.create
|
||||
|
||||
.. automethod:: Range.alter
|
||||
|
||||
Type Dictionary
|
||||
---------------
|
||||
|
||||
:class:`TypeDict` is derived from
|
||||
:class:`~pyrseas.dbobject.DbObjectDict`. It is a dictionary that
|
||||
represents the collection of domains and enums in a database.
|
||||
|
||||
.. autoclass:: TypeDict
|
||||
|
||||
.. automethod:: TypeDict.from_map
|
||||
@@ -0,0 +1,129 @@
|
||||
yamltodb - YAML to Database
|
||||
===========================
|
||||
|
||||
Name
|
||||
----
|
||||
|
||||
yamltodb -- generate SQL statements to update a Postgres database to
|
||||
match the schema specified in a YAML file
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
yamltodb [option...] dbname [spec]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
:program:`yamltodb` is a utility for generating SQL statements to
|
||||
update a Postgres database so that it will match the schema
|
||||
specified in an input `YAML <http://yaml.org>`_ formatted
|
||||
specification file.
|
||||
|
||||
For example, given the input file shown under :doc:`dbtoyaml`,
|
||||
:program:`yamltodb`, when run against a newly-created database,
|
||||
outputs the following SQL statements::
|
||||
|
||||
CREATE SCHEMA s1;
|
||||
ALTER SCHEMA s1 OWNER TO bob;
|
||||
GRANT ALL ON SCHEMA s1 TO bob;
|
||||
GRANT ALL ON SCHEMA s1 TO alice;
|
||||
CREATE TABLE t1 (
|
||||
c1 integer NOT NULL,
|
||||
c2 smallint,
|
||||
c3 boolean DEFAULT false,
|
||||
c4 text);
|
||||
ALTER TABLE t1 OWNER TO alice;
|
||||
CREATE TABLE s1.t2 (
|
||||
c21 integer NOT NULL,
|
||||
c22 character varying(16));
|
||||
ALTER TABLE s1.t2 OWNER TO bob;
|
||||
GRANT ALL ON TABLE s1.t2 TO bob;
|
||||
GRANT SELECT ON TABLE s1.t2 TO PUBLIC;
|
||||
GRANT INSERT, DELETE, UPDATE ON TABLE s1.t2 TO alice WITH GRANT OPTION;
|
||||
GRANT INSERT ON TABLE s1.t2 TO carol;
|
||||
ALTER TABLE t1 ADD CONSTRAINT t1_c2_check CHECK (c2 > 123);
|
||||
ALTER TABLE t1 ADD CONSTRAINT t1_pkey PRIMARY KEY (c1);
|
||||
ALTER TABLE s1.t2 ADD CONSTRAINT t2_pkey PRIMARY KEY (c21);
|
||||
ALTER TABLE t1 ADD CONSTRAINT t1_c2_fkey FOREIGN KEY (c2) REFERENCES s1.t2 (c21);
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
:program:`yamltodb` accepts the following command-line arguments (in
|
||||
addition to the :doc:`cmdargs`):
|
||||
|
||||
.. program:: yamltodb
|
||||
|
||||
**dbname**
|
||||
|
||||
Specifies the name of the database whose schema is to analyzed.
|
||||
|
||||
**spec**
|
||||
|
||||
Specifies the location of the YAML specification. If this is
|
||||
omitted or specified as a single or double dash, the specification
|
||||
is read from the program's standard input. However, if the
|
||||
:option:`--multiple-files` option is used, that takes precedence.
|
||||
|
||||
.. cmdoption:: -m, --multiple-files
|
||||
|
||||
Specifies that input should be taken from YAML specification files
|
||||
present in a two-level (metadata) directory tree. See `Multiple
|
||||
File Output` under :doc:`dbtoyaml` for further details.
|
||||
|
||||
.. cmdoption:: -n <schema>
|
||||
--schema <schema>
|
||||
|
||||
Compare only a schema matching `schema`. By default, all schemas
|
||||
are compared. Multiple schemas can be compared by using multiple
|
||||
:option:`-n` switches.
|
||||
|
||||
.. cmdoption:: -1
|
||||
--single-transaction
|
||||
|
||||
Wrap the generated statements in BEGIN/COMMIT. This ensures that
|
||||
either all the statements complete successfully, or no changes are
|
||||
applied.
|
||||
|
||||
.. cmdoption:: -u, --update
|
||||
|
||||
Execute the generated statements against the database mentioned in
|
||||
**dbname**. This implies the :option:`--single-transaction`
|
||||
option.
|
||||
|
||||
.. cmdoption:: --revert
|
||||
|
||||
Generate SQL in reversion mode, that is, to undo the changes that
|
||||
would normally be generated. For example, if without this option,
|
||||
the SQL would be a ``DROP TABLE``, the :option:`--revert` option
|
||||
generates a ``CREATE TABLE`` with all the columns, constraints and
|
||||
other objects associated with the table being dropped.
|
||||
|
||||
This option is experimental and currently has only been
|
||||
implemented for schemas and sequences.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Given a YAML file named ``moviesdb.yaml``, to generate SQL statements
|
||||
to update a database called `mymovies`::
|
||||
|
||||
yamltodb mymovies moviesdb.yaml
|
||||
|
||||
To generate the statements as above and immediately update `mymovies`::
|
||||
|
||||
yamltodb mymovies moviesdb.yaml | psql mymovies
|
||||
|
||||
or::
|
||||
|
||||
yamltodb --update mymovies moviesdb.yaml
|
||||
|
||||
To generate the statements directly from the output of
|
||||
:program:`dbtoyaml` (against a different database), with statements
|
||||
enclosed in a single transaction, and save the statements in a file
|
||||
named ``mymovies.sql``::
|
||||
|
||||
dbtoyaml devmovies | yamltodb -1 mymovies -o mymovies.sql
|
||||
Reference in New Issue
Block a user