Permalink
Browse files

Enhance documentation of DbObject. Remove redundant to_map methods.

 * docs/conversion.rst: Remove to_map automethod.
 * docs/dbobject.rst: Improve documentation of DbObject.
 * docs/operator.rst: Remove to_map automethod.
 * docs/table.rst: Remove to_map automethod on View.
 * docs/type.rst: Remove to_map automethod on Enum.
 * pyrseas/dbobject/__init__.py: Expand or add docstrings for various
   methods and attributes. (DbObject.{_base_map,to_map}): New method
   to simplify implementation of to_map.
 * pyrseas/dbobject/cast.py (Cast.extern_key): Use lowercase 'as' for
   consistency. (Cast.to_map): Use _base_map.
 * pyrseas/dbobject/column.py (Column.to_map): Use _base_map.
 * pyrseas/dbobject/constraint.py ({CheckConstraint,PrimaryKey,
   ForeignKey,UniqueConstraint}.to_map): Use _base_map.
 * pyrseas/dbobject/conversion.py (Conversion.to_map): Remove as
   redundant.
 * pyrseas/dbobject/dbtype.py ({BaseType,Domain}.to_map): Use
   _base_map. (Enum.to_map): Remove as redundant.
 * pyrseas/dbobject/function.py ({Function,Aggregate}.to_map): Use
   _base_map.
 * pyrseas/dbobject/index.py (Index.to_map): Use _base_map.
 * pyrseas/dbobject/language.py (Language.to_map): Use
   _base_map. Eliminate redundant description code.
 * pyrseas/dbobject/operator.py (Operator.to_map): Remove as
   redundant.
 * pyrseas/dbobject/operclass.py (OperatorClass.to_map): Use
   _base_map.
 * pyrseas/dbobject/operfamily.py: Indentation.
 * pyrseas/dbobject/rule.py (Rule.to_map): Use _base_map.
 * pyrseas/dbobject/table.py (View.to_map): Remove as redundant.
 * pyrseas/dbobject/trigger.py (Trigger.to_map): Use _base_map.
 * tests/dbobject/test_cast.py: Use 'as' instead of 'AS' in external
   maps.
 * tests/dbobject/test_language.py: Spacing.
  • Loading branch information...
