From: Mike Bayer Date: Sun, 10 Nov 2013 00:42:01 +0000 (-0500) Subject: - add a new sphinx extension "viewsource". takes advantage of part of the viewcode... X-Git-Tag: rel_0_9_0~131 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=546015e6e147130c4f21c87ec9e1537d9f71c3fb;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - add a new sphinx extension "viewsource". takes advantage of part of the viewcode extension to allow ad-hoc display of the source of any file, as well as a "directory listing" structure. - reorganize examples/ to take advantage of new extension. in particular, keep moving all the descriptive text for files etc. into module docstrings, taking more advantage of self-documentation. --- diff --git a/doc/build/builder/viewsource.py b/doc/build/builder/viewsource.py new file mode 100644 index 0000000000..399908504b --- /dev/null +++ b/doc/build/builder/viewsource.py @@ -0,0 +1,201 @@ +from docutils import nodes +from sphinx.ext.viewcode import collect_pages +from sphinx.pycode import ModuleAnalyzer +import imp +from sphinx import addnodes +import re +from sphinx.util.compat import Directive +import os +from docutils.statemachine import StringList +from sphinx.environment import NoUri + +def view_source(name, rawtext, text, lineno, inliner, + options={}, content=[]): + + env = inliner.document.settings.env + + node = _view_source_node(env, text, None) + return [node], [] + +def _view_source_node(env, text, state): + # pretend we're using viewcode fully, + # install the context it looks for + if not hasattr(env, '_viewcode_modules'): + env._viewcode_modules = {} + + modname = text + text = modname.split(".")[-1] + ".py" + + # imitate sphinx . syntax + if modname.startswith("."): + # see if the modname needs to be corrected in terms + # of current module context + base_module = env.temp_data.get('autodoc:module') + if base_module is None: + base_module = env.temp_data.get('py:module') + + if base_module: + modname = base_module + modname + + urito = env.app.builder.get_relative_uri + + # we're showing code examples which may have dependencies + # which we really don't want to have required so load the + # module by file, not import (though we are importing) + # the top level module here... + pathname = None + for token in modname.split("."): + file_, pathname, desc = imp.find_module(token, [pathname] if pathname else None) + if file_: + file_.close() + + # unlike viewcode which silently traps exceptions, + # I want this to totally barf if the file can't be loaded. + # a failed build better than a complete build missing + # key content + analyzer = ModuleAnalyzer.for_file(pathname, modname) + # copied from viewcode + analyzer.find_tags() + if not isinstance(analyzer.code, unicode): + code = analyzer.code.decode(analyzer.encoding) + else: + code = analyzer.code + + if state is not None: + docstring = _find_mod_docstring(analyzer) + if docstring: + # get rid of "foo.py" at the top + docstring = re.sub(r"^[a-zA-Z_0-9]+\.py", "", docstring) + + # strip + docstring = docstring.strip() + + # yank only first paragraph + docstring = docstring.split("\n\n")[0].strip() + else: + docstring = None + + entry = code, analyzer.tags, {} + env._viewcode_modules[modname] = entry + pagename = '_modules/' + modname.replace('.', '/') + + try: + refuri = urito(env.docname, pagename) + except NoUri: + # if we're in the latex builder etc., this seems + # to be what we get + refuri = None + + + if docstring: + # embed the ref with the doc text so that it isn't + # a separate paragraph + if refuri: + docstring = "`%s <%s>`_ - %s" % (text, refuri, docstring) + else: + docstring = "``%s`` - %s" % (text, docstring) + para = nodes.paragraph('', '') + state.nested_parse(StringList([docstring]), 0, para) + return_node = para + else: + if refuri: + refnode = nodes.reference('', '', + nodes.Text(text, text), + refuri=urito(env.docname, pagename) + ) + else: + refnode = nodes.Text(text, text) + + if state: + return_node = nodes.paragraph('', '', refnode) + else: + return_node = refnode + + return return_node + +from sphinx.pycode.pgen2 import token + +def _find_mod_docstring(analyzer): + """attempt to locate the module-level docstring. + + Note that sphinx autodoc just uses ``__doc__``. But we don't want + to import the module, so we need to parse for it. + + """ + analyzer.tokenize() + for type_, parsed_line, start_pos, end_pos, raw_line in analyzer.tokens: + if type_ == token.COMMENT: + continue + elif type_ == token.STRING: + return eval(parsed_line) + else: + return None + +def _parse_content(content): + d = {} + d['text'] = [] + idx = 0 + for line in content: + idx += 1 + m = re.match(r' *\:(.+?)\:(?: +(.+))?', line) + if m: + attrname, value = m.group(1, 2) + d[attrname] = value or '' + else: + break + d["text"] = content[idx:] + return d + +def _comma_list(text): + return re.split(r"\s*,\s*", text.strip()) + +class AutoSourceDirective(Directive): + has_content = True + + def run(self): + content = _parse_content(self.content) + + + env = self.state.document.settings.env + self.docname = env.docname + + sourcefile = self.state.document.current_source.split(":")[0] + dir_ = os.path.dirname(sourcefile) + files = [ + f for f in os.listdir(dir_) if f.endswith(".py") + and f != "__init__.py" + ] + + if "files" in content: + # ordered listing of files to include + files = [fname for fname in _comma_list(content["files"]) + if fname in set(files)] + + node = nodes.paragraph('', '', + nodes.Text("Listing of files:", "Listing of files:") + ) + + bullets = nodes.bullet_list() + for fname in files: + modname, ext = os.path.splitext(fname) + # relative lookup + modname = "." + modname + + link = _view_source_node(env, modname, self.state) + + list_node = nodes.list_item('', + link + ) + bullets += list_node + + node += bullets + + return [node] + +def setup(app): + app.add_role('viewsource', view_source) + + app.add_directive('autosource', AutoSourceDirective) + + # from sphinx.ext.viewcode + app.connect('html-collect-pages', collect_pages) diff --git a/doc/build/conf.py b/doc/build/conf.py index e08b018481..efc9e217f4 100644 --- a/doc/build/conf.py +++ b/doc/build/conf.py @@ -18,7 +18,7 @@ import os # 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('../../lib')) -sys.path.insert(0, os.path.abspath('../../examples')) +sys.path.insert(0, os.path.abspath('../..')) # examples sys.path.insert(0, os.path.abspath('.')) import sqlalchemy @@ -38,6 +38,7 @@ extensions = [ 'builder.dialect_info', 'builder.mako', 'builder.sqlformatter', + 'builder.viewsource', ] # Add any paths that contain templates here, relative to this directory. diff --git a/doc/build/orm/examples.rst b/doc/build/orm/examples.rst index e0c87dadf7..60d075a369 100644 --- a/doc/build/orm/examples.rst +++ b/doc/build/orm/examples.rst @@ -12,23 +12,20 @@ each of which are listed below. Additional SQLAlchemy examples, some user contributed, are available on the wiki at ``_. + .. _examples_adjacencylist: Adjacency List -------------- -Location: /examples/adjacency_list/ - -.. automodule:: adjacency_list +.. automodule:: examples.adjacency_list .. _examples_associations: Associations ------------ -Location: /examples/association/ - -.. automodule:: association +.. automodule:: examples.association .. _examples_instrumentation: @@ -36,105 +33,74 @@ Location: /examples/association/ Attribute Instrumentation ------------------------- -Location: /examples/custom_attributes/ - -.. automodule:: custom_attributes +.. automodule:: examples.custom_attributes .. _examples_caching: Dogpile Caching --------------- -Location: /examples/dogpile_caching/ - -.. automodule:: dogpile_caching +.. automodule:: examples.dogpile_caching Directed Graphs --------------- -Location: /examples/graphs/ - -.. automodule:: graphs +.. automodule:: examples.graphs Dynamic Relations as Dictionaries ---------------------------------- -Location: /examples/dynamic_dict/ - -.. automodule:: dynamic_dict +.. automodule:: examples.dynamic_dict .. _examples_generic_associations: Generic Associations -------------------- -Location: /examples/generic_associations - -.. automodule:: generic_associations +.. automodule:: examples.generic_associations .. _examples_sharding: Horizontal Sharding ------------------- -Location: /examples/sharding - -.. automodule:: sharding +.. automodule:: examples.sharding Inheritance Mappings -------------------- -Location: /examples/inheritance/ - -.. automodule:: inheritance +.. automodule:: examples.inheritance Large Collections ----------------- -Location: /examples/large_collection/ - -.. automodule:: large_collection +.. automodule:: examples.large_collection Nested Sets ----------- -Location: /examples/nested_sets/ - -.. automodule:: nested_sets - -Polymorphic Associations ------------------------- - -See :ref:`examples_generic_associations` for a modern version of polymorphic associations. +.. automodule:: examples.nested_sets .. _examples_postgis: PostGIS Integration ------------------- -Location: /examples/postgis - -.. automodule:: postgis +.. automodule:: examples.postgis Versioned Objects ----------------- -Location: /examples/versioning - -.. automodule:: versioning +.. automodule:: examples.versioning Vertical Attribute Mapping -------------------------- -Location: /examples/vertical - -.. automodule:: vertical +.. automodule:: examples.vertical .. _examples_xmlpersistence: XML Persistence --------------- -Location: /examples/elementtree/ - -.. automodule:: elementtree +.. automodule:: examples.elementtree diff --git a/examples/adjacency_list/__init__.py b/examples/adjacency_list/__init__.py index 44f27090bf..5d80363e4a 100644 --- a/examples/adjacency_list/__init__.py +++ b/examples/adjacency_list/__init__.py @@ -12,5 +12,7 @@ E.g.:: dump_tree(node) +.. autosource:: + """ diff --git a/examples/association/__init__.py b/examples/association/__init__.py index df736f4fbd..4cd64c22f8 100644 --- a/examples/association/__init__.py +++ b/examples/association/__init__.py @@ -1,20 +1,8 @@ """ - Examples illustrating the usage of the "association object" pattern, where an intermediary class mediates the relationship between two classes that are associated in a many-to-many pattern. -This directory includes the following examples: - -* basic_association.py - illustrate a many-to-many relationship between an - "Order" and a collection of "Item" objects, associating a purchase price - with each via an association object called "OrderItem" -* proxied_association.py - same example as basic_association, adding in - usage of :mod:`sqlalchemy.ext.associationproxy` to make explicit references - to "OrderItem" optional. -* dict_of_sets_with_default.py - an advanced association proxy example which - illustrates nesting of association proxies to produce multi-level Python - collections, in this case a dictionary with string keys and sets of integers - as values, which conceal the underlying mapped classes. +.. autosource:: """ \ No newline at end of file diff --git a/examples/association/basic_association.py b/examples/association/basic_association.py index a175b1b897..8a8a54ad1c 100644 --- a/examples/association/basic_association.py +++ b/examples/association/basic_association.py @@ -1,4 +1,8 @@ -"""A basic example of using the association object pattern. +"""basic_association.py + +illustrate a many-to-many relationship between an +"Order" and a collection of "Item" objects, associating a purchase price +with each via an association object called "OrderItem" The association object pattern is a form of many-to-many which associates additional data with each association between parent/child. diff --git a/examples/association/dict_of_sets_with_default.py b/examples/association/dict_of_sets_with_default.py index f541727e75..fc4aebfca5 100644 --- a/examples/association/dict_of_sets_with_default.py +++ b/examples/association/dict_of_sets_with_default.py @@ -1,4 +1,9 @@ -"""Illustrate a 'dict of sets of integers' model. +"""dict_of_sets_with_default.py + +an advanced association proxy example which +illustrates nesting of association proxies to produce multi-level Python +collections, in this case a dictionary with string keys and sets of integers +as values, which conceal the underlying mapped classes. This is a three table model which represents a parent table referencing a dictionary of string keys and sets as values, where each set stores a diff --git a/examples/association/proxied_association.py b/examples/association/proxied_association.py index 4cf1c51be7..7cb4c93382 100644 --- a/examples/association/proxied_association.py +++ b/examples/association/proxied_association.py @@ -1,5 +1,9 @@ -"""An extension to the basic_association.py example, which illustrates -the usage of sqlalchemy.ext.associationproxy. +"""proxied_association.py + +same example as basic_association, adding in +usage of :mod:`sqlalchemy.ext.associationproxy` to make explicit references +to ``OrderItem`` optional. + """ diff --git a/examples/custom_attributes/__init__.py b/examples/custom_attributes/__init__.py index b28e97d957..2072c051f3 100644 --- a/examples/custom_attributes/__init__.py +++ b/examples/custom_attributes/__init__.py @@ -2,18 +2,6 @@ Two examples illustrating modifications to SQLAlchemy's attribute management system. -``listen_for_events.py`` illustrates the usage of -:class:`~sqlalchemy.orm.interfaces.AttributeExtension` to intercept attribute -events. It additionally illustrates a way to automatically attach these -listeners to all class attributes using a -:class:`.InstrumentationManager`. - -``custom_management.py`` illustrates much deeper usage of -:class:`.InstrumentationManager` as well as -collection adaptation, to completely change the underlying method used to -store state on an object. This example was developed to illustrate -techniques which would be used by other third party object instrumentation -systems to interact with SQLAlchemy's event system and is only intended for -very intricate framework integrations. +.. autosource:: """ \ No newline at end of file diff --git a/examples/dogpile_caching/__init__.py b/examples/dogpile_caching/__init__.py index 00c386bda9..2d986584b5 100644 --- a/examples/dogpile_caching/__init__.py +++ b/examples/dogpile_caching/__init__.py @@ -50,35 +50,9 @@ The demo scripts themselves, in order of complexity, are run as follows:: python examples/dogpile_caching/local_session_caching.py - -Listing of files: - - environment.py - Establish the Session, a dictionary - of "regions", a sample cache region against a .dbm - file, data / cache file paths, and configurations, - bootstrap fixture data if necessary. - - caching_query.py - Represent functions and classes - which allow the usage of Dogpile caching with SQLAlchemy. - Introduces a query option called FromCache. - - model.py - The datamodel, which represents Person that has multiple - Address objects, each with PostalCode, City, Country - - fixture_data.py - creates demo PostalCode, Address, Person objects - in the database. - - helloworld.py - the basic idea. - - relationship_caching.py - Illustrates how to add cache options on - relationship endpoints, so that lazyloads load from cache. - - advanced.py - Further examples of how to use FromCache. Combines - techniques from the first two scripts. - - local_session_caching.py - Grok everything so far ? This example - creates a new dogpile.cache backend that will persist data in a dictionary - which is local to the current session. remove() the session - and the cache is gone. +.. autosource:: + :files: environment.py, caching_query.py, model.py, fixture_data.py, \ + helloworld.py, relationship_caching.py, advanced.py, \ + local_session_caching.py """ diff --git a/examples/dogpile_caching/caching_query.py b/examples/dogpile_caching/caching_query.py index 7fe84bede0..9ac0d431ab 100644 --- a/examples/dogpile_caching/caching_query.py +++ b/examples/dogpile_caching/caching_query.py @@ -1,7 +1,8 @@ """caching_query.py -Represent persistence structures which allow the usage of -dogpile.cache caching with SQLAlchemy. +Represent functions and classes +which allow the usage of Dogpile caching with SQLAlchemy. +Introduces a query option called FromCache. The three new concepts introduced here are: diff --git a/examples/dogpile_caching/local_session_caching.py b/examples/dogpile_caching/local_session_caching.py index cf0083d2e7..e6c712b4af 100644 --- a/examples/dogpile_caching/local_session_caching.py +++ b/examples/dogpile_caching/local_session_caching.py @@ -1,5 +1,10 @@ """local_session_caching.py +Grok everything so far ? This example +creates a new dogpile.cache backend that will persist data in a dictionary +which is local to the current session. remove() the session +and the cache is gone. + Create a new Dogpile cache backend that will store cached data local to the current Session. diff --git a/examples/dogpile_caching/model.py b/examples/dogpile_caching/model.py index 622d31e6ac..75c0ad28a8 100644 --- a/examples/dogpile_caching/model.py +++ b/examples/dogpile_caching/model.py @@ -1,6 +1,7 @@ -"""Model. We are modeling Person objects with a collection -of Address objects. Each Address has a PostalCode, which -in turn references a City and then a Country: +"""model.py + +The datamodel, which represents Person that has multiple +Address objects, each with PostalCode, City, Country. Person --(1..n)--> Address Address --(has a)--> PostalCode diff --git a/examples/dogpile_caching/relation_caching.py b/examples/dogpile_caching/relationship_caching.py similarity index 90% rename from examples/dogpile_caching/relation_caching.py rename to examples/dogpile_caching/relationship_caching.py index d40752e483..320ced48a8 100644 --- a/examples/dogpile_caching/relation_caching.py +++ b/examples/dogpile_caching/relationship_caching.py @@ -1,5 +1,8 @@ """relationship_caching.py +Illustrates how to add cache options on +relationship endpoints, so that lazyloads load from cache. + Load a set of Person and Address objects, specifying that related PostalCode, City, Country objects should be pulled from long term cache. diff --git a/examples/dynamic_dict/__init__.py b/examples/dynamic_dict/__init__.py index 7f7b0691d3..e592ea2005 100644 --- a/examples/dynamic_dict/__init__.py +++ b/examples/dynamic_dict/__init__.py @@ -3,4 +3,6 @@ string keys) can operate upon a large collection without loading the full collection at once. +.. autosource:: + """ \ No newline at end of file diff --git a/examples/elementtree/__init__.py b/examples/elementtree/__init__.py index 6462dd5629..66e9cfbbe3 100644 --- a/examples/elementtree/__init__.py +++ b/examples/elementtree/__init__.py @@ -7,26 +7,6 @@ native cElementTree as well as lxml, and can be adapted to suit any kind of DOM representation system. Querying along xpath-like strings is illustrated as well. -In order of complexity: - -* ``pickle.py`` - Quick and dirty, serialize the whole DOM into a BLOB - column. While the example is very brief, it has very limited - functionality. - -* ``adjacency_list.py`` - Each DOM node is stored in an individual - table row, with attributes represented in a separate table. The - nodes are associated in a hierarchy using an adjacency list - structure. A query function is introduced which can search for nodes - along any path with a given structure of attributes, basically a - (very narrow) subset of xpath. - -* ``optimized_al.py`` - Uses the same strategy as - ``adjacency_list.py``, but associates each DOM row with its owning - document row, so that a full document of DOM nodes can be loaded - using O(1) queries - the construction of the "hierarchy" is performed - after the load in a non-recursive fashion and is much more - efficient. - E.g.:: # parse an XML file and persist in the database @@ -39,4 +19,7 @@ E.g.:: # dump the XML print document +.. autosource:: + :files: pickle.py, adjacency_list.py, optimized_al.py + """ \ No newline at end of file diff --git a/examples/elementtree/adjacency_list.py b/examples/elementtree/adjacency_list.py index a3ad42778b..5e27ba9cae 100644 --- a/examples/elementtree/adjacency_list.py +++ b/examples/elementtree/adjacency_list.py @@ -1,9 +1,17 @@ -"""illustrates an explicit way to persist an XML document expressed using ElementTree. +"""Illustrates an explicit way to persist an XML document expressed using ElementTree. + +Each DOM node is stored in an individual +table row, with attributes represented in a separate table. The +nodes are associated in a hierarchy using an adjacency list +structure. A query function is introduced which can search for nodes +along any path with a given structure of attributes, basically a +(very narrow) subset of xpath. This example explicitly marshals/unmarshals the ElementTree document into mapped entities which have their own tables. Compare to pickle.py which uses pickle to accomplish the same task. Note that the usage of both styles of persistence are identical, as is the structure of the main Document class. + """ ################################# PART I - Imports/Coniguration #################################### diff --git a/examples/elementtree/optimized_al.py b/examples/elementtree/optimized_al.py index 1dbad09434..e13f5b0eed 100644 --- a/examples/elementtree/optimized_al.py +++ b/examples/elementtree/optimized_al.py @@ -1,7 +1,9 @@ -"""This script duplicates adjacency_list.py, but optimizes the loading -of XML nodes to be based on a "flattened" datamodel. Any number of XML documents, -each of arbitrary complexity, can be loaded in their entirety via a single query -which joins on only three tables. +"""Uses the same strategy as + ``adjacency_list.py``, but associates each DOM row with its owning + document row, so that a full document of DOM nodes can be loaded + using O(1) queries - the construction of the "hierarchy" is performed + after the load in a non-recursive fashion and is more + efficient. """ diff --git a/examples/generic_associations/__init__.py b/examples/generic_associations/__init__.py index 2121e8b603..b6593b4f46 100644 --- a/examples/generic_associations/__init__.py +++ b/examples/generic_associations/__init__.py @@ -9,19 +9,10 @@ subclassing the ``HasAddresses`` mixin, which ensures that the parent class is provided with an ``addresses`` collection which contains ``Address`` objects. -The configurations include: - -* ``table_per_related.py`` - illustrates a distinct table per related collection. -* ``table_per_association.py`` - illustrates a shared collection table, using a - table per association. -* ``discriminator_on_association.py`` - shared collection table and shared - association table, including a discriminator column. -* ``generic_fk.py`` - imitates the approach taken by popular frameworks such - as Django and Ruby on Rails to create a so-called "generic foreign key". - -The ``discriminator_on_association.py`` and ``generic_fk.py`` scripts +The :viewsource:`.discriminator_on_association` and :viewsource:`.generic_fk` scripts are modernized versions of recipes presented in the 2007 blog post `Polymorphic Associations with SQLAlchemy `_. -. + +.. autosource:: """ \ No newline at end of file diff --git a/examples/generic_associations/discriminator_on_association.py b/examples/generic_associations/discriminator_on_association.py index 9968810d55..e03cfec009 100644 --- a/examples/generic_associations/discriminator_on_association.py +++ b/examples/generic_associations/discriminator_on_association.py @@ -1,17 +1,15 @@ """discriminator_on_related.py -The HasAddresses mixin will provide a relationship -to the fixed Address table based on a fixed association table. - -The association table contains a "discriminator" -which determines what type of parent object associates to the -Address row. SQLAlchemy's single-table-inheritance feature is used +Illustrates a mixin which provides a generic association +using a single target table and a single association table, +referred to by all parent tables. The association table +contains a "discriminator" column which determines what type of +parent object associates to each particular row in the association +table. + +SQLAlchemy's single-table-inheritance feature is used to target different association types. -This is a "polymorphic association". Even though a "discriminator" -that refers to a particular table is present, the extra association -table is used so that traditional foreign key constraints may be used. - This configuration attempts to simulate a so-called "generic foreign key" as closely as possible without actually foregoing the use of real foreign keys. Unlike table-per-related and table-per-association, diff --git a/examples/generic_associations/generic_fk.py b/examples/generic_associations/generic_fk.py index b92a28f602..e228c6ba4a 100644 --- a/examples/generic_associations/generic_fk.py +++ b/examples/generic_associations/generic_fk.py @@ -1,12 +1,11 @@ """generic_fk.py -This example will emulate key aspects of the system used by popular -frameworks such as Django, ROR, etc. - -It approaches the issue by bypassing standard referential integrity -practices, and producing a so-called "generic foreign key", which means -a database column that is not constrained to refer to any particular table. -In-application logic is used to determine which table is referenced. +Illustrates a so-called "generic foreign key", in a similar fashion +to that of popular frameworks such as Django, ROR, etc. This +approach bypasses standard referential integrity +practices, in that the "foreign key" column is not actually +constrained to refer to any particular table; instead, +in-application logic is used to determine which table is referenced. This approach is not in line with SQLAlchemy's usual style, as foregoing foreign key integrity means that the tables can easily contain invalid diff --git a/examples/generic_associations/table_per_association.py b/examples/generic_associations/table_per_association.py index 4cdc354941..4993492a46 100644 --- a/examples/generic_associations/table_per_association.py +++ b/examples/generic_associations/table_per_association.py @@ -1,8 +1,9 @@ """table_per_association.py -The HasAddresses mixin will provide a new "address_association" table for -each parent class. The "address" table will be shared -for all parents. +Illustrates a mixin which provides a generic association +via a individually generated association tables for each parent class. +The associated objects themselves are persisted in a single table +shared among all parents. This configuration has the advantage that all Address rows are in one table, so that the definition of "Address" diff --git a/examples/generic_associations/table_per_related.py b/examples/generic_associations/table_per_related.py index 8823cd3888..aff6e40ce6 100644 --- a/examples/generic_associations/table_per_related.py +++ b/examples/generic_associations/table_per_related.py @@ -1,7 +1,8 @@ """table_per_related.py -The HasAddresses mixin will provide a new "address" table for -each parent class, as well as a distinct "Address" subclass. +Illustrates a generic association which persists association +objects within individual tables, each one generated to persist +those objects on behalf of a particular parent class. This configuration has the advantage that each type of parent maintains its "Address" rows separately, so that collection diff --git a/examples/graphs/__init__.py b/examples/graphs/__init__.py index 629808abe9..57d41453b0 100644 --- a/examples/graphs/__init__.py +++ b/examples/graphs/__init__.py @@ -8,4 +8,6 @@ and querying for lower- and upper- neighbors are illustrated:: n2.add_neighbor(n5) print n2.higher_neighbors() +.. autosource:: + """ \ No newline at end of file diff --git a/examples/inheritance/__init__.py b/examples/inheritance/__init__.py index 09519a679b..eb3e843ca3 100644 --- a/examples/inheritance/__init__.py +++ b/examples/inheritance/__init__.py @@ -1,4 +1,6 @@ """Working examples of single-table, joined-table, and concrete-table inheritance as described in :ref:`datamapping_inheritance`. +.. autosource:: + """ \ No newline at end of file diff --git a/examples/inheritance/concrete.py b/examples/inheritance/concrete.py index b05afa5ea7..f9bdc81b4f 100644 --- a/examples/inheritance/concrete.py +++ b/examples/inheritance/concrete.py @@ -1,3 +1,5 @@ +"""Concrete (table-per-class) inheritance example.""" + from sqlalchemy import create_engine, MetaData, Table, Column, Integer, \ String from sqlalchemy.orm import mapper, sessionmaker, polymorphic_union diff --git a/examples/inheritance/joined.py b/examples/inheritance/joined.py index 8283ef05d9..6e0205e04e 100644 --- a/examples/inheritance/joined.py +++ b/examples/inheritance/joined.py @@ -1,4 +1,4 @@ -"""this example illustrates a polymorphic load of two classes""" +"""Joined-table (table-per-subclass) inheritance example.""" from sqlalchemy import Table, Column, Integer, String, \ ForeignKey, create_engine, inspect, or_ diff --git a/examples/inheritance/single.py b/examples/inheritance/single.py index b445f74a6f..22a6fe027d 100644 --- a/examples/inheritance/single.py +++ b/examples/inheritance/single.py @@ -1,3 +1,5 @@ +"""Single-table inheritance example.""" + from sqlalchemy import MetaData, Table, Column, Integer, String, \ ForeignKey, create_engine from sqlalchemy.orm import mapper, relationship, sessionmaker diff --git a/examples/large_collection/__init__.py b/examples/large_collection/__init__.py index 4098cd53a4..432d9196f2 100644 --- a/examples/large_collection/__init__.py +++ b/examples/large_collection/__init__.py @@ -9,4 +9,6 @@ objects is very large, including: ``passive_deletes=True`` to greatly improve the performance of related collection deletion. +.. autosource:: + """ diff --git a/examples/nested_sets/__init__.py b/examples/nested_sets/__init__.py index 1a97b9aef3..3e73bb13e9 100644 --- a/examples/nested_sets/__init__.py +++ b/examples/nested_sets/__init__.py @@ -1,4 +1,6 @@ """ Illustrates a rudimentary way to implement the "nested sets" pattern for hierarchical data using the SQLAlchemy ORM. +.. autosource:: + """ \ No newline at end of file diff --git a/examples/postgis/__init__.py b/examples/postgis/__init__.py index cec5ad48a3..250d9ce876 100644 --- a/examples/postgis/__init__.py +++ b/examples/postgis/__init__.py @@ -33,5 +33,7 @@ E.g.:: print session.query(Road).filter(Road.road_geom.intersects(r1.road_geom)).all() +.. autosource:: + """ diff --git a/examples/sharding/__init__.py b/examples/sharding/__init__.py index dacc815f9b..59d26a2175 100644 --- a/examples/sharding/__init__.py +++ b/examples/sharding/__init__.py @@ -27,4 +27,6 @@ is a simple method of assigning objects to different tables (and potentially database nodes) in an explicit way - described on the wiki at `EntityName `_. +.. autosource:: + """ diff --git a/examples/versioning/__init__.py b/examples/versioning/__init__.py index 4621fae3b3..a2a6a1813c 100644 --- a/examples/versioning/__init__.py +++ b/examples/versioning/__init__.py @@ -57,4 +57,6 @@ can be applied:: SomeHistoryClass = SomeClass.__history_mapper__.class_ +.. autosource:: + """ \ No newline at end of file diff --git a/examples/versioning/history_meta.py b/examples/versioning/history_meta.py index 5b0f1920fc..8cb5234343 100644 --- a/examples/versioning/history_meta.py +++ b/examples/versioning/history_meta.py @@ -1,3 +1,5 @@ +"""Versioned mixin class and other utilities.""" + from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.orm import mapper, class_mapper, attributes, object_mapper from sqlalchemy.orm.exc import UnmappedClassError, UnmappedColumnError diff --git a/examples/versioning/test_versioning.py b/examples/versioning/test_versioning.py index ca70c9ac01..9062805552 100644 --- a/examples/versioning/test_versioning.py +++ b/examples/versioning/test_versioning.py @@ -1,3 +1,5 @@ +"""Unit tests illustrating usage of the ``history_meta.py`` module functions.""" + from unittest import TestCase from sqlalchemy.ext.declarative import declarative_base from .history_meta import Versioned, versioned_session diff --git a/examples/vertical/__init__.py b/examples/vertical/__init__.py index 6073da91c9..0b69f32ea5 100644 --- a/examples/vertical/__init__.py +++ b/examples/vertical/__init__.py @@ -29,5 +29,6 @@ Example:: AnimalFact.value == True)))) print 'weasel-like animals', q.all() +.. autosource:: """ \ No newline at end of file