1 parent 72c3590 commit 3163e20bbaf929c584979798c532c90ae33b8285 @jmafc jmafc committed Sep 23, 2011
View
@@ -17,8 +17,6 @@ conversion between character set encodings
.. autoclass:: Conversion
-.. automethod:: Conversion.to_map
-
.. automethod:: Conversion.create
.. automethod:: Conversion.diff_map
View
@@ -10,20 +10,27 @@ intermediate class. Most Pyrseas classes are derived from either
Database Object
---------------
-A :class:`DbObject` represents a database object such as a
-schema, table, or column, defined in a system catalog. It is
+A :class:`DbObject` represents a database object such as a schema,
+table, or column, defined in a PostgreSQL `system catalog
+<http://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
+
.. automethod:: DbObject.extern_key
+.. autoattribute:: DbObject.keylist
+
.. automethod:: DbObject.key
.. automethod:: DbObject.identifier
+.. automethod:: DbObject.to_map
+
.. automethod:: DbObject.comment
.. automethod:: DbObject.drop
@@ -49,6 +56,10 @@ e.g., :class:`~pyrseas.schema.SchemaDict` sets :attr:`cls` to
.. autoclass:: DbObjectDict
+.. autoattribute:: DbObjectDict.cls
+
+.. autoattribute:: DbObjectDict.query
+
.. automethod:: DbObjectDict.fetch
View
@@ -22,8 +22,6 @@ represents a `PostgreSQL user-defined operator
.. automethod:: Operator.identifier
-.. automethod:: Operator.to_map
-
.. automethod:: Operator.create
.. automethod:: Operator.diff_map
View
@@ -131,8 +131,6 @@ The map returned by :meth:`to_map` and expected as argument by
.. autoclass:: View
-.. automethod:: View.to_map
-
.. automethod:: View.create
.. automethod:: View.diff_map
View
@@ -73,8 +73,6 @@ represents an `enumerated type
.. autoclass:: Enum
-.. automethod:: Enum.to_map
-
.. automethod:: Enum.create
Domain
@@ -57,7 +57,17 @@ class DbObject(object):
"A single object in a database catalog, e.g., a schema, a table, a column"
keylist = ['name']
+ """List of attributes that uniquely identify the object in the catalogs
+
+ See description of :meth:`key` for further details.
+ """
+
objtype = ''
+ """Type of object as an uppercase string, for SQL syntax generation
+
+ This is used in most CREATE, ALTER and DROP statements. It is
+ also used by :meth:`extern_key` in lowercase form.
+ """
def __init__(self, **attrs):
"""Initialize the catalog object from a dictionary of attributes
@@ -74,13 +84,39 @@ def extern_key(self):
"""Return the key to be used in external maps for this object
:return: string
+
+ This is used for the first two levels of external maps. The
+ first level is the one that includes schemas, as well as
+ (procedural) languages and casts. The second level includes
+ all schema-owned objects, i.e., tables, functions, operators,
+ etc. All subsequent levels, e.g., primary keys, indexes,
+ etc., currently use the object name as the external
+ identifier, appearing in the map after an object grouping
+ header, such as ``primary_key``.
+
+ The common format for an external key is `object-type
+ non-schema-qualified-name`, where `object-type` is the
+ lowercase version of :attr:`objtype`, e.g., ``table
+ tablename``. Some object types require more, e.g., functions
+ need the signature, so they override this implementation.
"""
return '%s %s' % (self.objtype.lower(), self.name)
def key(self):
"""Return a tuple that identifies the database object
- :return: a single value or a tuple
+ :return: a single string or a tuple of strings
+
+ This is used as key for all internal maps. The first-level
+ objects (schemas, languages and casts) use the object name as
+ the key. Second-level (schema-owned) objects usually use the
+ schema name and the object name as the key. Some object types
+ need longer keys, e.g., operators need schema name, operator
+ symbols, left argument and right argument.
+
+ Each class implementing an object type specifies a
+ :attr:`keylist` attribute, i.e., a list giving the names of
+ attributes making up the key.
"""
lst = [getattr(self, k) for k in self.keylist]
return len(lst) == 1 and lst[0] or tuple(lst)
@@ -89,21 +125,38 @@ def identifier(self):
"""Returns a full identifier for the database object
:return: string
+
+ This is used by :meth:`comment` and :meth:`drop` to generate
+ SQL syntax referring to the object. It does not include the
+ object type, but it may include (in overriden methods) other
+ elements, e.g., the arguments to a function.
"""
return quote_id(self.__dict__[self.keylist[0]])
+ def _base_map(self):
+ """Return a base map, i.e., copy of attributes excluding keys
+
+ :return: dictionary
+ """
+ dct = self.__dict__.copy()
+ for key in self.keylist:
+ del dct[key]
+ return dct
+
def to_map(self):
"""Convert an object to a YAML-suitable format
:return: dictionary
+
+ This base implementation simply copies the internal Python
+ dictionary, removes the :attr:`keylist` attributes, and
+ returns a new dictionary using the :meth:`extern_key` result
+ as the key.
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
- return {self.extern_key(): dct}
+ return {self.extern_key(): self._base_map()}
def comment(self):
- """Return SQL statement to create COMMENT on object
+ """Return SQL statement to create a COMMENT on the object
:return: SQL statement
"""
@@ -137,7 +190,7 @@ def diff_map(self, inobj):
Compares the object to an input object and generates SQL
statements to transform it into the one represented by the
- input.
+ input. This base implementation simply deals with comments.
"""
stmts = []
stmts.append(self.diff_description(inobj))
@@ -210,7 +263,10 @@ def rename(self, newname):
newname)
def set_search_path(self):
- """Return a SQL SET search_path if not in the 'public' schema"""
+ """Return a SQL SET search_path if not in the 'public' schema
+
+ :return: SQL statement
+ """
stmt = ''
if self.schema != 'public':
stmt = "SET search_path TO %s, pg_catalog" % quote_id(self.schema)
@@ -221,7 +277,13 @@ class DbObjectDict(dict):
"""A dictionary of database objects, all of the same type"""
cls = DbObject
+ """The class, derived from :class:`DbObject` that the objects belong to.
+ """
query = ''
+ """The SQL SELECT query to fetch object instances from the catalogs
+
+ This is used by the method :meth:`fetch`.
+ """
def __init__(self, dbconn=None):
"""Initialize the dictionary
@@ -245,7 +307,7 @@ def _from_catalog(self):
self[obj.key()] = obj
def fetch(self):
- """Fetch all objects from the catalogs using the class query
+ """Fetch all objects from the catalogs using the class :attr:`query`
:return: list of self.cls objects
"""
View
@@ -24,7 +24,7 @@ def extern_key(self):
:return: string
"""
- return '%s (%s AS %s)' % (self.objtype.lower(), self.source,
+ return '%s (%s as %s)' % (self.objtype.lower(), self.source,
self.target)
def identifier(self):
@@ -39,9 +39,7 @@ def to_map(self):
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
dct['context'] = CONTEXTS[self.context]
dct['method'] = METHODS[self.method]
return {self.extern_key(): dct}
@@ -21,9 +21,7 @@ def to_map(self):
"""
if hasattr(self, 'dropped'):
return None
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
del dct['number'], dct['name'], dct['_table']
if hasattr(self, 'inherited'):
dct['inherited'] = (self.inherited != 0)
@@ -84,9 +84,7 @@ def to_map(self, dbcols):
:param dbcols: dictionary of dbobject columns
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
if 'target' in dct:
del dct['target']
if dbcols:
@@ -132,9 +130,7 @@ def to_map(self, dbcols):
:param dbcols: dictionary of dbobject columns
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
dct['columns'] = [dbcols[k - 1] for k in self.keycols]
del dct['keycols']
return {self.name: dct}
@@ -173,9 +169,7 @@ def to_map(self, dbcols, refcols):
:param dbcols: dictionary of dbobject columns
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
dct['columns'] = [dbcols[k - 1] for k in self.keycols]
del dct['keycols']
refsch = hasattr(self, 'ref_schema') and self.ref_schema or self.schema
@@ -229,10 +223,7 @@ def to_map(self, dbcols):
:param dbcols: dictionary of dbobject columns
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
-
+ dct = self._base_map()
dct['columns'] = []
dct['columns'] = [dbcols[k - 1] for k in self.keycols]
del dct['keycols']
@@ -15,16 +15,6 @@ class Conversion(DbSchemaObject):
keylist = ['schema', 'name']
objtype = "CONVERSION"
- def to_map(self):
- """Convert conversion to a YAML-suitable format
-
- :return: dictionary
- """
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
- return {self.extern_key(): dct}
-
def create(self):
"""Return SQL statements to CREATE the conversion
View
@@ -46,9 +46,7 @@ def to_map(self):
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
del dct['dep_funcs']
if self.internallength < 0:
dct['internallength'] = 'variable'
@@ -132,16 +130,6 @@ def create(self):
class Enum(DbType):
"An enumerated type definition"
- def to_map(self):
- """Convert a type to a YAML-suitable format
-
- :return: dictionary
- """
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
- return {self.extern_key(): dct}
-
def create(self):
"""Return SQL statements to CREATE the enum
@@ -166,9 +154,7 @@ def to_map(self):
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
if hasattr(self, 'check_constraints'):
if not 'check_constraints' in dct:
dct.update(check_constraints={})
@@ -43,9 +43,7 @@ def to_map(self):
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
if self.volatility == 'v':
del dct['volatility']
else:
@@ -136,9 +134,7 @@ def to_map(self):
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
del dct['language']
return {self.extern_key(): dct}
@@ -30,9 +30,7 @@ def to_map(self, dbcols):
:param dbcols: dictionary of dbobject columns
:return: dictionary
"""
- dct = self.__dict__.copy()
- for k in self.keylist:
- del dct[k]
+ dct = self._base_map()
if hasattr(self, 'keycols'):
dct['columns'] = [dbcols[int(k) - 1] for k in self.keycols.split()]
del dct['keycols']
Oops, something went wrong.

0 comments on commit 3163e20

Please sign in to comment.