]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
update to new doc system
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 25 Oct 2012 19:49:44 +0000 (15:49 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 25 Oct 2012 19:49:44 +0000 (15:49 -0400)
24 files changed:
CHANGES
doc/build/builder/autodoc_mods.py [new file with mode: 0644]
doc/build/builder/builders.py [deleted file]
doc/build/builder/changelog.py [new file with mode: 0644]
doc/build/builder/dialect_info.py [new file with mode: 0644]
doc/build/builder/mako.py [new file with mode: 0644]
doc/build/builder/sqlformatter.py [new file with mode: 0644]
doc/build/changelog/changelog_01.rst [new file with mode: 0644]
doc/build/changelog/changelog_02.rst [new file with mode: 0644]
doc/build/changelog/changelog_03.rst [new file with mode: 0644]
doc/build/changelog/changelog_04.rst [new file with mode: 0644]
doc/build/changelog/changelog_05.rst [new file with mode: 0644]
doc/build/changelog/changelog_06.rst [new file with mode: 0644]
doc/build/changelog/changelog_07.rst [new file with mode: 0644]
doc/build/changelog/index.rst [new file with mode: 0644]
doc/build/changelog/migration_04.rst [new file with mode: 0644]
doc/build/changelog/migration_05.rst [new file with mode: 0644]
doc/build/changelog/migration_06.rst [new file with mode: 0644]
doc/build/changelog/migration_07.rst [new file with mode: 0644]
doc/build/conf.py
doc/build/index.rst
doc/build/intro.rst
doc/build/static/docs.css
test/orm/test_attributes.py

diff --git a/CHANGES b/CHANGES
index 0c795c27152695205469e582fb5672eb680fd922..e0d4d7c42445b33314ecea1492393fe97ca05643 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,12 @@ CHANGES
 =======
 0.7.10
 ======
+- changelog
+  - The changelog has been moved to the documentation.
+    This file will be maintained throughout remaining
+    0.7 maintenance for backwards compabitility, but
+    is removed in 0.8.
+
 - orm
   - [bug] Fixed Session accounting bug whereby replacing
     a deleted object in the identity map with another
diff --git a/doc/build/builder/autodoc_mods.py b/doc/build/builder/autodoc_mods.py
new file mode 100644 (file)
index 0000000..8c687fb
--- /dev/null
@@ -0,0 +1,47 @@
+import re
+
+def autodoc_skip_member(app, what, name, obj, skip, options):
+    if what == 'class' and skip and \
+        name in ('__init__', '__eq__', '__ne__', '__lt__',
+                    '__le__', '__call__') and \
+        obj.__doc__:
+        return False
+    else:
+        return skip
+
+# im sure this is in the app somewhere, but I don't really
+# know where, so we're doing it here.
+_track_autodoced = {}
+def autodoc_process_docstring(app, what, name, obj, options, lines):
+    if what == "class":
+        _track_autodoced[name] = obj
+    elif what in ("attribute", "method") and \
+        options.get("inherited-members"):
+        m = re.match(r'(.*?)\.([\w_]+)$', name)
+        if m:
+            clsname, attrname = m.group(1, 2)
+            if clsname in _track_autodoced:
+                cls = _track_autodoced[clsname]
+                for supercls in cls.__mro__:
+                    if attrname in supercls.__dict__:
+                        break
+                if supercls is not cls:
+                    lines[:0] = [
+                        ".. container:: inherited_member",
+                        "",
+                        "    *inherited from the* :%s:`.%s.%s` *%s of* :class:`.%s`" % (
+                                    "attr" if what == "attribute"
+                                    else "meth",
+                                    supercls.__name__,
+                                    attrname,
+                                    what,
+                                    supercls.__name__
+                                ),
+                        ""
+                    ]
+
+
+def setup(app):
+    app.connect('autodoc-skip-member', autodoc_skip_member)
+    app.connect('autodoc-process-docstring', autodoc_process_docstring)
+
diff --git a/doc/build/builder/builders.py b/doc/build/builder/builders.py
deleted file mode 100644 (file)
index 46469e3..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-from sphinx.application import TemplateBridge
-from sphinx.builders.html import StandaloneHTMLBuilder
-from sphinx.highlighting import PygmentsBridge
-from sphinx.jinja2glue import BuiltinTemplateLoader
-from pygments import highlight
-from pygments.lexer import RegexLexer, bygroups, using
-from pygments.token import *
-from pygments.filter import Filter, apply_filters
-from pygments.lexers import PythonLexer, PythonConsoleLexer
-from pygments.formatters import HtmlFormatter, LatexFormatter
-import re
-from mako.lookup import TemplateLookup
-from mako.template import Template
-from mako import __version__
-import os
-
-rtd = os.environ.get('READTHEDOCS', None) == 'True'
-
-class MakoBridge(TemplateBridge):
-    def init(self, builder, *args, **kw):
-        self.jinja2_fallback = BuiltinTemplateLoader()
-        self.jinja2_fallback.init(builder, *args, **kw)
-
-        builder.config.html_context['release_date'] = builder.config['release_date']
-        builder.config.html_context['site_base'] = builder.config['site_base']
-
-        self.lookup = TemplateLookup(directories=builder.config.templates_path,
-            #format_exceptions=True,
-            imports=[
-                "from builder import util"
-            ]
-        )
-
-        if rtd:
-            import urllib2
-            template_url = builder.config['site_base'] + "/docs_base.mako"
-            template = urllib2.urlopen(template_url).read()
-            self.lookup.put_string("/rtd_base.mako", template)
-
-    def render(self, template, context):
-        template = template.replace(".html", ".mako")
-        context['prevtopic'] = context.pop('prev', None)
-        context['nexttopic'] = context.pop('next', None)
-        version = context['version']
-        pathto = context['pathto']
-
-        # RTD layout
-        if rtd:
-            # add variables if not present, such
-            # as if local test of READTHEDOCS variable
-            if 'MEDIA_URL' not in context:
-                context['MEDIA_URL'] = "http://media.readthedocs.org/"
-            if 'slug' not in context:
-                context['slug'] = context['project'].lower()
-            if 'url' not in context:
-                context['url'] = "/some/test/url"
-            if 'current_version' not in context:
-                context['current_version'] = "latest"
-
-            if 'name' not in context:
-                context['name'] = context['project'].lower()
-
-            context['rtd'] = True
-            context['toolbar'] = True
-            context['layout'] = "rtd_layout.mako"
-            context['base'] = "rtd_base.mako"
-            context['pdf_url'] = "%spdf/%s/%s/%s.pdf" % (
-                    context['MEDIA_URL'],
-                    context['slug'],
-                    context['current_version'],
-                    context['slug']
-            )
-        # local docs layout
-        else:
-            context['rtd'] = False
-            context['toolbar'] = False
-            context['layout'] = "layout.mako"
-            context['base'] = "static_base.mako"
-
-        context.setdefault('_', lambda x:x)
-        return self.lookup.get_template(template).render_unicode(**context)
-
-    def render_string(self, template, context):
-        # this is used for  .js, .css etc. and we don't have
-        # local copies of that stuff here so use the jinja render.
-        return self.jinja2_fallback.render_string(template, context)
-
-class StripDocTestFilter(Filter):
-    def filter(self, lexer, stream):
-        for ttype, value in stream:
-            if ttype is Token.Comment and re.match(r'#\s*doctest:', value):
-                continue
-            yield ttype, value
-
-class PyConWithSQLLexer(RegexLexer):
-    name = 'PyCon+SQL'
-    aliases = ['pycon+sql']
-
-    flags = re.IGNORECASE | re.DOTALL
-
-    tokens = {
-            'root': [
-                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
-                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
-                (r'.*?\n', using(PythonConsoleLexer))
-            ],
-            'sqlpopup':[
-                (
-                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))',
-                    bygroups(using(PythonConsoleLexer), Token.Sql.Popup),
-                    "#pop"
-                )
-            ],
-            'opensqlpopup':[
-                (
-                    r'.*?(?:{stop}\n*|$)',
-                    Token.Sql,
-                    "#pop"
-                )
-            ]
-        }
-
-
-class PythonWithSQLLexer(RegexLexer):
-    name = 'Python+SQL'
-    aliases = ['pycon+sql']
-
-    flags = re.IGNORECASE | re.DOTALL
-
-    tokens = {
-            'root': [
-                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
-                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
-                (r'.*?\n', using(PythonLexer))
-            ],
-            'sqlpopup':[
-                (
-                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))',
-                    bygroups(using(PythonLexer), Token.Sql.Popup),
-                    "#pop"
-                )
-            ],
-            'opensqlpopup':[
-                (
-                    r'.*?(?:{stop}\n*|$)',
-                    Token.Sql,
-                    "#pop"
-                )
-            ]
-        }
-
-
-def _strip_trailing_whitespace(iter_):
-    buf = list(iter_)
-    if buf:
-        buf[-1] = (buf[-1][0], buf[-1][1].rstrip())
-    for t, v in buf:
-        yield t, v
-
-class PopupSQLFormatter(HtmlFormatter):
-    def _format_lines(self, tokensource):
-        buf = []
-        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
-            if ttype in Token.Sql:
-                for t, v in HtmlFormatter._format_lines(self, iter(buf)):
-                    yield t, v
-                buf = []
-
-                if ttype is Token.Sql:
-                    yield 1, "<div class='show_sql'>%s</div>" % re.sub(r'(?:[{stop}|\n]*)$', '', value)
-                elif ttype is Token.Sql.Link:
-                    yield 1, "<a href='#' class='sql_link'>sql</a>"
-                elif ttype is Token.Sql.Popup:
-                    yield 1, "<div class='popup_sql'>%s</div>" % re.sub(r'(?:[{stop}|\n]*)$', '', value)
-            else:
-                buf.append((ttype, value))
-
-        for t, v in _strip_trailing_whitespace(HtmlFormatter._format_lines(self, iter(buf))):
-            yield t, v
-
-class PopupLatexFormatter(LatexFormatter):
-    def _filter_tokens(self, tokensource):
-        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
-            if ttype in Token.Sql:
-                if ttype is not Token.Sql.Link and ttype is not Token.Sql.Open:
-                    yield Token.Literal, re.sub(r'{stop}', '', value)
-                else:
-                    continue
-            else:
-                yield ttype, value
-
-    def format(self, tokensource, outfile):
-        LatexFormatter.format(self, self._filter_tokens(tokensource), outfile)
-
-def autodoc_skip_member(app, what, name, obj, skip, options):
-    if what == 'class' and skip and \
-        name in ('__init__', '__eq__', '__ne__', '__lt__', '__le__', '__call__') and \
-        obj.__doc__:
-        return False
-    else:
-        return skip
-
-def setup(app):
-    app.add_lexer('pycon+sql', PyConWithSQLLexer())
-    app.add_lexer('python+sql', PythonWithSQLLexer())
-    app.add_config_value('release_date', "", True)
-    app.add_config_value('site_base', "", True)
-    app.add_config_value('build_number', "", 1)
-    app.connect('autodoc-skip-member', autodoc_skip_member)
-    PygmentsBridge.html_formatter = PopupSQLFormatter
-    PygmentsBridge.latex_formatter = PopupLatexFormatter
-
diff --git a/doc/build/builder/changelog.py b/doc/build/builder/changelog.py
new file mode 100644 (file)
index 0000000..85ae6db
--- /dev/null
@@ -0,0 +1,286 @@
+import re
+from sphinx.util.compat import Directive
+from docutils.statemachine import StringList
+from docutils import nodes, utils
+import textwrap
+import itertools
+import collections
+import md5
+
+def _comma_list(text):
+    return re.split(r"\s*,\s*", text.strip())
+
+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
+
+
+class EnvDirective(object):
+    @property
+    def env(self):
+        return self.state.document.settings.env
+
+class ChangeLogDirective(EnvDirective, Directive):
+    has_content = True
+
+    type_ = "change"
+
+    default_section = 'misc'
+
+    def _organize_by_section(self, changes):
+        compound_sections = [(s, s.split(" ")) for s in
+                                self.sections if " " in s]
+
+        bysection = collections.defaultdict(list)
+        all_sections = set()
+        for rec in changes:
+            inner_tag = rec['tags'].intersection(self.inner_tag_sort)
+            if inner_tag:
+                inner_tag = inner_tag.pop()
+            else:
+                inner_tag = ""
+
+            for compound, comp_words in compound_sections:
+                if rec['tags'].issuperset(comp_words):
+                    bysection[(compound, inner_tag)].append(rec)
+                    all_sections.add(compound)
+                    break
+            else:
+                intersect = rec['tags'].intersection(self.sections)
+                if intersect:
+                    for sec in rec['sorted_tags']:
+                        if sec in intersect:
+                            bysection[(sec, inner_tag)].append(rec)
+                            all_sections.add(sec)
+                            break
+                else:
+                    bysection[(self.default_section, inner_tag)].append(rec)
+        return bysection, all_sections
+
+    @classmethod
+    def changes(cls, env):
+        return env.temp_data['ChangeLogDirective_%s_changes' % cls.type_]
+
+    def _setup_run(self):
+        self.sections = self.env.config.changelog_sections
+        self.inner_tag_sort = self.env.config.changelog_inner_tag_sort + [""]
+        self.env.temp_data['ChangeLogDirective_%s_changes' % self.type_] = []
+        self._parsed_content = _parse_content(self.content)
+
+        p = nodes.paragraph('', '',)
+        self.state.nested_parse(self.content[1:], 0, p)
+
+    def run(self):
+        self._setup_run()
+        changes = self.changes(self.env)
+        output = []
+
+        self.version = version = self._parsed_content.get('version', '')
+        id_prefix = "%s-%s" % (self.type_, version)
+        topsection = self._run_top(id_prefix)
+        output.append(topsection)
+
+        bysection, all_sections = self._organize_by_section(changes)
+
+        counter = itertools.count()
+
+        sections_to_render = [s for s in self.sections if s in all_sections]
+        if not sections_to_render:
+            for cat in self.inner_tag_sort:
+                append_sec = self._append_node()
+
+                for rec in bysection[(self.default_section, cat)]:
+                    rec["id"] = "%s-%s" % (id_prefix, next(counter))
+
+                    self._render_rec(rec, None, cat, append_sec)
+
+                if append_sec.children:
+                    topsection.append(append_sec)
+        else:
+            for section in sections_to_render + [self.default_section]:
+                sec = nodes.section('',
+                        nodes.title(section, section),
+                        ids=["%s-%s" % (id_prefix, section.replace(" ", "-"))]
+                )
+
+                append_sec = self._append_node()
+                sec.append(append_sec)
+
+                for cat in self.inner_tag_sort:
+                    for rec in bysection[(section, cat)]:
+                        rec["id"] = "%s-%s" % (id_prefix, next(counter))
+                        self._render_rec(rec, section, cat, append_sec)
+
+                if append_sec.children:
+                    topsection.append(sec)
+
+        return output
+
+    def _append_node(self):
+        return nodes.bullet_list()
+
+    def _run_top(self, id_prefix):
+        version = self._parsed_content.get('version', '')
+        topsection = nodes.section('',
+                nodes.title(version, version),
+                ids=[id_prefix]
+            )
+
+        if self._parsed_content.get("released"):
+            topsection.append(nodes.Text("Released: %s" %
+                        self._parsed_content['released']))
+        else:
+            topsection.append(nodes.Text("no release date"))
+        return topsection
+
+
+    def _render_rec(self, rec, section, cat, append_sec):
+        para = rec['node'].deepcopy()
+
+        text = _text_rawsource_from_node(para)
+
+        to_hash = "%s %s" % (self.version, text[0:100])
+        targetid = "%s-%s" % (self.type_,
+                        md5.md5(to_hash.encode('ascii', 'ignore')
+                            ).hexdigest())
+        targetnode = nodes.target('', '', ids=[targetid])
+        para.insert(0, targetnode)
+        permalink = nodes.reference('', '',
+                        nodes.Text("(link)", "(link)"),
+                        refid=targetid,
+                        classes=['changeset-link']
+                    )
+        para.append(permalink)
+
+        insert_ticket = nodes.paragraph('')
+        para.append(insert_ticket)
+
+        i = 0
+        for collection, render, prefix in (
+                (rec['tickets'], self.env.config.changelog_render_ticket, "#%s"),
+                (rec['pullreq'], self.env.config.changelog_render_pullreq,
+                                            "pull request %s"),
+                (rec['changeset'], self.env.config.changelog_render_changeset, "r%s"),
+            ):
+            for refname in collection:
+                if i > 0:
+                    insert_ticket.append(nodes.Text(", ", ", "))
+                else:
+                    insert_ticket.append(nodes.Text(" ", " "))
+                i += 1
+                if render is not None:
+                    refuri = render % refname
+                    node = nodes.reference('', '',
+                            nodes.Text(prefix % refname, prefix % refname),
+                            refuri=refuri
+                        )
+                else:
+                    node = nodes.Text(prefix % refname, prefix % refname)
+                insert_ticket.append(node)
+
+        if rec['tags']:
+            tag_node = nodes.strong('',
+                        " ".join("[%s]" % t for t
+                            in
+                                [t1 for t1 in [section, cat]
+                                    if t1 in rec['tags']] +
+
+                                list(rec['tags'].difference([section, cat]))
+                        ) + " "
+                    )
+            para.children[0].insert(0, tag_node)
+
+        append_sec.append(
+            nodes.list_item('',
+                nodes.target('', '', ids=[rec['id']]),
+                para
+            )
+        )
+
+
+class ChangeDirective(EnvDirective, Directive):
+    has_content = True
+
+    type_ = "change"
+    parent_cls = ChangeLogDirective
+
+    def run(self):
+        content = _parse_content(self.content)
+        p = nodes.paragraph('', '',)
+        sorted_tags = _comma_list(content.get('tags', ''))
+        rec = {
+            'tags': set(sorted_tags).difference(['']),
+            'tickets': set(_comma_list(content.get('tickets', ''))).difference(['']),
+            'pullreq': set(_comma_list(content.get('pullreq', ''))).difference(['']),
+            'changeset': set(_comma_list(content.get('changeset', ''))).difference(['']),
+            'node': p,
+            'type': self.type_,
+            "title": content.get("title", None),
+            'sorted_tags': sorted_tags
+        }
+
+        if "declarative" in rec['tags']:
+            rec['tags'].add("orm")
+
+        self.state.nested_parse(content['text'], 0, p)
+        self.parent_cls.changes(self.env).append(rec)
+
+        return []
+
+def _text_rawsource_from_node(node):
+    src = []
+    stack = [node]
+    while stack:
+        n = stack.pop(0)
+        if isinstance(n, nodes.Text):
+            src.append(n.rawsource)
+        stack.extend(n.children)
+    return "".join(src)
+
+def _rst2sphinx(text):
+    return StringList(
+        [line.strip() for line in textwrap.dedent(text).split("\n")]
+    )
+
+
+def make_ticket_link(name, rawtext, text, lineno, inliner,
+                      options={}, content=[]):
+    env = inliner.document.settings.env
+    render_ticket = env.config.changelog_render_ticket or "%s"
+    prefix = "#%s"
+    if render_ticket:
+        ref = render_ticket % text
+        node = nodes.reference(rawtext, prefix % text, refuri=ref, **options)
+    else:
+        node = nodes.Text(prefix % text, prefix % text)
+    return [node], []
+
+def setup(app):
+    app.add_directive('changelog', ChangeLogDirective)
+    app.add_directive('change', ChangeDirective)
+    app.add_config_value("changelog_sections", [], 'env')
+    app.add_config_value("changelog_inner_tag_sort", [], 'env')
+    app.add_config_value("changelog_render_ticket",
+            None,
+            'env'
+        )
+    app.add_config_value("changelog_render_pullreq",
+            None,
+            'env'
+        )
+    app.add_config_value("changelog_render_changeset",
+            None,
+            'env'
+        )
+    app.add_role('ticket', make_ticket_link)
diff --git a/doc/build/builder/dialect_info.py b/doc/build/builder/dialect_info.py
new file mode 100644 (file)
index 0000000..22e3fb0
--- /dev/null
@@ -0,0 +1,174 @@
+import re
+from sphinx.util.compat import Directive
+from docutils import nodes
+
+class DialectDirective(Directive):
+    has_content = True
+
+    _dialects = {}
+
+    def _parse_content(self):
+        d = {}
+        d['default'] = self.content[0]
+        d['text'] = []
+        idx = 0
+        for line in self.content[1:]:
+            idx += 1
+            m = re.match(r'\:(.+?)\: +(.+)', line)
+            if m:
+                attrname, value = m.group(1, 2)
+                d[attrname] = value
+            else:
+                break
+        d["text"] = self.content[idx + 1:]
+        return d
+
+    def _dbapi_node(self):
+
+        dialect_name, dbapi_name = self.dialect_name.split("+")
+
+        try:
+            dialect_directive = self._dialects[dialect_name]
+        except KeyError:
+            raise Exception("No .. dialect:: %s directive has been established"
+                                    % dialect_name)
+
+        output = []
+
+        content = self._parse_content()
+
+        parent_section_ref = self.state.parent.children[0]['ids'][0]
+        self._append_dbapi_bullet(dialect_name, dbapi_name,
+                                        content['name'], parent_section_ref)
+
+        p = nodes.paragraph('', '',
+                    nodes.Text(
+                        "Support for the %s database via the %s driver." % (
+                                dialect_directive.database_name,
+                                content['name']
+                        ),
+                        "Support for the %s database via the %s driver." % (
+                                dialect_directive.database_name,
+                                content['name']
+                        )
+                    ),
+        )
+
+        self.state.nested_parse(content['text'], 0, p)
+        output.append(p)
+
+        if "url" in content or "driverurl" in content:
+            sec = nodes.section(
+                    '',
+                    nodes.title("DBAPI", "DBAPI"),
+                    ids=["dialect-%s-%s-url" % (dialect_name, dbapi_name)]
+            )
+            if "url" in content:
+                text = "Documentation and download information (if applicable) "\
+                        "for %s is available at:\n" % content["name"]
+                uri = content['url']
+                sec.append(
+                    nodes.paragraph('', '',
+                        nodes.Text(text, text),
+                        nodes.reference('', '',
+                            nodes.Text(uri, uri),
+                            refuri=uri,
+                        )
+                    )
+                )
+            if "driverurl" in content:
+                text = "Drivers for this database are available at:\n"
+                sec.append(
+                    nodes.paragraph('', '',
+                        nodes.Text(text, text),
+                        nodes.reference('', '',
+                            nodes.Text(content['driverurl'], content['driverurl']),
+                            refuri=content['driverurl']
+                        )
+                    )
+                )
+            output.append(sec)
+
+
+        if "connectstring" in content:
+            sec = nodes.section(
+                    '',
+                    nodes.title("Connecting", "Connecting"),
+                    nodes.paragraph('', '',
+                        nodes.Text("Connect String:", "Connect String:"),
+                        nodes.literal_block(content['connectstring'],
+                            content['connectstring'])
+                    ),
+                    ids=["dialect-%s-%s-connect" % (dialect_name, dbapi_name)]
+            )
+            output.append(sec)
+
+        return output
+
+    def _dialect_node(self):
+        self._dialects[self.dialect_name] = self
+
+        content = self._parse_content()
+        self.database_name = content['name']
+
+        self.bullets = nodes.bullet_list()
+        text = "The following dialect/DBAPI options are available.  "\
+                "Please refer to individual DBAPI sections for connect information."
+        sec = nodes.section('',
+                nodes.paragraph('', '',
+                    nodes.Text(
+                        "Support for the %s database." % content['name'],
+                        "Support for the %s database." % content['name']
+                    ),
+                ),
+                nodes.title("DBAPI Support", "DBAPI Support"),
+                nodes.paragraph('', '',
+                    nodes.Text(text, text),
+                    self.bullets
+                ),
+                ids=["dialect-%s" % self.dialect_name]
+            )
+
+        return [sec]
+
+    def _append_dbapi_bullet(self, dialect_name, dbapi_name, name, idname):
+        env = self.state.document.settings.env
+        dialect_directive = self._dialects[dialect_name]
+
+        list_node = nodes.list_item('',
+                nodes.paragraph('', '',
+                    nodes.reference('', '',
+                                nodes.Text(name, name),
+                                refdocname=self.docname,
+                                refuri=env.app.builder.get_relative_uri(
+                                        dialect_directive.docname, self.docname) +
+                                            "#" + idname
+                            ),
+                    #nodes.Text(" ", " "),
+                    #nodes.reference('', '',
+                    #            nodes.Text("(connectstring)", "(connectstring)"),
+                    #            refdocname=self.docname,
+                    #            refuri=env.app.builder.get_relative_uri(
+                    #                    dialect_directive.docname, self.docname) +
+                    ##                        "#" + ("dialect-%s-%s-connect" %
+                    #                                (dialect_name, dbapi_name))
+                    #        )
+                    )
+            )
+        dialect_directive.bullets.append(list_node)
+
+    def run(self):
+        env = self.state.document.settings.env
+        self.docname = env.docname
+
+        self.dialect_name = dialect_name = self.content[0]
+
+        has_dbapi = "+" in dialect_name
+        if has_dbapi:
+            return self._dbapi_node()
+        else:
+            return self._dialect_node()
+
+def setup(app):
+    app.add_directive('dialect', DialectDirective)
+
diff --git a/doc/build/builder/mako.py b/doc/build/builder/mako.py
new file mode 100644 (file)
index 0000000..845686a
--- /dev/null
@@ -0,0 +1,82 @@
+from __future__ import absolute_import
+
+from sphinx.application import TemplateBridge
+from sphinx.jinja2glue import BuiltinTemplateLoader
+from mako.lookup import TemplateLookup
+import os
+
+rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+class MakoBridge(TemplateBridge):
+    def init(self, builder, *args, **kw):
+        self.jinja2_fallback = BuiltinTemplateLoader()
+        self.jinja2_fallback.init(builder, *args, **kw)
+
+        builder.config.html_context['release_date'] = builder.config['release_date']
+        builder.config.html_context['site_base'] = builder.config['site_base']
+
+        self.lookup = TemplateLookup(directories=builder.config.templates_path,
+            #format_exceptions=True,
+            imports=[
+                "from builder import util"
+            ]
+        )
+
+        if rtd:
+            import urllib2
+            template_url = builder.config['site_base'] + "/docs_base.mako"
+            template = urllib2.urlopen(template_url).read()
+            self.lookup.put_string("/rtd_base.mako", template)
+
+    def render(self, template, context):
+        template = template.replace(".html", ".mako")
+        context['prevtopic'] = context.pop('prev', None)
+        context['nexttopic'] = context.pop('next', None)
+
+        # RTD layout
+        if rtd:
+            # add variables if not present, such
+            # as if local test of READTHEDOCS variable
+            if 'MEDIA_URL' not in context:
+                context['MEDIA_URL'] = "http://media.readthedocs.org/"
+            if 'slug' not in context:
+                context['slug'] = context['project'].lower()
+            if 'url' not in context:
+                context['url'] = "/some/test/url"
+            if 'current_version' not in context:
+                context['current_version'] = "latest"
+
+            if 'name' not in context:
+                context['name'] = context['project'].lower()
+
+            context['rtd'] = True
+            context['toolbar'] = True
+            context['layout'] = "rtd_layout.mako"
+            context['base'] = "rtd_base.mako"
+            context['pdf_url'] = "%spdf/%s/%s/%s.pdf" % (
+                    context['MEDIA_URL'],
+                    context['slug'],
+                    context['current_version'],
+                    context['slug']
+            )
+        # local docs layout
+        else:
+            context['rtd'] = False
+            context['toolbar'] = False
+            context['layout'] = "layout.mako"
+            context['base'] = "static_base.mako"
+
+        context.setdefault('_', lambda x: x)
+        return self.lookup.get_template(template).render_unicode(**context)
+
+    def render_string(self, template, context):
+        # this is used for  .js, .css etc. and we don't have
+        # local copies of that stuff here so use the jinja render.
+        return self.jinja2_fallback.render_string(template, context)
+
+def setup(app):
+    app.config['template_bridge'] = "builder.mako.MakoBridge"
+    app.add_config_value('release_date', "", 'env')
+    app.add_config_value('site_base', "", 'env')
+    app.add_config_value('build_number', "", 'env')
+
diff --git a/doc/build/builder/sqlformatter.py b/doc/build/builder/sqlformatter.py
new file mode 100644 (file)
index 0000000..2d80749
--- /dev/null
@@ -0,0 +1,132 @@
+from pygments.lexer import RegexLexer, bygroups, using
+from pygments.token import Token
+from pygments.filter import Filter
+from pygments.filter import apply_filters
+from pygments.lexers import PythonLexer, PythonConsoleLexer
+from sphinx.highlighting import PygmentsBridge
+from pygments.formatters import HtmlFormatter, LatexFormatter
+
+import re
+
+
+def _strip_trailing_whitespace(iter_):
+    buf = list(iter_)
+    if buf:
+        buf[-1] = (buf[-1][0], buf[-1][1].rstrip())
+    for t, v in buf:
+        yield t, v
+
+
+class StripDocTestFilter(Filter):
+    def filter(self, lexer, stream):
+        for ttype, value in stream:
+            if ttype is Token.Comment and re.match(r'#\s*doctest:', value):
+                continue
+            yield ttype, value
+
+class PyConWithSQLLexer(RegexLexer):
+    name = 'PyCon+SQL'
+    aliases = ['pycon+sql']
+
+    flags = re.IGNORECASE | re.DOTALL
+
+    tokens = {
+            'root': [
+                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
+                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
+                (r'.*?\n', using(PythonConsoleLexer))
+            ],
+            'sqlpopup': [
+                (
+                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|'
+                        'COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA'
+                        '|DESCRIBE).*?(?:{stop}\n?|$))',
+                    bygroups(using(PythonConsoleLexer), Token.Sql.Popup),
+                    "#pop"
+                )
+            ],
+            'opensqlpopup': [
+                (
+                    r'.*?(?:{stop}\n*|$)',
+                    Token.Sql,
+                    "#pop"
+                )
+            ]
+        }
+
+
+class PythonWithSQLLexer(RegexLexer):
+    name = 'Python+SQL'
+    aliases = ['pycon+sql']
+
+    flags = re.IGNORECASE | re.DOTALL
+
+    tokens = {
+            'root': [
+                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
+                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
+                (r'.*?\n', using(PythonLexer))
+            ],
+            'sqlpopup': [
+                (
+                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK'
+                        '|COMMIT|ALTER|UPDATE|CREATE|DROP'
+                        '|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))',
+                    bygroups(using(PythonLexer), Token.Sql.Popup),
+                    "#pop"
+                )
+            ],
+            'opensqlpopup': [
+                (
+                    r'.*?(?:{stop}\n*|$)',
+                    Token.Sql,
+                    "#pop"
+                )
+            ]
+        }
+
+class PopupSQLFormatter(HtmlFormatter):
+    def _format_lines(self, tokensource):
+        buf = []
+        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
+            if ttype in Token.Sql:
+                for t, v in HtmlFormatter._format_lines(self, iter(buf)):
+                    yield t, v
+                buf = []
+
+                if ttype is Token.Sql:
+                    yield 1, "<div class='show_sql'>%s</div>" % \
+                                        re.sub(r'(?:[{stop}|\n]*)$', '', value)
+                elif ttype is Token.Sql.Link:
+                    yield 1, "<a href='#' class='sql_link'>sql</a>"
+                elif ttype is Token.Sql.Popup:
+                    yield 1, "<div class='popup_sql'>%s</div>" % \
+                                        re.sub(r'(?:[{stop}|\n]*)$', '', value)
+            else:
+                buf.append((ttype, value))
+
+        for t, v in _strip_trailing_whitespace(
+                        HtmlFormatter._format_lines(self, iter(buf))):
+            yield t, v
+
+class PopupLatexFormatter(LatexFormatter):
+    def _filter_tokens(self, tokensource):
+        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
+            if ttype in Token.Sql:
+                if ttype is not Token.Sql.Link and ttype is not Token.Sql.Open:
+                    yield Token.Literal, re.sub(r'{stop}', '', value)
+                else:
+                    continue
+            else:
+                yield ttype, value
+
+    def format(self, tokensource, outfile):
+        LatexFormatter.format(self, self._filter_tokens(tokensource), outfile)
+
+def setup(app):
+    app.add_lexer('pycon+sql', PyConWithSQLLexer())
+    app.add_lexer('python+sql', PythonWithSQLLexer())
+
+    PygmentsBridge.html_formatter = PopupSQLFormatter
+    PygmentsBridge.latex_formatter = PopupLatexFormatter
+
diff --git a/doc/build/changelog/changelog_01.rst b/doc/build/changelog/changelog_01.rst
new file mode 100644 (file)
index 0000000..156599a
--- /dev/null
@@ -0,0 +1,975 @@
+
+==============
+0.1 Changelog
+==============
+
+                
+.. changelog::
+    :version: 0.1.7
+    :released: Fri May 05 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      some fixes to topological sort algorithm
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added DISTINCT ON support to Postgres (just supply distinct=[col1,col2..])
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added __mod__ (% operator) to sql expressions
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      "order_by" mapper property inherited from inheriting mapper
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to column type used when mapper UPDATES/DELETEs
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      with convert_unicode=True, reflection was failing, has been fixed
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      types types types!  still werent working....have to use TypeDecorator again :(
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      mysql binary type converts array output to buffer, fixes PickleType
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed the attributes.py memory leak once and for all
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      unittests are qualified based on the databases that support each one
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed bug where column defaults would clobber VALUES clause of insert objects
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed bug where table def w/ schema name would force engine connection
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix for parenthesis to work correctly with subqueries in INSERT/UPDATE
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      HistoryArraySet gets extend() method
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed lazyload support for other comparison operators besides =
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      lazyload fix where two comparisons in the join condition point to the
+      samem column
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "construct_new" flag to mapper, will use __new__ to create instances
+      instead of __init__ (standard in 0.2)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added selectresults.py to SVN, missed it last time
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      tweak to allow a many-to-many relationship from a table to itself via
+      an association table
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      small fix to "translate_row" function used by polymorphic example
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      create_engine uses cgi.parse_qsl to read query string (out the window in 0.2)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      tweaks to CAST operator
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed function names LOCAL_TIME/LOCAL_TIMESTAMP -> LOCALTIME/LOCALTIMESTAMP
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed order of ORDER BY/HAVING in compile
+
+.. changelog::
+    :version: 0.1.6
+    :released: Wed Apr 12 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      support for MS-SQL added courtesy Rick Morrison, Runar Petursson
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      the latest SQLSoup from J. Ellis
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      ActiveMapper has preliminary support for inheritance (Jeff Watkins)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added a "mods" system which allows pluggable modules that modify/augment
+      core functionality, using the function "install_mods(*modnames)".
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added the first "mod", SelectResults, which modifies mapper selects to
+      return generators that turn ranges into LIMIT/OFFSET queries
+      (Jonas Borgstr?
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      factored out querying capabilities of Mapper into a separate Query object
+      which is Session-centric.  this improves the performance of mapper.using(session)
+      and makes other things possible.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      objectstore/Session refactored, the official way to save objects is now
+      via the flush() method.  The begin/commit functionality of Session is factored
+      into LegacySession which is still established as the default behavior, until
+      the 0.2 series.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      types system is bound to an engine at query compile time, not schema
+      construction time.  this simplifies the types system as well as the ProxyEngine.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added 'version_id' keyword argument to mapper. this keyword should reference a
+      Column object with type Integer, preferably non-nullable, which will be used on
+      the mapped table to track version numbers. this number is incremented on each
+      save operation and is specifed in the UPDATE/DELETE conditions so that it
+      factors into the returned row count, which results in a ConcurrencyError if the
+      value received is not the expected count.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added 'entity_name' keyword argument to mapper. a mapper is now associated
+      with a class via the class object as well as an optional entity_name parameter,
+      which is a string defaulting to None. any number of primary mappers can be
+      created for a class, qualified by the entity name. instances of those classes
+      will issue all of their load and save operations through their
+      entity_name-qualified mapper, and maintain separate a identity in the identity
+      map for an otherwise equilvalent object.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to the attributes system. code has been clarified, and also fixed to
+      support proper polymorphic behavior on object attributes.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "for_update" flag to Select objects
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      some fixes for backrefs
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix for postgres1 DateTime type
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      documentation pages mostly switched over to Markdown syntax
+
+.. changelog::
+    :version: 0.1.5
+    :released: Mon Mar 27 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added SQLSession concept to SQLEngine. this object keeps track of retrieving a
+      connection from the connection pool as well as an in-progress transaction.
+      methods push_session() and pop_session() added to SQLEngine which push/pop a new
+      SQLSession onto the engine, allowing operation upon a second connection "nested"
+      within the previous one, allowing nested transactions. Other tricks are sure to
+      come later regarding SQLSession.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added nest_on argument to objectstore.Session. This is a single SQLEngine or
+      list of engines for which push_session()/pop_session() will be called each time
+      this Session becomes the active session (via objectstore.push_session() or
+      equivalent). This allows a unit of work Session to take advantage of the nested
+      transaction feature without explicitly calling push_session/pop_session on the
+      engine.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      factored apart objectstore/unitofwork to separate "Session scoping" from
+      "uow commit heavy lifting"
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added populate_instance() method to MapperExtension. allows an extension to
+      modify the population of object attributes. this method can call the
+      populate_instance() method on another mapper to proxy the attribute population
+      from one mapper to another; some row translation logic is also built in to help
+      with this.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed Oracle8-compatibility "use_ansi" flag which converts JOINs to
+      comparisons with the = and (+) operators, passes basic unittests
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      tweaks to Oracle LIMIT/OFFSET support
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Oracle reflection uses ALL_** views instead of USER_** to get larger
+      list of stuff to reflect from
+
+    .. change::
+        :tags: 
+        :tickets: 105
+
+      fixes to Oracle foreign key reflection
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      objectstore.commit(obj1, obj2,...) adds an extra step to seek out private
+      relations on properties and delete child objects, even though its not a global
+      commit
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      lots and lots of fixes to mappers which use inheritance, strengthened the
+      concept of relations on a mapper being made towards the "local" table for that
+      mapper, not the tables it inherits.  allows more complex compositional patterns
+      to work with lazy/eager loading.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added support for mappers to inherit from others based on the same table,
+      just specify the same table as that of both parent/child mapper.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      some minor speed improvements to the attributes system with regards to
+      instantiating and populating new objects.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed MySQL binary unit test
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      INSERTs can receive clause elements as VALUES arguments, not just literal
+      values
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      support for calling multi-tokened functions, i.e. schema.mypkg.func()
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added J. Ellis' SQLSoup module to extensions package
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "polymorphic" examples illustrating methods to load multiple object types
+      from one mapper, the second of which uses the new populate_instance() method.
+      small improvements to mapper, UNION construct to help the examples along
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improvements/fixes to session.refresh()/session.expire() (which may have
+      been called "invalidate" earlier..)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added session.expunge() which totally removes an object from the current
+      session
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added *args, **kwargs pass-thru to engine.transaction(func) allowing easier
+      creation of transactionalizing decorator functions
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added iterator interface to ResultProxy:  "for row in result:..."
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added assertion to tx = session.begin(); tx.rollback(); tx.begin(), i.e. cant
+      use it after a rollback()
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added date conversion on bind parameter fix to SQLite enabling dates to
+      work with pysqlite1
+
+    .. change::
+        :tags: 
+        :tickets: 116
+
+      improvements to subqueries to more intelligently construct their FROM
+      clauses
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added PickleType to types.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed two bugs with column labels with regards to bind parameters: bind param
+      keynames they are now generated from a column "label" in all relevant cases to
+      take advantage of excess-name-length rules, and checks for a peculiar collision
+      against a column named the same as "tablename_colname" added
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      major overhaul to unit of work documentation, other documentation sections.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed attributes bug where if an object is committed, its lazy-loaded list got
+      blown away if it hadnt been loaded
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added unique_connection() method to engine, connection pool to return a
+      connection that is not part of the thread-local context or any current
+      transaction
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added invalidate() function to pooled connection.  will remove the connection
+      from the pool.  still need work for engines to auto-reconnect to a stale DB
+      though.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added distinct() function to column elements so you can do
+      func.count(mycol.distinct())
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "always_refresh" flag to Mapper, creates a mapper that will always
+      refresh the attributes of objects it gets/selects from the DB, overwriting any
+      changes made.
+
+.. changelog::
+    :version: 0.1.4
+    :released: Mon Mar 13 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      create_engine() now uses genericized parameters; host/hostname,
+      db/dbname/database, password/passwd, etc. for all engine connections. makes
+       engine URIs much more "universal"
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added support for SELECT statements embedded into a column clause, using the
+      flag "scalar=True"
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      another overhaul to EagerLoading when used in conjunction with mappers that
+      inherit; improvements to eager loads figuring out their aliased queries
+      correctly, also relations set up against a mapper with inherited mappers will
+      create joins against the table that is specific to the mapper itself (i.e. and
+      not any tables that are inherited/are further down the inheritance chain),
+      this can be overridden by using custom primary/secondary joins.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added J.Ellis patch to mapper.py so that selectone() throws an exception
+      if query returns more than one object row, selectfirst() to not throw the
+      exception. also adds selectfirst_by (synonymous with get_by) and selectone_by
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added onupdate parameter to Column, will exec SQL/python upon an update
+      statement.Also adds "for_update=True" to all DefaultGenerator subclasses
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added support for Oracle table reflection contributed by Andrija Zaric;
+      still some bugs to work out regarding composite primary keys/dictionary selection
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      checked in an initial Firebird module, awaiting testing.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added sql.ClauseParameters dictionary object as the result for
+      compiled.get_params(), does late-typeprocessing of bind parameters so
+      that the original values are easier to access
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      more docs for indexes, column defaults, connection pooling, engine construction
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to the construction of the types system. uses a simpler inheritance
+      pattern so that any of the generic types can be easily subclassed, with no need
+      for TypeDecorator.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "convert_unicode=False" parameter to SQLEngine, will cause all String
+      types to perform unicode encoding/decoding (makes Strings act like Unicodes)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added 'encoding="utf8"' parameter to engine.  the given encoding will be
+      used for all encode/decode calls within Unicode types as well as Strings
+      when convert_unicode=True.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improved support for mapping against UNIONs, added polymorph.py example
+      to illustrate multi-class mapping against a UNION
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to SQLite LIMIT/OFFSET syntax
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to Oracle LIMIT syntax
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added backref() function, allows backreferences to have keyword arguments
+      that will be passed to the backref.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Sequences and ColumnDefault objects can do execute()/scalar() standalone
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      SQL functions (i.e. func.foo()) can do execute()/scalar() standalone
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to SQL functions so that the ANSI-standard functions, i.e. current_timestamp
+      etc., do not specify parenthesis.  all other functions do.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added settattr_clean and append_clean to SmartProperty, which set
+      attributes without triggering a "dirty" event or any history. used as:
+      myclass.prop1.setattr_clean(myobject, 'hi')
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improved support to column defaults when used by mappers; mappers will pull
+      pre-executed defaults from statement's executed bind parameters
+      (pre-conversion) to populate them into a saved object's attributes; if any
+      PassiveDefaults have fired off, will instead post-fetch the row from the DB to
+      populate the object.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added 'get_session().invalidate(*obj)' method to objectstore, instances will
+      refresh() themselves upon the next attribute access.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improvements to SQL func calls including an "engine" keyword argument so
+      they can be execute()d or scalar()ed standalone, also added func accessor to
+      SQLEngine
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to MySQL4 custom table engines, i.e. TYPE instead of ENGINE
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      slightly enhanced logging, includes timestamps and a somewhat configurable
+      formatting system, in lieu of a full-blown logging system
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improvements to the ActiveMapper class from the TG gang, including
+      many-to-many relationships
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added Double and TinyInt support to mysql
+
+.. changelog::
+    :version: 0.1.3
+    :released: Thu Mar 02 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      completed "post_update" feature, will add a second update statement before
+      inserts and after deletes in order to reconcile a relationship without any
+      dependencies being created; used when persisting two rows that are dependent
+      on each other
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      completed mapper.using(session) function, localized per-object Session
+      functionality; objects can be declared and manipulated as local to any
+      user-defined Session
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to Oracle "row_number over" clause with multiple tables
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      mapper.get() was not selecting multiple-keyed objects if the mapper's table was a join,
+      such as in an inheritance relationship, this is fixed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to sql/schema packages so that the sql package can run all on its own,
+      producing selects, inserts, etc. without any engine dependencies.  builds upon
+      new TableClause/ColumnClause lexical objects.  Schema's Table/Column objects
+      are the "physical" subclasses of them.  simplifies schema/sql relationship,
+      extensions (like proxyengine), and speeds overall performance by a large margin.
+      removes the entire getattr() behavior that plagued 0.1.1.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      refactoring of how the mapper "synchronizes" data between two objects into a
+      separate module, works better with properties attached to a mapper that has an
+      additional inheritance relationship to one of the related tables, also the same
+      methodology used to synchronize parent/child objects now used by mapper to
+      synchronize between inherited and inheriting mappers.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      made objectstore "check for out-of-identitymap" more aggressive, will perform the
+      check when object attributes are modified or the object is deleted
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Index object fully implemented, can be constructed standalone, or via
+      "index" and "unique" arguments on Columns.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "convert_unicode" flag to SQLEngine, will treat all String/CHAR types
+      as Unicode types, with raw-byte/utf-8 translation on the bind parameter and
+      result set side.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      postgres maintains a list of ANSI functions that must have no parenthesis so
+      function calls with no arguments work consistently
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      tables can be created with no engine specified.  this will default their engine
+      to a module-scoped "default engine" which is a ProxyEngine.  this engine can
+      be connected via the function "global_connect".
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "refresh(*obj)" method to objectstore / Session to reload the attributes of
+      any set of objects from the database unconditionally
+
+.. changelog::
+    :version: 0.1.2
+    :released: Fri Feb 24 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed a recursive call in schema that was somehow running 994 times then returning
+      normally.  broke nothing, slowed down everything.  thanks to jpellerin for finding this.
+
+.. changelog::
+    :version: 0.1.1
+    :released: Thu Feb 23 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      small fix to Function class so that expressions with a func.foo() use the type of the
+      Function object (i.e. the left side) as the type of the boolean expression, not the
+      other side which is more of a moving target (changeset 1020).
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      creating self-referring mappers with backrefs slightly easier (but still not that easy -
+      changeset 1019)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixes to one-to-one mappings (changeset 1015)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      psycopg1 date/time issue with None fixed (changeset 1005)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      two issues related to postgres, which doesnt want to give you the "lastrowid"
+      since oids are deprecated:
+         * postgres database-side defaults that are on primary key cols *do* execute
+      explicitly beforehand, even though thats not the idea of a PassiveDefault.  this is
+      because sequences on columns get reflected as PassiveDefaults, but need to be explicitly
+      executed on a primary key col so we know what we just inserted.
+         * if you did add a row that has a bunch of database-side defaults on it,
+      and the PassiveDefault thing was working the old way, i.e. they just execute on
+      the DB side, the "cant get the row back without an OID" exception that occurred
+      also will not happen unless someone (usually the ORM) explicitly asks for it.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed a glitch with engine.execute_compiled where it was making a second
+      ResultProxy that just got thrown away.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      began to implement newer logic in object properities.  you can now say
+      myclass.attr.property, which will give you the PropertyLoader corresponding to that
+      attribute, i.e. myclass.mapper.props['attr']
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      eager loading has been internally overhauled to use aliases at all times.  more
+      complicated chains of eager loads can now be created without any need for explicit
+      "use aliases"-type instructions.  EagerLoader code is also much simpler now.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      a new somewhat experimental flag "use_update" added to relations, indicates that
+      this relationship should be handled by a second UPDATE statement, either after a
+      primary INSERT or before a primary DELETE.  handles circular row dependencies.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added exceptions module, all raised exceptions (except for some
+      KeyError/AttributeError exceptions) descend from these classes.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to date types with MySQL, returned timedelta converted to datetime.time
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      two-phase objectstore.commit operations (i.e. begin/commit) now return a
+      transactional object (SessionTrans), to more clearly indicate transaction boundaries.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Index object with create/drop support added to schema
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to postgres, where it will explicitly pre-execute a PassiveDefault on a table
+      if it is a primary key column, pursuant to the ongoing "we cant get inserted rows
+      back from postgres" issue
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      change to information_schema query that gets back postgres table defs, now
+      uses explicit JOIN keyword, since one user had faster performance with 8.1
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to engine.process_defaults so it works correctly with a table that has
+      different column name/column keys (changset 982)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      a column can only be attached to one table - this is now asserted
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      postgres time types descend from Time type
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to alltests so that it runs types test (now named testtypes)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to Join object so that it correctly exports its foreign keys (cs 973)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      creating relationships against mappers that use inheritance fixed (cs 973)
diff --git a/doc/build/changelog/changelog_02.rst b/doc/build/changelog/changelog_02.rst
new file mode 100644 (file)
index 0000000..3053659
--- /dev/null
@@ -0,0 +1,1187 @@
+
+==============
+0.2 Changelog
+==============
+
+                
+.. changelog::
+    :version: 0.2.8
+    :released: Tue Sep 05 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      cleanup on connection methods + documentation.  custom DBAPI
+      arguments specified in query string, 'connect_args' argument
+      to 'create_engine', or custom creation function via 'creator'
+      function to 'create_engine'.
+
+    .. change::
+        :tags: 
+        :tickets: 274
+
+      added "recycle" argument to Pool, is "pool_recycle" on create_engine,
+      defaults to 3600 seconds; connections after this age will be closed and
+      replaced with a new one, to handle db's that automatically close
+      stale connections
+
+    .. change::
+        :tags: 
+        :tickets: 121
+
+      changed "invalidate" semantics with pooled connection; will
+      instruct the underlying connection record to reconnect the next
+      time its called.  "invalidate" will also automatically be called
+      if any error is thrown in the underlying call to connection.cursor().
+      this will hopefully allow the connection pool to reconnect to a
+      database that had been stopped and started without restarting
+      the connecting application
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      eesh !  the tutorial doctest was broken for quite some time.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      add_property() method on mapper does a "compile all mappers"
+      step in case the given property references a non-compiled mapper
+      (as it did in the case of the tutorial !)
+
+    .. change::
+        :tags: 
+        :tickets: 277
+
+      check for pg sequence already existing before create
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      if a contextual session is established via MapperExtension.get_session
+      (as it is using the sessioncontext plugin, etc), a lazy load operation
+      will use that session by default if the parent object is not
+      persistent with a session already.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      lazy loads will not fire off for an object that does not have a
+      database identity (why?
+      see http://www.sqlalchemy.org/trac/wiki/WhyDontForeignKeysLoadData)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      unit-of-work does a better check for "orphaned" objects that are
+      part of a "delete-orphan" cascade, for certain conditions where the
+      parent isnt available to cascade from.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      mappers can tell if one of their objects is an "orphan" based
+      on interactions with the attribute package. this check is based
+      on a status flag maintained for each relationship
+      when objects are attached and detached from each other.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      it is now invalid to declare a self-referential relationship with
+      "delete-orphan" (as the abovementioned check would make them impossible
+      to save)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improved the check for objects being part of a session when the
+      unit of work seeks to flush() them as part of a relationship..
+
+    .. change::
+        :tags: 
+        :tickets: 280
+
+      statement execution supports using the same BindParam
+      object more than once in an expression; simplified handling of positional
+      parameters.  nice job by Bill Noon figuring out the basic idea.
+
+    .. change::
+        :tags: 
+        :tickets: 60, 71
+
+      postgres reflection moved to use pg_schema tables, can be overridden
+      with use_information_schema=True argument to create_engine.
+
+    .. change::
+        :tags: 
+        :tickets: 155
+
+      added case_sensitive argument to MetaData, Table, Column, determines
+      itself automatically based on if a parent schemaitem has a non-None
+      setting for the flag, or if not, then whether the identifier name is all lower
+      case or not.  when set to True, quoting is applied to identifiers with mixed or
+      uppercase identifiers.  quoting is also applied automatically in all cases to
+      identifiers that are known to be reserved words or contain other non-standard
+      characters. various database dialects can override all of this behavior, but
+      currently they are all using the default behavior.  tested with postgres, mysql,
+      sqlite, oracle.  needs more testing with firebird, ms-sql. part of the ongoing
+      work with
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      unit tests updated to run without any pysqlite installed; pool
+      test uses a mock DBAPI
+
+    .. change::
+        :tags: 
+        :tickets: 281
+
+      urls support escaped characters in passwords
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added limit/offset to UNION queries (though not yet in oracle)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "timezone=True" flag to DateTime and Time types.  postgres
+      so far will convert this to "TIME[STAMP] (WITH|WITHOUT) TIME ZONE",
+      so that control over timezone presence is more controllable (psycopg2
+      returns datetimes with tzinfo's if available, which can create confusion
+      against datetimes that dont).
+
+    .. change::
+        :tags: 
+        :tickets: 287
+
+      fix to using query.count() with distinct, **kwargs with SelectResults
+      count()
+
+    .. change::
+        :tags: 
+        :tickets: 289
+
+      deregister Table from MetaData when autoload fails;
+
+    .. change::
+        :tags: 
+        :tickets: 293
+
+      import of py2.5s sqlite3
+
+    .. change::
+        :tags: 
+        :tickets: 296
+
+      unicode fix for startswith()/endswith()
+
+.. changelog::
+    :version: 0.2.7
+    :released: Sat Aug 12 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      quoting facilities set up so that database-specific quoting can be
+      turned on for individual table, schema, and column identifiers when
+      used in all queries/creates/drops.  Enabled via "quote=True" in
+      Table or Column, as well as "quote_schema=True" in Table.  Thanks to
+      Aaron Spike for his excellent efforts.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      assignmapper was setting is_primary=True, causing all sorts of mayhem
+      by not raising an error when redundant mappers were set up, fixed
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added allow_null_pks option to Mapper, allows rows where some
+      primary key columns are null (i.e. when mapping to outer joins etc)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      modifcation to unitofwork to not maintain ordering within the
+      "new" list or within the UOWTask "objects" list; instead, new objects
+      are tagged with an ordering identifier as they are registered as new
+      with the session, and the INSERT statements are then sorted within the
+      mapper save_obj.  the INSERT ordering has basically been pushed all
+      the way to the end of the flush cycle. that way the various sorts and
+      organizations occuring within UOWTask (particularly the circular task
+      sort) dont have to worry about maintaining order (which they werent anyway)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed reflection of foreign keys to autoload the referenced table
+      if it was not loaded already
+
+    .. change::
+        :tags: 
+        :tickets: 256
+
+      - pass URL query string arguments to connect() function
+
+    .. change::
+        :tags: 
+        :tickets: 257
+
+      - oracle boolean type
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      custom primary/secondary join conditions in a relation *will* be propagated
+      to backrefs by default.  specifying a backref() will override this behavior.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      better check for ambiguous join conditions in sql.Join; propagates to a
+      better error message in PropertyLoader (i.e. relation()/backref()) for when
+      the join condition can't be reasonably determined.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      sqlite creates ForeignKeyConstraint objects properly upon table
+      reflection.
+
+    .. change::
+        :tags: 
+        :tickets: 224
+
+      adjustments to pool stemming from changes made for.
+      overflow counter should only be decremented if the connection actually
+      succeeded.  added a test script to attempt testing this.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed mysql reflection of default values to be PassiveDefault
+
+    .. change::
+        :tags: 
+        :tickets: 263, 264
+
+      added reflected 'tinyint', 'mediumint' type to MS-SQL.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      SingletonThreadPool has a size and does a cleanup pass, so that
+      only a given number of thread-local connections stay around (needed
+      for sqlite applications that dispose of threads en masse)
+
+    .. change::
+        :tags: 
+        :tickets: 267, 265
+
+      fixed small pickle bug(s) with lazy loaders
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed possible error in mysql reflection where certain versions
+      return an array instead of string for SHOW CREATE TABLE call
+
+    .. change::
+        :tags: 
+        :tickets: 1770
+
+      fix to lazy loads when mapping to joins
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      all create()/drop() calls have a keyword argument of "connectable".
+      "engine" is deprecated.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed ms-sql connect() to work with adodbapi
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "nowait" flag to Select()
+
+    .. change::
+        :tags: 
+        :tickets: 271
+
+      inheritance check uses issubclass() instead of direct __mro__ check
+      to make sure class A inherits from B, allowing mapper inheritance to more
+      flexibly correspond to class inheritance
+
+    .. change::
+        :tags: 
+        :tickets: 252
+
+      SelectResults will use a subselect, when calling an aggregate (i.e.
+      max, min, etc.) on a SelectResults that has an ORDER BY clause
+
+    .. change::
+        :tags: 
+        :tickets: 269
+
+      fixes to types so that database-specific types more easily used;
+      fixes to mysql text types to work with this methodology
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      some fixes to sqlite date type organization
+
+    .. change::
+        :tags: 
+        :tickets: 263
+
+      added MSTinyInteger to MS-SQL
+
+.. changelog::
+    :version: 0.2.6
+    :released: Thu Jul 20 2006
+
+    .. change::
+        :tags: 
+        :tickets: 76
+
+      big overhaul to schema to allow truly composite primary and foreign
+      key constraints, via new ForeignKeyConstraint and PrimaryKeyConstraint
+      objects.
+      Existing methods of primary/foreign key creation have not been changed
+      but use these new objects behind the scenes.  table creation
+      and reflection is now more table oriented rather than column oriented.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to MapperExtension calling scheme, wasnt working very well
+      previously
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      tweaks to ActiveMapper, supports self-referential relationships
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      slight rearrangement to objectstore (in activemapper/threadlocal)
+      so that the SessionContext is referenced by '.context' instead
+      of subclassed directly.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      activemapper will use threadlocal's objectstore if the mod is
+      activated when activemapper is imported
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      small fix to URL regexp to allow filenames with '@' in them
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixes to Session expunge/update/etc...needs more cleanup.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      select_table mappers *still* werent always compiling
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed up Boolean datatype
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added count()/count_by() to list of methods proxied by assignmapper;
+      this also adds them to activemapper
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      connection exceptions wrapped in DBAPIError
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      ActiveMapper now supports autoloading column definitions from the
+      database if you supply a __autoload__ = True attribute in your
+      mapping inner-class.  Currently this does not support reflecting
+      any relationships.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      deferred column load could screw up the connection status in
+      a flush() under some circumstances, this was fixed
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      expunge() was not working with cascade, fixed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      potential endless loop in cascading operations fixed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "synonym()" function, applied to properties to have a
+      propname the same as another, for the purposes of overriding props
+      and allowing the original propname to be accessible in select_by().
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to typing in clause construction which specifically helps
+      type issues with polymorphic_union (CAST/ColumnClause propagates
+      its type to proxy columns)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      mapper compilation work ongoing, someday it'll work....moved
+      around the initialization of MapperProperty objects to be after
+      all mappers are created to better handle circular compilations.
+      do_init() method is called on all properties now which are more
+      aware of their "inherited" status if so.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      eager loads explicitly disallowed on self-referential relationships, or
+      relationships to an inheriting mapper (which is also self-referential)
+
+    .. change::
+        :tags: 
+        :tickets: 244
+
+      reduced bind param size in query._get to appease the picky oracle
+
+    .. change::
+        :tags: 
+        :tickets: 234
+
+      added 'checkfirst' argument to table.create()/table.drop(), as
+      well as table.exists()
+
+    .. change::
+        :tags: 
+        :tickets: 245
+
+      some other ongoing fixes to inheritance
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      attribute/backref/orphan/history-tracking tweaks as usual...
+
+.. changelog::
+    :version: 0.2.5
+    :released: Sat Jul 08 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed endless loop bug in select_by(), if the traversal hit
+      two mappers that referenced each other
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      upgraded all unittests to insert './lib/' into sys.path,
+      working around new setuptools PYTHONPATH-killing behavior
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      further fixes with attributes/dependencies/etc....
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improved error handling for when DynamicMetaData is not connected
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      MS-SQL support largely working (tested with pymssql)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      ordering of UPDATE and DELETE statements within groups is now
+      in order of primary key values, for more deterministic ordering
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      after_insert/delete/update mapper extensions now called per object,
+      not per-object-per-table
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      further fixes/refactorings to mapper compilation
+
+.. changelog::
+    :version: 0.2.4
+    :released: Tue Jun 27 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      try/except when the mapper sets init.__name__ on a mapped class,
+      supports python 2.3
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed bug where threadlocal engine would still autocommit
+      despite a transaction in progress
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      lazy load and deferred load operations require the parent object
+      to be in a Session to do the operation; whereas before the operation
+      would just return a blank list or None, it now raises an exception.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Session.update() is slightly more lenient if the session to which
+      the given object was formerly attached to was garbage collected;
+      otherwise still requires you explicitly remove the instance from
+      the previous Session.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixes to mapper compilation, checking for more error conditions
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      small fix to eager loading combined with ordering/limit/offset
+
+    .. change::
+        :tags: 
+        :tickets: 206
+
+      utterly remarkable:  added a single space between 'CREATE TABLE'
+      and '(<the rest of it>' since *thats how MySQL indicates a non-
+      reserved word tablename.....*
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      more fixes to inheritance, related to many-to-many relations
+      properly saving
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed bug when specifying explicit module to mysql dialect
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      when QueuePool times out it raises a TimeoutError instead of
+      erroneously making another connection
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Queue.Queue usage in pool has been replaced with a locally
+      modified version (works in py2.3/2.4!) that uses a threading.RLock
+      for a mutex.  this is to fix a reported case where a ConnectionFairy's
+      __del__() method got called within the Queue's get() method, which
+      then returns its connection to the Queue via the the put() method,
+      causing a reentrant hang unless threading.RLock is used.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      postgres will not place SERIAL keyword on a primary key column
+      if it has a foreign key constraint
+
+    .. change::
+        :tags: 
+        :tickets: 221
+
+      cursor() method on ConnectionFairy allows db-specific extension
+      arguments to be propagated
+
+    .. change::
+        :tags: 
+        :tickets: 225
+
+      lazy load bind params properly propagate column type
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      new MySQL types: MSEnum, MSTinyText, MSMediumText, MSLongText, etc.
+      more support for MS-specific length/precision params in numeric types
+      patch courtesy Mike Bernson
+
+    .. change::
+        :tags: 
+        :tickets: 224
+
+      some fixes to connection pool invalidate()
+
+.. changelog::
+    :version: 0.2.3
+    :released: Sat Jun 17 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to mapper compilation to be deferred.  this allows mappers
+      to be constructed in any order, and their relationships to each
+      other are compiled when the mappers are first used.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed a pretty big speed bottleneck in cascading behavior particularly
+      when backrefs were in use
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      the attribute instrumentation module has been completely rewritten; its
+      now a large degree simpler and clearer, slightly faster.  the "history"
+      of an attribute is no longer micromanaged with each change and is
+      instead part of a "CommittedState" object created when the
+      instance is first loaded.  HistoryArraySet is gone, the behavior of
+      list attributes is now more open ended (i.e. theyre not sets anymore).
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      py2.4 "set" construct used internally, falls back to sets.Set when
+      "set" not available/ordering is needed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to transaction control, so that repeated rollback() calls
+      dont fail (was failing pretty badly when flush() would raise
+      an exception in a larger try/except transaction block)
+
+    .. change::
+        :tags: 
+        :tickets: 151
+
+      "foreignkey" argument to relation() can also be a list.  fixed
+      auto-foreignkey detection
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed bug where tables with schema names werent getting indexed in
+      the MetaData object properly
+
+    .. change::
+        :tags: 
+        :tickets: 207
+
+      fixed bug where Column with redefined "key" property wasnt getting
+      type conversion happening in the ResultProxy
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed 'port' attribute of URL to be an integer if present
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed old bug where if a many-to-many table mapped as "secondary"
+      had extra columns, delete operations didnt work
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      bugfixes for mapping against UNION queries
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed incorrect exception class thrown when no DB driver present
+
+    .. change::
+        :tags: 
+        :tickets: 138
+
+      added NonExistentTable exception thrown when reflecting a table
+      that doesnt exist
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      small fix to ActiveMapper regarding one-to-one backrefs, other
+      refactorings
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overridden constructor in mapped classes gets __name__ and
+      __doc__ from the original class
+
+    .. change::
+        :tags: 
+        :tickets: 200
+
+      fixed small bug in selectresult.py regarding mapper extension
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      small tweak to cascade_mappers, not very strongly supported
+      function at the moment
+
+    .. change::
+        :tags: 
+        :tickets: 202
+
+      some fixes to between(), column.between() to propagate typing
+      information better
+
+    .. change::
+        :tags: 
+        :tickets: 203
+
+      if an object fails to be constructed, is not added to the
+      session
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      CAST function has been made into its own clause object with
+      its own compilation function in ansicompiler; allows MySQL
+      to silently ignore most CAST calls since MySQL
+      seems to only support the standard CAST syntax with Date types.
+      MySQL-compatible CAST support for strings, ints, etc. a TODO
+
+.. changelog::
+    :version: 0.2.2
+    :released: Mon Jun 05 2006
+
+    .. change::
+        :tags: 
+        :tickets: 190
+
+      big improvements to polymorphic inheritance behavior, enabling it
+      to work with adjacency list table structures
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      major fixes and refactorings to inheritance relationships overall,
+      more unit tests
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed "echo_pool" flag on create_engine()
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to docs, removed incorrect info that close() is unsafe to use
+      with threadlocal strategy (its totally safe !)
+
+    .. change::
+        :tags: 
+        :tickets: 188
+
+      create_engine() can take URLs as string or unicode
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      firebird support partially completed;
+      thanks to James Ralston and Brad Clements for their efforts.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Oracle url translation was broken, fixed, will feed host/port/sid
+      into cx_oracle makedsn() if 'database' field is present, else uses
+      straight TNS name from the 'host' field
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to using unicode criterion for query.get()/query.load()
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      count() function on selectables now uses table primary key or
+      first column instead of "1" for criterion, also uses label "rowcount"
+      instead of "count".
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      got rudimental "mapping to multiple tables" functionality cleaned up,
+      more correctly documented
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      restored global_connect() function, attaches to a DynamicMetaData
+      instance called "default_metadata".  leaving MetaData arg to Table
+      out will use the default metadata.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixes to session cascade behavior, entity_name propigation
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      reorganized unittests into subdirectories
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      more fixes to threadlocal connection nesting patterns
+
+.. changelog::
+    :version: 0.2.1
+    :released: Mon May 29 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      "pool" argument to create_engine() properly propagates
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixes to URL, raises exception if not parsed, does not pass blank
+      fields along to the DB connect string (a string such as
+      user:host@/db was breaking on postgres)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      small fixes to Mapper when it inserts and tries to get
+      new primary key values back
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      rewrote half of TLEngine, the ComposedSQLEngine used with
+      'strategy="threadlocal"'.  it now properly implements engine.begin()/
+      engine.commit(), which nest fully with connection.begin()/trans.commit().
+      added about six unittests.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      major "duh" in pool.Pool, forgot to put back the WeakValueDictionary.
+      unittest which was supposed to check for this was also silently missing
+      it.  fixed unittest to ensure that ConnectionFairy properly falls out
+      of scope.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      placeholder dispose() method added to SingletonThreadPool, doesnt
+      do anything yet
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      rollback() is automatically called when an exception is raised,
+      but only if theres no transaction in process (i.e. works more like
+      autocommit).
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed exception raise in sqlite if no sqlite module present
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added extra example detail for association object doc
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Connection adds checks for already being closed
+
+.. changelog::
+    :version: 0.2.0
+    :released: Sat May 27 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to Engine system so that what was formerly the SQLEngine
+      is now a ComposedSQLEngine which consists of a variety of components,
+      including a Dialect, ConnectionProvider, etc. This impacted all the
+      db modules as well as Session and Mapper.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      create_engine now takes only RFC-1738-style strings:
+      driver://user:password@host:port/database
+
+    .. change::
+        :tags: 
+        :tickets: 152
+
+      total rewrite of connection-scoping methodology, Connection objects
+      can now execute clause elements directly, added explicit "close" as
+      well as support throughout Engine/ORM to handle closing properly,
+      no longer relying upon __del__ internally to return connections
+      to the pool.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to Session interface and scoping.  uses hibernate-style
+      methods, including query(class), save(), save_or_update(), etc.
+      no threadlocal scope is installed by default.  Provides a binding
+      interface to specific Engines and/or Connections so that underlying
+      Schema objects do not need to be bound to an Engine.  Added a basic
+      SessionTransaction object that can simplistically aggregate transactions
+      across multiple engines.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to mapper's dependency and "cascade" behavior; dependency logic
+      factored out of properties.py into a separate module "dependency.py".
+      "cascade" behavior is now explicitly controllable, proper implementation
+      of "delete", "delete-orphan", etc.  dependency system can now determine at
+      flush time if a child object has a parent or not so that it makes better
+      decisions on how that child should be updated in the DB with regards to deletes.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to Schema to build upon MetaData object instead of an Engine.
+      Entire SQL/Schema system can be used with no Engines whatsoever, executed
+      solely by an explicit Connection object.  the "bound" methodlogy exists via the
+      BoundMetaData for schema objects.  ProxyEngine is generally not needed
+      anymore and is replaced by DynamicMetaData.
+
+    .. change::
+        :tags: 
+        :tickets: 167
+
+      true polymorphic behavior implemented, fixes
+
+    .. change::
+        :tags: 
+        :tickets: 147
+
+      "oid" system has been totally moved into compile-time behavior;
+      if they are used in an order_by where they are not available, the order_by
+      doesnt get compiled, fixes
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      overhaul to packaging; "mapping" is now "orm", "objectstore" is now
+      "session", the old "objectstore" namespace gets loaded in via the
+      "threadlocal" mod if used
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      mods now called in via "import <modname>".  extensions favored over
+      mods as mods are globally-monkeypatching
+
+    .. change::
+        :tags: 
+        :tickets: 154
+
+      fix to add_property so that it propagates properties to inheriting
+      mappers
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      backrefs create themselves against primary mapper of its originating
+      property, priamry/secondary join arguments can be specified to override.
+      helps their usage with polymorphic mappers
+
+    .. change::
+        :tags: 
+        :tickets: 31
+
+      "table exists" function has been implemented
+
+    .. change::
+        :tags: 
+        :tickets: 98
+
+      "create_all/drop_all" added to MetaData object
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improvements and fixes to topological sort algorithm, as well as more
+      unit tests
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      tutorial page added to docs which also can be run with a custom doctest
+      runner to ensure its properly working.  docs generally overhauled to
+      deal with new code patterns
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      many more fixes, refactorings.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      migration guide is available on the Wiki at
+      http://www.sqlalchemy.org/trac/wiki/02Migration
diff --git a/doc/build/changelog/changelog_03.rst b/doc/build/changelog/changelog_03.rst
new file mode 100644 (file)
index 0000000..c1944c7
--- /dev/null
@@ -0,0 +1,2928 @@
+
+==============
+0.3 Changelog
+==============
+
+                
+.. changelog::
+    :version: 0.3.11
+    :released: Sun Oct 14 2007
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      tweak DISTINCT precedence for clauses like
+      `func.count(t.c.col.distinct())`
+
+    .. change::
+        :tags: sql
+        :tickets: 719
+
+      Fixed detection of internal '$' characters in :bind$params
+
+    .. change::
+        :tags: sql
+        :tickets: 768
+
+      dont assume join criterion consists only of column objects
+
+    .. change::
+        :tags: sql
+        :tickets: 764
+
+      adjusted operator precedence of NOT to match '==' and others, so that
+      ~(x==y) produces NOT (x=y), which is compatible with MySQL < 5.0
+      (doesn't like "NOT x=y")
+
+    .. change::
+        :tags: orm
+        :tickets: 687
+
+      added a check for joining from A->B using join(), along two
+      different m2m tables.  this raises an error in 0.3 but is
+      possible in 0.4 when aliases are used.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed small exception throw bug in Session.merge()
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug where mapper, being linked to a join where one table had
+      no PK columns, would not detect that the joined table had no PK.
+
+    .. change::
+        :tags: orm
+        :tickets: 769
+
+      fixed bugs in determining proper sync clauses from custom inherit
+      conditions
+
+    .. change::
+        :tags: orm
+        :tickets: 813
+
+      backref remove object operation doesn't fail if the other-side
+      collection doesn't contain the item, supports noload collections
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      fixed another occasional race condition which could occur
+      when using pool with threadlocal setting
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      fixed specification of YEAR columns when generating schema
+
+    .. change::
+        :tags: mssql
+        :tickets: 679
+
+      added support for TIME columns (simulated using DATETIME)
+
+    .. change::
+        :tags: mssql
+        :tickets: 721
+
+      added support for BIGINT, MONEY, SMALLMONEY, UNIQUEIDENTIFIER and
+      SQL_VARIANT
+
+    .. change::
+        :tags: mssql
+        :tickets: 684
+
+      index names are now quoted when dropping from reflected tables
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      can now specify a DSN for PyODBC, using a URI like mssql:///?dsn=bob
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      when reflecting tables from alternate schemas, the "default" placed upon
+      the primary key, i.e. usually a sequence name, has the "schema" name
+      unconditionally quoted, so that schema names which need quoting are fine.
+      its slightly unnecessary for schema names which don't need quoting
+      but not harmful.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      passthrough for stringified dates
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      supports_sane_rowcount() set to False due to ticket #370 (right way).
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      fixed reflection of Column's nullable property.
+
+    .. change::
+        :tags: oracle
+        :tickets: 622, 751
+
+      removed LONG_STRING, LONG_BINARY from "binary" types, so type objects
+      don't try to read their values as LOB.
+
+.. changelog::
+    :version: 0.3.10
+    :released: Fri Jul 20 2007
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      a new mutex that was added in 0.3.9 causes the pool_timeout
+      feature to fail during a race condition; threads would
+      raise TimeoutError immediately with no delay if many threads
+      push the pool into overflow at the same time.  this issue has been
+      fixed.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      got connection-bound metadata to work with implicit execution
+
+    .. change::
+        :tags: sql
+        :tickets: 667
+
+      foreign key specs can have any chararcter in their identifiers
+
+    .. change::
+        :tags: sql
+        :tickets: 664
+
+      added commutativity-awareness to binary clause comparisons to
+      each other, improves ORM lazy load optimization
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      cleanup to connection-bound sessions, SessionTransaction
+
+    .. change::
+        :tags: postgres
+        :tickets: 571
+
+      fixed max identifier length (63)
+
+.. changelog::
+    :version: 0.3.9
+    :released: Sun Jul 15 2007
+
+    .. change::
+        :tags: general
+        :tickets: 607
+
+      better error message for NoSuchColumnError
+
+    .. change::
+        :tags: general
+        :tickets: 428
+
+      finally figured out how to get setuptools version in, available
+      as sqlalchemy.__version__
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      the various "engine" arguments, such as "engine", "connectable",
+      "engine_or_url", "bind_to", etc. are all present, but deprecated.
+      they all get replaced by the single term "bind".  you also
+      set the "bind" of MetaData using
+      metadata.bind = <engine or connection>
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      iteration over dict association proxies is now dict-like, not
+      InstrumentedList-like (e.g. over keys instead of values)
+
+    .. change::
+        :tags: ext
+        :tickets: 597
+
+      association proxies no longer bind tightly to source collections, and are constructed with a thunk instead
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      added selectone_by() to assignmapper
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      forwards-compatibility with 0.4: added one(), first(), and
+      all() to Query.  almost all Query functionality from 0.4 is
+      present in 0.3.9 for forwards-compat purposes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      reset_joinpoint() really really works this time, promise ! lets
+      you re-join from the root:
+      query.join(['a', 'b']).filter(<crit>).reset_joinpoint().\
+      join(['a', 'c']).filter(<some other crit>).all()
+      in 0.4 all join() calls start from the "root"
+
+    .. change::
+        :tags: orm
+        :tickets: 613
+
+      added synchronization to the mapper() construction step, to avoid
+      thread collisions when pre-existing mappers are compiling in a
+      different thread
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a warning is issued by Mapper when two primary key columns of the
+      same name are munged into a single attribute.  this happens frequently
+      when mapping to joins (or inheritance).
+
+    .. change::
+        :tags: orm
+        :tickets: 598
+
+      synonym() properties are fully supported by all Query joining/
+      with_parent operations
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed very stupid bug when deleting items with many-to-many
+      uselist=False relations
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      remember all that stuff about polymorphic_union ?  for
+      joined table inheritance ?  Funny thing...
+      You sort of don't need it for joined table inheritance, you
+      can just string all the tables together via outerjoin().
+      The UNION still applies if concrete tables are involved,
+      though (since nothing to join them on).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      small fix to eager loading to better work with eager loads
+      to polymorphic mappers that are using a straight "outerjoin"
+      clause
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      ForeignKey to a table in a schema thats not the default schema
+      requires the schema to be explicit; i.e. ForeignKey('alt_schema.users.id')
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      MetaData can now be constructed with an engine or url as the first
+      argument, just like BoundMetaData
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      BoundMetaData is now deprecated, and MetaData is a direct substitute.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      DynamicMetaData has been renamed to ThreadLocalMetaData.  the
+      DynamicMetaData name is deprecated and is an alias for ThreadLocalMetaData
+      or a regular MetaData if threadlocal=False
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      composite primary key is represented as a non-keyed set to allow for
+      composite keys consisting of cols with the same name; occurs within a
+      Join.  helps inheritance scenarios formulate correct PK.
+
+    .. change::
+        :tags: sql
+        :tickets: 185
+
+      improved ability to get the "correct" and most minimal set of primary key
+      columns from a join, equating foreign keys and otherwise equated columns.
+      this is also mostly to help inheritance scenarios formulate the best
+      choice of primary key columns.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added 'bind' argument to Sequence.create()/drop(), ColumnDefault.execute()
+
+    .. change::
+        :tags: sql
+        :tickets: 650
+
+      columns can be overridden in a reflected table with a "key"
+      attribute different than the column's name, including for primary key
+      columns
+
+    .. change::
+        :tags: sql
+        :tickets: 657
+
+      fixed "ambiguous column" result detection, when dupe col names exist
+      in a result
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      some enhancements to "column targeting", the ability to match a column
+      to a "corresponding" column in another selectable.  this affects mostly
+      ORM ability to map to complex joins
+
+    .. change::
+        :tags: sql
+        :tickets: 619
+
+      MetaData and all SchemaItems are safe to use with pickle.  slow
+      table reflections can be dumped into a pickled file to be reused later.
+      Just reconnect the engine to the metadata after unpickling.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added a mutex to QueuePool's "overflow" calculation to prevent a race
+      condition that can bypass max_overflow
+
+    .. change::
+        :tags: sql
+        :tickets: 623
+
+      fixed grouping of compound selects to give correct results. will break
+      on sqlite in some cases, but those cases were producing incorrect
+      results anyway, sqlite doesn't support grouped compound selects
+
+    .. change::
+        :tags: sql
+        :tickets: 620
+
+      fixed precedence of operators so that parenthesis are correctly applied
+
+    .. change::
+        :tags: sql
+        :tickets: 545
+
+      calling <column>.in_() (i.e. with no arguments) will return
+      "CASE WHEN (<column> IS NULL) THEN NULL ELSE 0 END = 1)", so that
+      NULL or False is returned in all cases, rather than throwing an error
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixed "where"/"from" criterion of select() to accept a unicode string
+      in addition to regular string - both convert to text()
+
+    .. change::
+        :tags: sql
+        :tickets: 558
+
+      added standalone distinct() function in addition to column.distinct()
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      result.last_inserted_ids() should return a list that is identically
+      sized to the primary key constraint of the table.  values that were
+      "passively" created and not available via cursor.lastrowid will be None.
+
+    .. change::
+        :tags: sql
+        :tickets: 589
+
+      long-identifier detection fixed to use > rather than >= for
+      max ident length
+
+    .. change::
+        :tags: sql
+        :tickets: 593
+
+      fixed bug where selectable.corresponding_column(selectable.c.col)
+      would not return selectable.c.col, if the selectable is a join
+      of a table and another join involving the same table.  messed
+      up ORM decision making
+
+    .. change::
+        :tags: sql
+        :tickets: 595
+
+      added Interval type to types.py
+
+    .. change::
+        :tags: mysql
+        :tickets: 625
+
+      fixed catching of some errors that imply a dropped connection
+
+    .. change::
+        :tags: mysql
+        :tickets: 624
+
+      fixed escaping of the modulo operator
+
+    .. change::
+        :tags: mysql
+        :tickets: 590
+
+      added 'fields' to reserved words
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      various reflection enhancement/fixes
+
+    .. change::
+        :tags: oracle
+        :tickets: 604
+
+      datetime fixes: got subsecond TIMESTAMP to work,
+      added OracleDate which supports types.Date with only year/month/day
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      added dialect flag "auto_convert_lobs", defaults to True; will cause any
+      LOB objects detected in a result set to be forced into OracleBinary
+      so that the LOB is read() automatically, if no typemap was present
+      (i.e., if a textual execute() was issued).
+
+    .. change::
+        :tags: oracle
+        :tickets: 624
+
+      mod operator '%' produces MOD
+
+    .. change::
+        :tags: oracle
+        :tickets: 542
+
+      converts cx_oracle datetime objects to Python datetime.datetime when
+      Python 2.3 used
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      fixed unicode conversion in Oracle TEXT type
+
+    .. change::
+        :tags: postgres
+        :tickets: 624
+
+      fixed escaping of the modulo operator
+
+    .. change::
+        :tags: postgres
+        :tickets: 570
+
+      added support for reflection of domains
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      types which are missing during reflection resolve to Null type
+      instead of raising an error
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      the fix in "schema" above fixes reflection of foreign keys from an
+      alt-schema table to a public schema table
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      rearranged dialect initialization so it has time to warn about pysqlite1
+      being too old.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      sqlite better handles datetime/date/time objects mixed and matched
+      with various Date/Time/DateTime columns
+
+    .. change::
+        :tags: sqlite
+        :tickets: 603
+
+      string PK column inserts dont get overwritten with OID
+
+    .. change::
+        :tags: mssql
+        :tickets: 634
+
+      fix port option handling for pyodbc
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      now able to reflect start and increment values for identity columns
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      preliminary support for using scope_identity() with pyodbc
+
+.. changelog::
+    :version: 0.3.8
+    :released: Sat Jun 02 2007
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      added detach() to Connection, allows underlying DBAPI connection
+      to be detached from its pool, closing on dereference/close()
+      instead of being reused by the pool.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      added invalidate() to Connection, immediately invalidates the
+      Connection and its underlying DBAPI connection.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      _Label class overrides compare_self to return its ultimate
+      object. meaning, if you say someexpr.label('foo') == 5, it
+      produces the correct "someexpr == 5".
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      _Label propagates "_hide_froms()" so that scalar selects
+      behave more properly with regards to FROM clause #574
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fix to long name generation when using oid_column as an order by
+      (oids used heavily in mapper queries)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      significant speed improvement to ResultProxy, pre-caches
+      TypeEngine dialect implementations and saves on function calls
+      per column
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      parenthesis are applied to clauses via a new _Grouping
+      construct. uses operator precedence to more intelligently apply
+      parenthesis to clauses, provides cleaner nesting of clauses
+      (doesnt mutate clauses placed in other clauses, i.e. no 'parens'
+      flag)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added 'modifier' keyword, works like func.<foo> except does not
+      add parenthesis.  e.g. select([modifier.DISTINCT(...)]) etc.
+
+    .. change::
+        :tags: sql
+        :tickets: 578
+
+      removed "no group by's in a select thats part of a UNION"
+      restriction
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added reset_joinpoint() method to Query, moves the "join point"
+      back to the starting mapper. 0.4 will change the behavior of
+      join() to reset the "join point" in all cases so this is an
+      interim method. for forwards compatibility, ensure joins across
+      multiple relations are specified using a single join(), i.e.
+      join(['a', 'b', 'c']).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug in query.instances() that wouldnt handle more than
+      on additional mapper or one additional column.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      "delete-orphan" no longer implies "delete". ongoing effort to
+      separate the behavior of these two operations.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      many-to-many relationships properly set the type of bind params
+      for delete operations on the association table
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      many-to-many relationships check that the number of rows deleted
+      from the association table by a delete operation matches the
+      expected results
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      session.get() and session.load() propagate **kwargs through to
+      query
+
+    .. change::
+        :tags: orm
+        :tickets: 577
+
+      fix to polymorphic query which allows the original
+      polymorphic_union to be embedded into a correlated subquery
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fix to select_by(<propname>=<object instance>) -style joins in
+      conjunction with many-to-many relationships, bug introduced in
+      r2556
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "primary_key" argument to mapper() is propagated to the
+      "polymorphic" mapper. primary key columns in this list get
+      normalized to that of the mapper's local table.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      restored logging of "lazy loading clause" under
+      sa.orm.strategies logger, got removed in 0.3.7
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      improved support for eagerloading of properties off of mappers
+      that are mapped to select() statements; i.e. eagerloader is
+      better at locating the correct selectable with which to attach
+      its LEFT OUTER JOIN.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Nearly all MySQL column types are now supported for declaration
+      and reflection. Added NCHAR, NVARCHAR, VARBINARY, TINYBLOB,
+      LONGBLOB, YEAR
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      The sqltypes.Binary passthrough now always builds a BLOB,
+      avoiding problems with very old database versions
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      support for column-level CHARACTER SET and COLLATE declarations,
+      as well as ASCII, UNICODE, NATIONAL and BINARY shorthand.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      set max identifier length to 31
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      supports_sane_rowcount() set to False due to ticket #370.
+      versioned_id_col feature wont work in FB.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      some execution fixes
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      new association proxy implementation, implementing complete
+      proxies to list, dict and set-based relation collections
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      added orderinglist, a custom list class that synchronizes an
+      object attribute with that object's position in the list
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      small fix to SelectResultsExt to not bypass itself during
+      select().
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      added filter(), filter_by() to assignmapper
+
+.. changelog::
+    :version: 0.3.7
+    :released: Sun Apr 29 2007
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      warnings module used for issuing warnings (instead of logging)
+
+    .. change::
+        :tags: engines
+        :tickets: 480
+
+      cleanup of DBAPI import strategies across all engines
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      refactoring of engine internals which reduces complexity,
+      number of codepaths; places more state inside of ExecutionContext
+      to allow more dialect control of cursor handling, result sets.
+      ResultProxy totally refactored and also has two versions of
+      "buffered" result sets used for different purposes.
+
+    .. change::
+        :tags: engines
+        :tickets: 514
+
+      server side cursor support fully functional in postgres.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      improved framework for auto-invalidation of connections that have
+      lost their underlying database, via dialect-specific detection
+      of exceptions corresponding to that database's disconnect
+      related error messages.  Additionally, when a "connection no
+      longer open" condition is detected, the entire connection pool
+      is discarded and replaced with a new instance.  #516
+
+    .. change::
+        :tags: engines
+        :tickets: 521
+
+      the dialects within sqlalchemy.databases become a setuptools
+      entry points. loading the built-in database dialects works the
+      same as always, but if none found will fall back to trying
+      pkg_resources to load an external module
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Engine contains a "url" attribute referencing the url.URL object
+      used by create_engine().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      keys() of result set columns are not lowercased, come back
+      exactly as they're expressed in cursor.description.  note this
+      causes colnames to be all caps in oracle.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      preliminary support for unicode table names, column names and
+      SQL statements added, for databases which can support them.
+      Works with sqlite and postgres so far.  Mysql *mostly* works
+      except the has_table() function does not work.  Reflection
+      works too.
+
+    .. change::
+        :tags: sql
+        :tickets: 522
+
+      the Unicode type is now a direct subclass of String, which now
+      contains all the "convert_unicode" logic.  This helps the variety
+      of unicode situations that occur in db's such as MS-SQL to be
+      better handled and allows subclassing of the Unicode datatype.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      ClauseElements can be used in in_() clauses now, such as bind
+      parameters, etc. #476
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      reverse operators implemented for `CompareMixin` elements,
+      allows expressions like "5 + somecolumn" etc. #474
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the "where" criterion of an update() and delete() now correlates
+      embedded select() statements against the table being updated or
+      deleted.  this works the same as nested select() statement
+      correlation, and can be disabled via the correlate=False flag on
+      the embedded select().
+
+    .. change::
+        :tags: sql
+        :tickets: 512
+
+      column labels are now generated in the compilation phase, which
+      means their lengths are dialect-dependent.  So on oracle a label
+      that gets truncated to 30 chars will go out to 63 characters
+      on postgres.  Also, the true labelname is always attached as the
+      accessor on the parent Selectable so theres no need to be aware
+      of the "truncated" label names.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      column label and bind param "truncation" also generate
+      deterministic names now, based on their ordering within the
+      full statement being compiled.  this means the same statement
+      will produce the same string across application restarts and
+      allowing DB query plan caching to work better.
+
+    .. change::
+        :tags: sql
+        :tickets: 513
+
+      the "mini" column labels generated when using subqueries, which
+      are to work around glitchy SQLite behavior that doesnt understand
+      "foo.id" as equivalent to "id", are now only generated in the case
+      that those named columns are selected from (part of)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the label() method on ColumnElement will properly propagate the
+      TypeEngine of the base element out to the label, including a label()
+      created from a scalar=True select() statement.
+
+    .. change::
+        :tags: sql
+        :tickets: 513
+
+      MS-SQL better detects when a query is a subquery and knows not to
+      generate ORDER BY phrases for those
+
+    .. change::
+        :tags: sql
+        :tickets: 505
+
+      fix for fetchmany() "size" argument being positional in most
+      dbapis
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      sending None as an argument to func.<something> will produce
+      an argument of NULL
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      query strings in unicode URLs get keys encoded to ascii
+      for **kwargs compat
+
+    .. change::
+        :tags: sql
+        :tickets: 523
+
+      slight tweak to raw execute() change to also support tuples
+      for positional parameters, not just lists
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fix to case() construct to propagate the type of the first
+      WHEN condition as the return type of the case statement
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed critical issue when, after options(eagerload()) is used,
+      the mapper would then always apply query "wrapping" behavior
+      for all subsequent LIMIT/OFFSET/DISTINCT queries, even if no
+      eager loading was applied on those subsequent queries.
+
+    .. change::
+        :tags: orm
+        :tickets: 541
+
+      added query.with_parent(someinstance) method.  searches for
+      target instance using lazy join criterion from parent instance.
+      takes optional string "property" to isolate the desired relation.
+      also adds static Query.query_from_parent(instance, property)
+      version.
+
+    .. change::
+        :tags: orm
+        :tickets: 554
+
+      improved query.XXX_by(someprop=someinstance) querying to use
+      similar methodology to with_parent, i.e. using the "lazy" clause
+      which prevents adding the remote instance's table to the SQL,
+      thereby making more complex conditions possible
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added generative versions of aggregates, i.e. sum(), avg(), etc.
+      to query. used via query.apply_max(), apply_sum(), etc.
+      #552
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fix to using distinct() or distinct=True in combination with
+      join() and similar
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      corresponding to label/bindparam name generation, eager loaders
+      generate deterministic names for the aliases they create using
+      md5 hashes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      improved/fixed custom collection classes when giving it "set"/
+      "sets.Set" classes or subclasses (was still looking for append()
+      methods on them during lazy loads)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      restored old "column_property()" ORM function (used to be called
+      "column()") to force any column expression to be added as a property
+      on a mapper, particularly those that aren't present in the mapped
+      selectable.  this allows "scalar expressions" of any kind to be
+      added as relations (though they have issues with eager loads).
+
+    .. change::
+        :tags: orm
+        :tickets: 533
+
+      fix to many-to-many relationships targeting polymorphic mappers
+
+    .. change::
+        :tags: orm
+        :tickets: 543
+
+      making progress with session.merge() as well as combining its
+      usage with entity_name
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the usual adjustments to relationships between inheriting mappers,
+      in this case establishing relation()s to subclass mappers where
+      the join conditions come from the superclass' table
+
+    .. change::
+        :tags: informix
+        :tickets: 
+
+      informix support added !  courtesy James Zhang, who put a ton
+      of effort in.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      removed silly behavior where sqlite would reflect UNIQUE indexes
+      as part of the primary key (?!)
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      small fix to allow successive compiles of the same SELECT object
+      which features LIMIT/OFFSET.  oracle dialect needs to modify
+      the object to have ROW_NUMBER OVER and wasn't performing
+      the full series of steps on successive compiles.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      support for SSL arguments given as inline within URL query string,
+      prefixed with "ssl_", courtesy terjeros@gmail.com.
+
+    .. change::
+        :tags: <schemaname>, mysql
+        :tickets: 
+
+      mysql uses "DESCRIBE.<tablename>", catching exceptions
+      if table doesnt exist, in order to determine if a table exists.
+      this supports unicode table names as well as schema names. tested
+      with MySQL5 but should work with 4.1 series as well. (#557)
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      big fix to AssociationProxy so that multiple AssociationProxy
+      objects can be associated with a single association collection.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      assign_mapper names methods according to their keys (i.e. __name__)
+      #551
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      pyodbc is now the preferred DB-API for MSSQL, and if no module is
+      specifically requested, will be loaded first on a module probe.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      The @@SCOPE_IDENTITY is now used instead of @@IDENTITY. This
+      behavior may be overridden with the engine_connect
+      "use_scope_identity" keyword parameter, which may also be specified
+      in the dburi.
+
+.. changelog::
+    :version: 0.3.6
+    :released: Fri Mar 23 2007
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      bindparam() names are now repeatable!  specify two
+      distinct bindparam()s with the same name in a single statement,
+      and the key will be shared.  proper positional/named args translate
+      at compile time.  for the old behavior of "aliasing" bind parameters
+      with conflicting names, specify "unique=True" - this option is
+      still used internally for all the auto-genererated (value-based)
+      bind parameters.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      slightly better support for bind params as column clauses, either
+      via bindparam() or via literal(), i.e. select([literal('foo')])
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      MetaData can bind to an engine either via "url" or "engine" kwargs
+      to constructor, or by using connect() method. BoundMetaData is
+      identical to MetaData except engine_or_url param is required.
+      DynamicMetaData is the same and provides thread-local connections be
+      default.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      exists() becomes useable as a standalone selectable, not just in a
+      WHERE clause, i.e. exists([columns], criterion).select()
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      correlated subqueries work inside of ORDER BY, GROUP BY
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixed function execution with explicit connections, i.e.
+      conn.execute(func.dosomething())
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      use_labels flag on select() wont auto-create labels for literal text
+      column elements, since we can make no assumptions about the text. to
+      create labels for literal columns, you can say "somecol AS
+      somelabel", or use literal_column("somecol").label("somelabel")
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      quoting wont occur for literal columns when they are "proxied" into
+      the column collection for their selectable (is_literal flag is
+      propagated). literal columns are specified via
+      literal_column("somestring").
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added "fold_equivalents" boolean argument to Join.select(), which
+      removes 'duplicate' columns from the resulting column clause that
+      are known to be equivalent based on the join condition. this is of
+      great usage when constructing subqueries of joins which Postgres
+      complains about if duplicate column names are present.
+
+    .. change::
+        :tags: sql
+        :tickets: 503
+
+      fixed use_alter flag on ForeignKeyConstraint
+
+    .. change::
+        :tags: sql
+        :tickets: 506
+
+      fixed usage of 2.4-only "reversed" in topological.py
+
+    .. change::
+        :tags: sql
+        :tickets: 501
+
+      for hackers, refactored the "visitor" system of ClauseElement and
+      SchemaItem so that the traversal of items is controlled by the
+      ClauseVisitor itself, using the method visitor.traverse(item).
+      accept_visitor() methods can still be called directly but will not
+      do any traversal of child items. ClauseElement/SchemaItem now have a
+      configurable get_children() method to return the collection of child
+      elements for each parent object. This allows the full traversal of
+      items to be clear and unambiguous (as well as loggable), with an
+      easy method of limiting a traversal (just pass flags which are
+      picked up by appropriate get_children() methods).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the "else_" parameter to the case statement now properly works when
+      set to zero.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the full featureset of the SelectResults extension has been merged
+      into a new set of methods available off of Query.  These methods
+      all provide "generative" behavior, whereby the Query is copied
+      and a new one returned with additional criterion added.
+      The new methods include:
+      
+          filter() - applies select criterion to the query
+          filter_by() - applies "by"-style criterion to the query
+          avg() - return the avg() function on the given column
+          join() - join to a property (or across a list of properties)
+          outerjoin() - like join() but uses LEFT OUTER JOIN
+          limit()/offset() - apply LIMIT/OFFSET
+          range-based access which applies limit/offset:
+             session.query(Foo)[3:5]
+          distinct() - apply DISTINCT
+          list() - evaluate the criterion and return results
+      
+      no incompatible changes have been made to Query's API and no methods
+      have been deprecated.  Existing methods like select(), select_by(),
+      get(), get_by() all execute the query at once and return results
+      like they always did.  join_to()/join_via() are still there although
+      the generative join()/outerjoin() methods are easier to use.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the return value for multiple mappers used with instances() now
+      returns a cartesian product of the requested list of mappers,
+      represented as a list of tuples. this corresponds to the documented
+      behavior. So that instances match up properly, the "uniquing" is
+      disabled when this feature is used.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query has add_entity() and add_column() generative methods. these
+      will add the given mapper/class or ColumnElement to the query at
+      compile time, and apply them to the instances() method. the user is
+      responsible for constructing reasonable join conditions (otherwise
+      you can get full cartesian products). result set is the list of
+      tuples, non-uniqued.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      strings and columns can also be sent to the *args of instances()
+      where those exact result columns will be part of the result tuples.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a full select() construct can be passed to query.select() (which
+      worked anyway), but also query.selectfirst(), query.selectone()
+      which will be used as is (i.e. no query is compiled). works
+      similarly to sending the results to instances().
+
+    .. change::
+        :tags: orm
+        :tickets: 495
+
+      eager loading will not "aliasize" "order by" clauses that were
+      placed in the select statement by something other than the eager
+      loader itself, to fix possibility of dupe columns as illustrated in. however, this means you have to be more careful with
+      the columns placed in the "order by" of Query.select(), that you
+      have explicitly named them in your criterion (i.e. you cant rely on
+      the eager loader adding them in for you)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added a handy multi-use "identity_key()" method to Session, allowing
+      the generation of identity keys for primary key values, instances,
+      and rows, courtesy Daniel Miller
+
+    .. change::
+        :tags: orm
+        :tickets: 249
+
+      many-to-many table will be properly handled even for operations that
+      occur on the "backref" side of the operation
+
+    .. change::
+        :tags: orm
+        :tickets: 492
+
+      added "refresh-expire" cascade.  allows refresh() and
+      expire() calls to propagate along relationships.
+
+    .. change::
+        :tags: orm
+        :tickets: 493
+
+      more fixes to polymorphic relations, involving proper lazy-clause
+      generation on many-to-one relationships to polymorphic mappers. also fixes to detection of "direction", more specific
+      targeting of columns that belong to the polymorphic union vs. those
+      that dont.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      some fixes to relationship calcs when using "viewonly=True" to pull
+      in other tables into the join condition which arent parent of the
+      relationship's parent/child mappings
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      flush fixes on cyclical-referential relationships that contain
+      references to other instances outside of the cyclical chain, when
+      some of the objects in the cycle are not actually part of the flush
+
+    .. change::
+        :tags: orm
+        :tickets: 500
+
+      put an aggressive check for "flushing object A with a collection of
+      B's, but you put a C in the collection" error condition - **even if
+      C is a subclass of B**, unless B's mapper loads polymorphically.
+      Otherwise, the collection will later load a "B" which should be a
+      "C" (since its not polymorphic) which breaks in bi-directional
+      relationships (i.e. C has its A, but A's backref will lazyload it as
+      a different instance of type "B") This check is going
+      to bite some of you who do this without issues, so the error message
+      will also document a flag "enable_typechecks=False" to disable this
+      checking. But be aware that bi-directional relationships in
+      particular become fragile without this check.
+
+    .. change::
+        :tags: extensions
+        :tickets: 472
+
+      options() method on SelectResults now implemented "generatively"
+      like the rest of the SelectResults methods.  But
+      you're going to just use Query now anyway.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      query() method is added by assignmapper.  this helps with
+      navigating to all the new generative methods on Query.
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      removed seconds input on DATE column types (probably
+        should remove the time altogether)
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      null values in float fields no longer raise errors
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      LIMIT with OFFSET now raises an error (MS-SQL has no OFFSET support)
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 509
+
+      added an facility to use the MSSQL type VARCHAR(max) instead of TEXT
+      for large unsized string fields. Use the new "text_as_varchar" to
+      turn it on.
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      ORDER BY clauses without a LIMIT are now stripped in subqueries, as
+      MS-SQL forbids this usage
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 480
+
+      cleanup of module importing code; specifiable DB-API module; more
+      explicit ordering of module preferences.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      got binary working for any size input !  cx_oracle works fine,
+      it was my fault as BINARY was being passed and not BLOB for
+      setinputsizes (also unit tests werent even setting input sizes).
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      also fixed CLOB read/write on a separate changeset.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      auto_setinputsizes defaults to True for Oracle, fixed cases where
+      it improperly propagated bad types.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      added a catchall **kwargs to MSString, to help reflection of
+      obscure types (like "varchar() binary" in MS 4.0)
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      added explicit MSTimeStamp type which takes effect when using
+      types.TIMESTAMP.
+
+.. changelog::
+    :version: 0.3.5
+    :released: Thu Feb 22 2007
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the value of "case_sensitive" defaults to True now, regardless of the
+      casing of the identifier, unless specifically set to False. this is
+      because the object might be label'ed as something else which does
+      contain mixed case, and propigating "case_sensitive=False" breaks that.
+      Other fixes to quoting when using labels and "fake" column objects
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added a "supports_execution()" method to ClauseElement, so that
+      individual kinds of clauses can express if they are appropriate for
+      executing...such as, you can execute a "select", but not a "Table" or a
+      "Join".
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixed argument passing to straight textual execute() on engine,
+      connection. can handle *args or a list instance for positional, **kwargs
+      or a dict instance for named args, or a list of list or dicts to invoke
+      executemany()
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      small fix to BoundMetaData to accept unicode or string URLs
+
+    .. change::
+        :tags: sql
+        :tickets: 466
+
+      fixed named PrimaryKeyConstraint generation courtesy
+      andrija at gmail
+
+    .. change::
+        :tags: sql
+        :tickets: 464
+
+      fixed generation of CHECK constraints on columns
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixes to tometadata() operation to propagate Constraints at column and
+      table level
+
+    .. change::
+        :tags: oracle
+        :tickets: 436
+
+      when returning "rowid" as the ORDER BY column or in use with ROW_NUMBER
+      OVER, oracle dialect checks the selectable its being applied to and will
+      switch to table PK if not applicable, i.e. for a UNION. checking for
+      DISTINCT, GROUP BY (other places that rowid is invalid) still a TODO.
+      allows polymorphic mappings to function.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      sequences on a non-pk column will properly fire off on INSERT
+
+    .. change::
+        :tags: oracle
+        :tickets: 435
+
+      added PrefetchingResultProxy support to pre-fetch LOB columns when they
+      are known to be present, fixes
+
+    .. change::
+        :tags: oracle
+        :tickets: 379
+
+      implemented reflection of tables based on synonyms, including across
+      dblinks
+
+    .. change::
+        :tags: oracle
+        :tickets: 363
+
+      issues a log warning when a related table cant be reflected due to
+      certain permission errors
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      fix to reflection on older DB's that might return array() type for
+      "show variables like" statements
+
+    .. change::
+        :tags: postgres
+        :tickets: 442
+
+      better reflection of sequences for alternate-schema Tables
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      sequences on a non-pk column will properly fire off on INSERT
+
+    .. change::
+        :tags: postgres
+        :tickets: 460, 444
+
+      added PGInterval type, PGInet type
+
+    .. change::
+        :tags: mssql
+        :tickets: 419
+
+      preliminary support for pyodbc (Yay!)
+
+    .. change::
+        :tags: mssql
+        :tickets: 298
+
+      better support for NVARCHAR types added
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      fix for commit logic on pymssql
+
+    .. change::
+        :tags: mssql
+        :tickets: 456
+
+      fix for query.get() with schema
+
+    .. change::
+        :tags: mssql
+        :tickets: 473
+
+      fix for non-integer relationships
+
+    .. change::
+        :tags: mssql
+        :tickets: 419
+
+      DB-API module now selectable at run-time
+
+    .. change::
+        :tags: tickets:422, 481, 415, mssql
+        :tickets: 
+
+      now passes many more unit tests
+
+    .. change::
+        :tags: mssql
+        :tickets: 479
+
+      better unittest compatibility with ANSI functions
+
+    .. change::
+        :tags: mssql
+        :tickets: 415
+
+      improved support for implicit sequence PK columns with auto-insert
+
+    .. change::
+        :tags: mssql
+        :tickets: 371
+
+      fix for blank password in adodbapi
+
+    .. change::
+        :tags: mssql
+        :tickets: 481
+
+      fixes to get unit tests working with pyodbc
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      fix to auto_identity_insert on db-url query
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      added query_timeout to db-url query parms. currently works only for
+      pymssql
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      tested with pymssql 0.8.0 (which is now LGPL)
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 441, 448, 439
+
+      another refactoring to relationship calculation. Allows more accurate
+      ORM behavior with relationships from/to/between mappers, particularly
+      polymorphic mappers, also their usage with Query, SelectResults. tickets
+      include,,.
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 
+
+      removed deprecated method of specifying custom collections on classes;
+      you must now use the "collection_class" option. the old way was
+      beginning to produce conflicts when people used assign_mapper(), which
+      now patches an "options" method, in conjunction with a relationship
+      named "options". (relationships take precedence over monkeypatched
+      assign_mapper methods).
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 454
+
+      extension() query option propagates to Mapper._instance() method so that
+      all loading-related methods get called
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 
+
+      eager relation to an inheriting mapper wont fail if no rows returned for
+      the relationship.
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 486
+
+      eager relation loading bug fixed for eager relation on multiple
+      descendant classes
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 423
+
+      fix for very large topological sorts, courtesy ants.aasma at gmail
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 
+
+      eager loading is slightly more strict about detecting "self-referential"
+      relationships, specifically between polymorphic mappers. this results in
+      an "eager degrade" to lazy loading.
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 449
+
+      improved support for complex queries embedded into "where" criterion for
+      query.select()
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 485
+
+      mapper options like eagerload(), lazyload(), deferred(), will work for
+      "synonym()" relationships
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 445
+
+      fixed bug where cascade operations incorrectly included deleted
+      collection items in the cascade
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 478
+
+      fixed relationship deletion error when one-to-many child item is moved
+      to a new parent in a single unit of work
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 
+
+      fixed relationship deletion error where parent/child with a single
+      column as PK/FK on the child would raise a "blank out the primary key"
+      error, if manually deleted or "delete" cascade without "delete-orphan"
+      was used
+
+    .. change::
+        :tags: orm, bugs
+        :tickets: 
+
+      fix to deferred so that load operation doesnt mistakenly occur when only
+      PK col attributes are set
+
+    .. change::
+        :tags: orm, enhancements
+        :tickets: 385
+
+      implemented foreign_keys argument to mapper. use in
+      conjunction with primaryjoin/secondaryjoin arguments to specify/override
+      foreign keys defined on the Table instance.
+
+    .. change::
+        :tags: orm, enhancements
+        :tickets: 
+
+      contains_eager('foo') automatically implies eagerload('foo')
+
+    .. change::
+        :tags: orm, enhancements
+        :tickets: 
+
+      added "alias" argument to contains_eager(). use it to specify the string
+      name or Alias instance of an alias used in the query for the eagerly
+      loaded child items. easier to use than "decorator"
+
+    .. change::
+        :tags: orm, enhancements
+        :tickets: 
+
+      added "contains_alias()" option for result set mapping to an alias of
+      the mapped table
+
+    .. change::
+        :tags: orm, enhancements
+        :tickets: 468
+
+      added support for py2.5 "with" statement with SessionTransaction
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      added distinct() method to SelectResults. generally should only make a
+      difference when using count().
+
+    .. change::
+        :tags: extensions
+        :tickets: 472
+
+      added options() method to SelectResults, equivalent to query.options()
+
+    .. change::
+        :tags: extensions
+        :tickets: 462
+
+      added optional __table_opts__ dictionary to ActiveMapper, will send kw
+      options to Table objects
+
+    .. change::
+        :tags: extensions
+        :tickets: 467
+
+      added selectfirst(), selectfirst_by() to assign_mapper
+
+.. changelog::
+    :version: 0.3.4
+    :released: Tue Jan 23 2007
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      global "insure"->"ensure" change. in US english "insure" is actually
+      largely interchangeable with "ensure" (so says the dictionary), so I'm not
+      completely illiterate, but its definitely sub-optimal to "ensure" which is
+      non-ambiguous.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added "fetchmany()" support to ResultProxy
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added support for column "key" attribute to be useable in
+      row[<key>]/row.<key>
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      changed "BooleanExpression" to subclass from "BinaryExpression", so that
+      boolean expressions can also follow column-clause behaviors (i.e. label(),
+      etc).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      trailing underscores are trimmed from func.<xxx> calls, such as func.if_()
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fix to correlation of subqueries when the column list of the select
+      statement is constructed with individual calls to append_column(); this
+      fixes an ORM bug whereby nested select statements were not getting
+      correlated with the main select generated by the Query object.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      another fix to subquery correlation so that a subquery which has only one
+      FROM element will *not* correlate that single element, since at least one
+      FROM element is required in a query.
+
+    .. change::
+        :tags: sql
+        :tickets: 414
+
+      default "timezone" setting is now False. this corresponds to Python's
+      datetime behavior as well as Postgres' timestamp/time types (which is the
+      only timezone-sensitive dialect at the moment)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the "op()" function is now treated as an "operation", rather than a
+      "comparison". the difference is, an operation produces a BinaryExpression
+      from which further operations can occur whereas comparison produces the
+      more restrictive BooleanExpression
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      trying to redefine a reflected primary key column as non-primary key raises
+      an error
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      type system slightly modified to support TypeDecorators that can be
+      overridden by the dialect (ok, thats not very clear, it allows the mssql
+      tweak below to be possible)
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      added an NVarchar type (produces NVARCHAR), also MSUnicode which provides
+      Unicode-translation for the NVarchar regardless of dialect convert_unicode
+      setting.
+
+    .. change::
+        :tags: postgres
+        :tickets: 424
+
+      fix to the initial checkfirst for tables to take current schema into
+      account
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      postgres has an optional "server_side_cursors=True" flag which will utilize
+      server side cursors. these are appropriate for fetching only partial
+      results and are necessary for working with very large unbounded result
+      sets. While we'd like this to be the default behavior, different
+      environments seem to have different results and the causes have not been
+      isolated so we are leaving the feature off by default for now. Uses an
+      apparently undocumented psycopg2 behavior recently discovered on the
+      psycopg mailing list.
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      added "BIGSERIAL" support for postgres table with
+      PGBigInteger/autoincrement
+
+    .. change::
+        :tags: postgres
+        :tickets: 402
+
+      fixes to postgres reflection to better handle when schema names are
+      present; thanks to jason (at) ncsmags.com
+
+    .. change::
+        :tags: mysql
+        :tickets: 420
+
+      mysql is inconsistent with what kinds of quotes it uses in foreign keys
+      during a SHOW CREATE TABLE, reflection updated to accomodate for all three
+      styles
+
+    .. change::
+        :tags: mysql
+        :tickets: 418
+
+      mysql table create options work on a generic passthru now, i.e. Table(...,
+      mysql_engine='InnoDB', mysql_collate="latin1_german2_ci",
+      mysql_auto_increment="5", mysql_<somearg>...), helps
+
+    .. change::
+        :tags: firebird
+        :tickets: 408
+
+      order of constraint creation puts primary key first before all other
+      constraints; required for firebird, not a bad idea for others
+
+    .. change::
+        :tags: firebird
+        :tickets: 409
+
+      Firebird fix to autoload multifield foreign keys
+
+    .. change::
+        :tags: firebird
+        :tickets: 409
+
+      Firebird NUMERIC type properly handles a type without precision
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      *slight* support for binary, but still need to figure out how to insert
+      reasonably large values (over 4K). requires auto_setinputsizes=True sent to
+      create_engine(), rows must be fully fetched individually, etc.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      poked the first hole in the can of worms: saying
+      query.select_by(somerelationname=someinstance) will create the join of the
+      primary key columns represented by "somerelationname"'s mapper to the
+      actual primary key in "someinstance".
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      reworked how relations interact with "polymorphic" mappers, i.e. mappers
+      that have a select_table as well as polymorphic flags. better determination
+      of proper join conditions, interaction with user- defined join conditions,
+      and support for self-referential polymorphic mappers.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      related to polymorphic mapping relations, some deeper error checking when
+      compiling relations, to detect an ambiguous "primaryjoin" in the case that
+      both sides of the relationship have foreign key references in the primary
+      join condition. also tightened down conditions used to locate "relation
+      direction", associating the "foreignkey" of the relationship with the
+      "primaryjoin"
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a little bit of improvement to the concept of a "concrete" inheritance
+      mapping, though that concept is not well fleshed out yet (added test case
+      to support concrete mappers on top of a polymorphic base).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fix to "proxy=True" behavior on synonym()
+
+    .. change::
+        :tags: orm
+        :tickets: 427
+
+      fixed bug where delete-orphan basically didn't work with many-to-many
+      relationships, backref presence generally hid the symptom
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added a mutex to the mapper compilation step. ive been reluctant to add any
+      kind of threading anything to SA but this is one spot that its its really
+      needed since mappers are typically "global", and while their state does not
+      change during normal operation, the initial compilation step does modify
+      internal state significantly, and this step usually occurs not at
+      module-level initialization time (unless you call compile()) but at
+      first-request time
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      basic idea of "session.merge()" actually implemented.  needs more testing.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "compile_mappers()" function as a shortcut to compiling all mappers
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fix to MapperExtension create_instance so that entity_name properly
+      associated with new instance
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      speed enhancements to ORM object instantiation, eager loading of rows
+
+    .. change::
+        :tags: orm
+        :tickets: 406
+
+      invalid options sent to 'cascade' string will raise an exception
+
+    .. change::
+        :tags: orm
+        :tickets: 407
+
+      fixed bug in mapper refresh/expire whereby eager loaders didnt properly
+      re-populate item lists
+
+    .. change::
+        :tags: orm
+        :tickets: 413
+
+      fix to post_update to ensure rows are updated even for non insert/delete
+      scenarios
+
+    .. change::
+        :tags: orm
+        :tickets: 412
+
+      added an error message if you actually try to modify primary key values on
+      an entity and then flush it
+
+    .. change::
+        :tags: extensions
+        :tickets: 426
+
+      added "validate=False" argument to assign_mapper, if True will ensure that
+      only mapped attributes are named
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      assign_mapper gets "options", "instances" functions added (i.e.
+      MyClass.instances())
+
+.. changelog::
+    :version: 0.3.3
+    :released: Fri Dec 15 2006
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      string-based FROM clauses fixed, i.e. select(..., from_obj=["sometext"])
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixes to passive_deletes flag, lazy=None (noload) flag
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added example/docs for dealing with large collections
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added object_session() method to sqlalchemy namespace
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed QueuePool bug whereby its better able to reconnect to a database
+      that was not reachable (thanks to Sébastien Lelong), also fixed dispose()
+      method
+
+    .. change::
+        :tags: 
+        :tickets: 396
+
+      patch that makes MySQL rowcount work correctly!
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to MySQL catch of 2006/2014 errors to properly re-raise OperationalError
+      exception
+
+.. changelog::
+    :version: 0.3.2
+    :released: Sun Dec 10 2006
+
+    .. change::
+        :tags: 
+        :tickets: 387
+
+      major connection pool bug fixed.  fixes MySQL out of sync
+      errors, will also prevent transactions getting rolled back
+      accidentally in all DBs
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      major speed enhancements vs. 0.3.1, to bring speed
+      back to 0.2.8 levels
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      made conditional dozens of debug log calls that were
+      time-intensive to generate log messages
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed bug in cascade rules whereby the entire object graph
+      could be unnecessarily cascaded on the save/update cascade
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      various speedups in attributes module
+
+    .. change::
+        :tags: 
+        :tickets: 388
+
+      identity map in Session is by default *no longer weak referencing*.
+      to have it be weak referencing, use create_session(weak_identity_map=True)
+      fixes
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      MySQL detects errors 2006 (server has gone away) and 2014
+      (commands out of sync) and invalidates the connection on which it occured.
+
+    .. change::
+        :tags: 
+        :tickets: 307
+
+      MySQL bool type fix:
+
+    .. change::
+        :tags: 
+        :tickets: 382, 349
+
+      postgres reflection fixes:
+
+    .. change::
+        :tags: 
+        :tickets: 247
+
+      added keywords for EXCEPT, INTERSECT, EXCEPT ALL, INTERSECT ALL
+
+    .. change::
+        :tags: 
+        :tickets: 2110
+
+      assign_mapper in assignmapper extension returns the created mapper
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added label() function to Select class, when scalar=True is used
+      to create a scalar subquery
+      i.e. "select x, y, (select max(foo) from table) AS foomax from table"
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added onupdate and ondelete keyword arguments to ForeignKey; propagate
+      to underlying ForeignKeyConstraint if present.  (dont propagate in the
+      other direction, however)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fix to session.update() to preserve "dirty" status of incoming object
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      sending a selectable to an IN via the in_() function no longer creates
+      a "union" out of multiple selects; only one selectable to a the in_() function
+      is allowed now (make a union yourself if union is needed)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      improved support for disabling save-update cascade via cascade="none" etc.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "remote_side" argument to relation(), used only with self-referential
+      mappers to force the direction of the parent/child relationship.  replaces
+      the usage of the "foreignkey" parameter for "switching" the direction.
+      "foreignkey" argument is deprecated for all uses and will eventually
+      be replaced by an argument dedicated to ForeignKey specification on mappers.
+
+.. changelog::
+    :version: 0.3.1
+    :released: Mon Nov 13 2006
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 
+
+      some new Pool utility classes, updated docs
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 
+
+      "use_threadlocal" on Pool defaults to False (same as create_engine)
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 
+
+      fixed direct execution of Compiled objects
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 
+
+      create_engine() reworked to be strict about incoming **kwargs.  all keyword
+      arguments must be consumed by one of the dialect, connection pool, and engine
+      constructors, else a TypeError is thrown which describes the full set of
+      invalid kwargs in relation to the selected dialect/pool/engine configuration.
+
+    .. change::
+        :tags: databases/types
+        :tickets: 
+
+      MySQL catches exception on "describe" and reports as NoSuchTableError
+
+    .. change::
+        :tags: databases/types
+        :tickets: 
+
+      further fixes to sqlite booleans, weren't working as defaults
+
+    .. change::
+        :tags: databases/types
+        :tickets: 
+
+      fix to postgres sequence quoting when using schemas
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "delete" cascade will load in all child objects, if they were not
+      loaded already.  this can be turned off (i.e. the old behavior) by setting
+      passive_deletes=True on a relation().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      adjustments to reworked eager query generation to not fail on circular
+      eager-loaded relationships (like backrefs)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug where eagerload() (nor lazyload()) option didn't properly
+      instruct the Query whether or not to use "nesting" when producing a
+      LIMIT query.
+
+    .. change::
+        :tags: orm
+        :tickets: 360
+
+      fixed bug in circular dependency sorting at flush time; if object A
+      contained a cyclical many-to-one relationship to object B, and object B
+      was just attached to object A, *but* object B itself wasnt changed,
+      the many-to-one synchronize of B's primary key attribute to A's foreign key
+      attribute wouldnt occur.
+
+    .. change::
+        :tags: orm
+        :tickets: 325
+
+      implemented from_obj argument for query.count, improves count function
+      on selectresults
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added an assertion within the "cascade" step of ORM relationships to check
+      that the class of object attached to a parent object is appropriate
+      (i.e. if A.items stores B objects, raise an error if a C is appended to A.items)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      new extension sqlalchemy.ext.associationproxy, provides transparent
+      "association object" mappings.  new example
+      examples/association/proxied_association.py illustrates.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      improvement to single table inheritance to load full hierarchies beneath
+      the target class
+
+    .. change::
+        :tags: orm
+        :tickets: 362
+
+      fix to subtle condition in topological sort where a node could appear twice,
+      for
+
+    .. change::
+        :tags: orm
+        :tickets: 365
+
+      additional rework to topological sort, refactoring, for
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      "delete-orphan" for a certain type can be set on more than one parent class;
+      the instance is an "orphan" only if its not attached to *any* of those parents
+
+.. changelog::
+    :version: 0.3.0
+    :released: Sun Oct 22 2006
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      logging is now implemented via standard python "logging" module.
+      "echo" keyword parameters are still functional but set/unset
+      log levels for their respective classes/instances.  all logging
+      can be controlled directly through the Python API by setting
+      INFO and DEBUG levels for loggers in the "sqlalchemy" namespace.
+      class-level logging is under "sqlalchemy.<module>.<classname>",
+      instance-level logging under "sqlalchemy.<module>.<classname>.0x..<00-FF>".
+      Test suite includes "--log-info" and "--log-debug" arguments
+      which work independently of --verbose/--quiet.  Logging added
+      to orm to allow tracking of mapper configurations, row iteration.
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      the documentation-generation system has been overhauled to be
+      much simpler in design and more integrated with Markdown
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      sqlite boolean datatype converts False/True to 0/1 by default
+
+    .. change::
+        :tags: sqlite
+        :tickets: 335
+
+      fixes to Date/Time (SLDate/SLTime) types; works as good as postgres
+      now
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      fixes bug 261 (table reflection broken for MS-SQL case-sensitive
+      databases)
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      can now specify port for pymssql
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      introduces new "auto_identity_insert" option for auto-switching
+      between "SET IDENTITY_INSERT" mode when values specified for IDENTITY columns
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      now supports multi-column foreign keys
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      fix to reflecting date/datetime columns
+
+    .. change::
+        :tags: ms-sql
+        :tickets: 
+
+      NCHAR and NVARCHAR type support added
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Oracle has experimental support for cx_Oracle.TIMESTAMP, which requires
+      a setinputsizes() call on the cursor that is now enabled via the
+      'auto_setinputsizes' flag to the oracle dialect.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      aliases do not use "AS"
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      correctly raises NoSuchTableError when reflecting non-existent table
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      a fair amount of cleanup to the schema package, removal of ambiguous
+      methods, methods that are no longer needed.  slightly more constrained
+      useage, greater emphasis on explicitness
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      the "primary_key" attribute of Table and other selectables becomes
+      a setlike ColumnCollection object; is ordered but not numerically
+      indexed.  a comparison clause between two pks that are derived from the
+      same underlying tables (i.e. such as two Alias objects) can be generated
+      via table1.primary_key==table2.primary_key
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      ForeignKey(Constraint) supports "use_alter=True", to create/drop a foreign key
+      via ALTER.  this allows circular foreign key relationships to be set up.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      append_item() methods removed from Table and Column; preferably
+      construct Table/Column/related objects inline, but if needed use
+      append_column(), append_foreign_key(), append_constraint(), etc.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      table.create() no longer returns the Table object, instead has no
+      return value.  the usual case is that tables are created via metadata,
+      which is preferable since it will handle table dependencies.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      added UniqueConstraint (goes at Table level), CheckConstraint
+      (goes at Table or Column level).
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      index=False/unique=True on Column now creates a UniqueConstraint,
+      index=True/unique=False creates a plain Index,
+      index=True/unique=True on Column creates a unique Index.  'index'
+      and 'unique' keyword arguments to column are now boolean only; for
+      explcit names and groupings of indexes or unique constraints, use the
+      UniqueConstraint/Index constructs explicitly.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      added autoincrement=True to Column; will disable schema generation
+      of SERIAL/AUTO_INCREMENT/identity seq for postgres/mysql/mssql if
+      explicitly set to False
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      TypeEngine objects now have methods to deal with copying and comparing
+      values of their specific type.  Currently used by the ORM, see below.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      fixed condition that occurred during reflection when a primary key
+      column was explciitly overridden, where the PrimaryKeyConstraint would
+      get both the reflected and the programmatic column doubled up
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      the "foreign_key" attribute on Column and ColumnElement in general
+      is deprecated, in favor of the "foreign_keys" list/set-based attribute,
+      which takes into account multiple foreign keys on one column.
+      "foreign_key" will return the first element in the "foreign_keys" list/set
+      or None if the list is empty.
+
+    .. change::
+        :tags: connections/pooling/execution
+        :tickets: 
+
+      connection pool tracks open cursors and automatically closes them
+      if connection is returned to pool with cursors still opened.  Can be
+      affected by options which cause it to raise an error instead, or to
+      do nothing.  fixes issues with MySQL, others
+
+    .. change::
+        :tags: connections/pooling/execution
+        :tickets: 
+
+      fixed bug where Connection wouldnt lose its Transaction
+      after commit/rollback
+
+    .. change::
+        :tags: connections/pooling/execution
+        :tickets: 
+
+      added scalar() method to ComposedSQLEngine, ResultProxy
+
+    .. change::
+        :tags: connections/pooling/execution
+        :tickets: 
+
+      ResultProxy will close() the underlying cursor when the ResultProxy
+      itself is closed.  this will auto-close cursors for ResultProxy objects
+      that have had all their rows fetched (or had scalar() called).
+
+    .. change::
+        :tags: connections/pooling/execution
+        :tickets: 
+
+      ResultProxy.fetchall() internally uses DBAPI fetchall() for better efficiency,
+      added to mapper iteration as well (courtesy Michael Twomey)
+
+    .. change::
+        :tags: construction, sql
+        :tickets: 292
+
+      changed "for_update" parameter to accept False/True/"nowait"
+      and "read", the latter two of which are interpreted only by
+      Oracle and Mysql
+
+    .. change::
+        :tags: construction, sql
+        :tickets: 
+
+      added extract() function to sql dialect
+      (SELECT extract(field FROM expr))
+
+    .. change::
+        :tags: construction, sql
+        :tickets: 
+
+      BooleanExpression includes new "negate" argument to specify
+      the appropriate negation operator if one is available.
+
+    .. change::
+        :tags: construction, sql
+        :tickets: 
+
+      calling a negation on an "IN" or "IS" clause will result in
+      "NOT IN", "IS NOT" (as opposed to NOT (x IN y)).
+
+    .. change::
+        :tags: construction, sql
+        :tickets: 172
+
+      Function objects know what to do in a FROM clause now.  their
+      behavior should be the same, except now you can also do things like
+      select(['*'], from_obj=[func.my_function()]) to get multiple
+      columns from the result, or even use sql.column() constructs to name the
+      return columns
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      attribute tracking modified to be more intelligent about detecting
+      changes, particularly with mutable types.  TypeEngine objects now
+      take a greater role in defining how to compare two scalar instances,
+      including the addition of a MutableType mixin which is implemented by
+      PickleType.  unit-of-work now tracks the "dirty" list as an expression
+      of all persistent objects where the attribute manager detects changes.
+      The basic issue thats fixed is detecting changes on PickleType
+      objects, but also generalizes type handling and "modified" object
+      checking to be more complete and extensible.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a wide refactoring to "attribute loader" and "options" architectures.
+      ColumnProperty and PropertyLoader define their loading behaivor via switchable
+      "strategies", and MapperOptions no longer use mapper/property copying
+      in order to function; they are instead propagated via QueryContext
+      and SelectionContext objects at query/instances time.
+      All of the internal copying of mappers and properties that was used to handle
+      inheritance as well as options() has been removed; the structure
+      of mappers and properties is much simpler than before and is clearly laid out
+      in the new 'interfaces' module.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      related to the mapper/property overhaul, internal refactoring to
+      mapper instances() method to use a SelectionContext object to track
+      state during the operation.
+      SLIGHT API BREAKAGE: the append_result() and populate_instances()
+      methods on MapperExtension have a slightly different method signature
+      now as a result of the change; hoping that these methods are not
+      in widespread use as of yet.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      instances() method moved to Query now, backwards-compatible
+      version remains on Mapper.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added contains_eager() MapperOption, used in conjunction with
+      instances() to specify properties that should be eagerly loaded
+      from the result set, using their plain column names by default, or translated
+      given an custom row-translation function.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      more rearrangements of unit-of-work commit scheme to better allow
+      dependencies within circular flushes to work properly...updated
+      task traversal/logging implementation
+
+    .. change::
+        :tags: orm
+        :tickets: 321
+
+      polymorphic mappers (i.e. using inheritance) now produces INSERT
+      statements in order of tables across all inherited classes
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added an automatic "row switch" feature to mapping, which will
+      detect a pending instance/deleted instance pair with the same
+      identity key and convert the INSERT/DELETE to a single UPDATE
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      "association" mappings simplified to take advantage of
+      automatic "row switch" feature
+
+    .. change::
+        :tags: orm
+        :tickets: 212
+
+      "custom list classes" is now implemented via the "collection_class"
+      keyword argument to relation().  the old way still works but is
+      deprecated
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "viewonly" flag to relation(), allows construction of
+      relations that have no effect on the flush() process.
+
+    .. change::
+        :tags: orm
+        :tickets: 292
+
+      added "lockmode" argument to base Query select/get functions,
+      including "with_lockmode" function to get a Query copy that has
+      a default locking mode.  Will translate "read"/"update"
+      arguments into a for_update argument on the select side.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      implemented "version check" logic in Query/Mapper, used
+      when version_id_col is in effect and query.with_lockmode()
+      is used to get() an instance thats already loaded
+
+    .. change::
+        :tags: orm
+        :tickets: 208
+
+      post_update behavior improved; does a better job at not
+      updating too many rows, updates only required columns
+
+    .. change::
+        :tags: orm
+        :tickets: 308
+
+      adjustments to eager loading so that its "eager chain" is
+      kept separate from the normal mapper setup, thereby
+      preventing conflicts with lazy loader operation, fixes
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fix to deferred group loading
+
+    .. change::
+        :tags: orm
+        :tickets: 346
+
+      session.flush() wont close a connection it opened
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "batch=True" flag to mapper; if False, save_obj
+      will fully save one object at a time including calls
+      to before_XXXX and after_XXXX
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "column_prefix=None" argument to mapper; prepends the
+      given string (typically '_') to column-based attributes automatically
+      set up from the mapper's Table
+
+    .. change::
+        :tags: orm
+        :tickets: 315
+
+      specifying joins in the from_obj argument of query.select() will
+      replace the main table of the query, if the table is somewhere within
+      the given from_obj.  this makes it possible to produce custom joins and
+      outerjoins in queries without the main table getting added twice.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      eagerloading is adjusted to more thoughtfully attach its LEFT OUTER JOINs
+      to the given query, looking for custom "FROM" clauses that may have
+      already been set up.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added join_to and outerjoin_to transformative methods to SelectResults,
+      to build up join/outerjoin conditions based on property names. also
+      added select_from to explicitly set from_obj parameter.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      removed "is_primary" flag from mapper.
diff --git a/doc/build/changelog/changelog_04.rst b/doc/build/changelog/changelog_04.rst
new file mode 100644 (file)
index 0000000..37b424d
--- /dev/null
@@ -0,0 +1,4198 @@
+
+==============
+0.4 Changelog
+==============
+
+                
+.. changelog::
+    :version: 0.4.8
+    :released: Sun Oct 12 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 1039
+
+      Fixed bug regarding inherit_condition passed
+      with "A=B" versus "B=A" leading to errors
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Changes made to new, dirty and deleted
+      collections in
+      SessionExtension.before_flush() will take
+      effect for that flush.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added label() method to InstrumentedAttribute
+      to establish forwards compatibility with 0.5.
+
+    .. change::
+        :tags: sql
+        :tickets: 1074
+
+      column.in_(someselect) can now be used as
+      a columns-clause expression without the subquery
+      bleeding into the FROM clause
+
+    .. change::
+        :tags: mysql
+        :tickets: 1146
+
+      Added MSMediumInteger type.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 968
+
+      Supplied a custom strftime() function which
+      handles dates before 1900.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      String's (and Unicode's, UnicodeText's, etc.)
+      convert_unicode logic disabled in the sqlite dialect,
+      to adjust for pysqlite 2.5.0's new requirement that
+      only Python unicode objects are accepted;
+      http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
+
+    .. change::
+        :tags: oracle
+        :tickets: 1155
+
+      has_sequence() now takes schema name into account
+
+    .. change::
+        :tags: oracle
+        :tickets: 1121
+
+      added BFILE to the list of reflected types
+
+.. changelog::
+    :version: 0.4.7p1
+    :released: Thu Jul 31 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added "add()" and "add_all()" to scoped_session
+      methods.  Workaround for 0.4.7:
+      
+        from sqlalchemy.orm.scoping import ScopedSession,\
+        instrument
+        setattr(
+            ScopedSession, "add", instrument("add"))
+        setattr(
+            ScopedSession, "add_all", instrument("add_all"))
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed non-2.3 compatible usage of set() and generator
+      expression within relation().
+
+.. changelog::
+    :version: 0.4.7
+    :released: Sat Jul 26 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 1058
+
+      The contains() operator when used with many-to-many
+      will alias() the secondary (association) table so
+      that multiple contains() calls will not conflict
+      with each other
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug preventing merge() from functioning in
+      conjunction with a comparable_property()
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the enable_typechecks=False setting on relation()
+      now only allows subtypes with inheriting mappers.
+      Totally unrelated types, or subtypes not set up with
+      mapper inheritance against the target mapper are
+      still not allowed.
+
+    .. change::
+        :tags: orm
+        :tickets: 976
+
+      Added is_active flag to Sessions to detect when
+      a transaction is in progress.  This
+      flag is always True with a "transactional"
+      (in 0.5 a non-"autocommit") Session.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug when calling select([literal('foo')])
+      or select([bindparam('foo')]).
+
+    .. change::
+        :tags: schema
+        :tickets: 571
+
+      create_all(), drop_all(), create(), drop() all raise
+      an error if the table name or schema name contains
+      more characters than that dialect's configured
+      character limit.  Some DB's can handle too-long
+      table names during usage, and SQLA can handle this
+      as well. But various reflection/
+      checkfirst-during-create scenarios fail since we are
+      looking for the name within the DB's catalog tables.
+
+    .. change::
+        :tags: schema
+        :tickets: 571, 820
+
+      The index name generated when you say "index=True"
+      on a Column is truncated to the length appropriate
+      for the dialect. Additionally, an Index with a too-
+      long name cannot be explicitly dropped with
+      Index.drop(), similar to.
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      Repaired server_side_cursors to properly detect
+      text() clauses.
+
+    .. change::
+        :tags: postgres
+        :tickets: 1092
+
+      Added PGCidr type.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Added 'CALL' to the list of SQL keywords which return
+      result rows.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Oracle get_default_schema_name() "normalizes" the name
+      before returning, meaning it returns a lower-case name
+      when the identifier is detected as case insensitive.
+
+    .. change::
+        :tags: oracle
+        :tickets: 709
+
+      creating/dropping tables takes schema name into account
+      when searching for the existing table, so that tables
+      in other owner namespaces with the same name do not
+      conflict
+
+    .. change::
+        :tags: oracle
+        :tickets: 1062
+
+      Cursors now have "arraysize" set to 50 by default on
+      them, the value of which is configurable using the
+      "arraysize" argument to create_engine() with the
+      Oracle dialect.  This to account for cx_oracle's default
+      setting of "1", which has the effect of many round trips
+      being sent to Oracle.  This actually works well in
+      conjunction with BLOB/CLOB-bound cursors, of which
+      there are any number available but only for the life of
+      that row request (so BufferedColumnRow is still needed,
+      but less so).
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      sqlite
+          - add SLFloat type, which matches the SQLite REAL
+            type affinity.  Previously, only SLNumeric was provided
+            which fulfills NUMERIC affinity, but that's not the
+            same as REAL.
+
+.. changelog::
+    :version: 0.4.6
+    :released: Sat May 10 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fix to the recent relation() refactoring which fixes
+      exotic viewonly relations which join between local and
+      remote table multiple times, with a common column shared
+      between the joins.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Also re-established viewonly relation() configurations
+      that join across multiple tables.
+
+    .. change::
+        :tags: orm
+        :tickets: 610
+
+      Added experimental relation() flag to help with
+      primaryjoins across functions, etc.,
+      _local_remote_pairs=[tuples].  This complements a complex
+      primaryjoin condition allowing you to provide the
+      individual column pairs which comprise the relation's
+      local and remote sides.  Also improved lazy load SQL
+      generation to handle placing bind params inside of
+      functions and other expressions.  (partial progress
+      towards)
+
+    .. change::
+        :tags: orm
+        :tickets: 1036
+
+      repaired single table inheritance such that you
+      can single-table inherit from a joined-table inherting
+      mapper without issue.
+
+    .. change::
+        :tags: orm
+        :tickets: 1027
+
+      Fixed "concatenate tuple" bug which could occur with
+      Query.order_by() if clause adaption had taken place.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Removed ancient assertion that mapped selectables require
+      "alias names" - the mapper creates its own alias now if
+      none is present.  Though in this case you need to use the
+      class, not the mapped selectable, as the source of column
+      attributes - so a warning is still issued.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixes to the "exists" function involving inheritance (any(),
+      has(), ~contains()); the full target join will be rendered
+      into the EXISTS clause for relations that link to subclasses.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      restored usage of append_result() extension method for primary
+      query rows, when the extension is present and only a single-
+      entity result is being returned.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Also re-established viewonly relation() configurations that
+      join across multiple tables.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      removed ancient assertion that mapped selectables require
+      "alias names" - the mapper creates its own alias now if
+      none is present.  Though in this case you need to use
+      the class, not the mapped selectable, as the source of
+      column attributes - so a warning is still issued.
+
+    .. change::
+        :tags: orm
+        :tickets: 1015
+
+      refined mapper._save_obj() which was unnecessarily calling
+      __ne__() on scalar values during flush
+
+    .. change::
+        :tags: orm
+        :tickets: 1019
+
+      added a feature to eager loading whereby subqueries set
+      as column_property() with explicit label names (which is not
+      necessary, btw) will have the label anonymized when
+      the instance is part of the eager join, to prevent
+      conflicts with a subquery or column of the same name
+      on the parent object.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      set-based collections |=, -=, ^= and &= are stricter about
+      their operands and only operate on sets, frozensets or
+      subclasses of the collection type. Previously, they would
+      accept any duck-typed set.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added an example dynamic_dict/dynamic_dict.py, illustrating
+      a simple way to place dictionary behavior on top of
+      a dynamic_loader.
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      Joined table inheritance mappers use a slightly relaxed
+      function to create the "inherit condition" to the parent
+      table, so that other foreign keys to not-yet-declared
+      Table objects don't trigger an error.
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      fixed reentrant mapper compile hang when
+      a declared attribute is used within ForeignKey,
+      ie. ForeignKey(MyOtherClass.someattribute)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added COLLATE support via the .collate(<collation>)
+      expression operator and collate(<expr>, <collation>) sql
+      function.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug with union() when applied to non-Table connected
+      select statements
+
+    .. change::
+        :tags: sql
+        :tickets: 1014
+
+      improved behavior of text() expressions when used as
+      FROM clauses, such as select().select_from(text("sometext"))
+
+    .. change::
+        :tags: sql
+        :tickets: 1021
+
+      Column.copy() respects the value of "autoincrement",
+      fixes usage with Migrate
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Pool listeners can now be provided as a dictionary of
+      callables or a (possibly partial) duck-type of
+      PoolListener, your choice.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      added "rollback_returned" option to Pool which will
+      disable the rollback() issued when connections are
+      returned.  This flag is only safe to use with a database
+      which does not support transactions (i.e. MySQL/MyISAM).
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      set-based association proxies |=, -=, ^= and &= are
+      stricter about their operands and only operate on sets,
+      frozensets or other association proxies. Previously, they
+      would accept any duck-typed set.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1005
+
+      Added "odbc_autotranslate" parameter to engine / dburi
+      parameters. Any given string will be passed through to the
+      ODBC connection string as:
+      
+            "AutoTranslate=%s" % odbc_autotranslate
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Added "odbc_options" parameter to engine / dburi
+      parameters. The given string is simply appended to the
+      SQLAlchemy-generated odbc connection string.
+      
+      This should obviate the need of adding a myriad of ODBC
+      options in the future.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      Handle the "SUBSTRING(:string FROM :start FOR :length)"
+      builtin.
+
+.. changelog::
+    :version: 0.4.5
+    :released: Fri Apr 04 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      A small change in behavior to session.merge() - existing
+      objects are checked for based on primary key attributes, not
+      necessarily _instance_key.  So the widely requested
+      capability, that:
+      
+            x = MyObject(id=1)
+            x = sess.merge(x)
+      
+      will in fact load MyObject with id #1 from the database if
+      present, is now available.  merge() still copies the state
+      of the given object to the persistent one, so an example
+      like the above would typically have copied "None" from all
+      attributes of "x" onto the persistent copy.  These can be
+      reverted using session.expire(x).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Also fixed behavior in merge() whereby collection elements
+      present on the destination but not the merged collection
+      were not being removed from the destination.
+
+    .. change::
+        :tags: orm
+        :tickets: 995
+
+      Added a more aggressive check for "uncompiled mappers",
+      helps particularly with declarative layer
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The methodology behind "primaryjoin"/"secondaryjoin" has
+      been refactored.  Behavior should be slightly more
+      intelligent, primarily in terms of error messages which
+      have been pared down to be more readable.  In a slight
+      number of scenarios it can better resolve the correct
+      foreign key than before.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added comparable_property(), adds query Comparator
+      behavior to regular, unmanaged Python properties
+
+    .. change::
+        :tags: orm, Company.employees.of_type(Engineer), 'machines'
+        :tickets: 
+
+      the functionality of query.with_polymorphic() has
+      been added to mapper() as a configuration option.
+      
+      It's set via several forms:
+            with_polymorphic='*'
+            with_polymorphic=[mappers]
+            with_polymorphic=('*', selectable)
+            with_polymorphic=([mappers], selectable)
+      
+      This controls the default polymorphic loading strategy
+      for inherited mappers. When a selectable is not given,
+      outer joins are created for all joined-table inheriting
+      mappers requested. Note that the auto-create of joins
+      is not compatible with concrete table inheritance.
+      
+      The existing select_table flag on mapper() is now
+      deprecated and is synonymous with
+      with_polymorphic('*', select_table).  Note that the
+      underlying "guts" of select_table have been
+      completely removed and replaced with the newer,
+      more flexible approach.
+      
+      The new approach also automatically allows eager loads
+      to work for subclasses, if they are present, for
+      example
+        sess.query(Company).options(
+         eagerload_all(
+         
+        ))
+      to load Company objects, their employees, and the
+      'machines' collection of employees who happen to be
+      Engineers. A "with_polymorphic" Query option should be
+      introduced soon as well which would allow per-Query
+      control of with_polymorphic() on relations.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added two "experimental" features to Query,
+      "experimental" in that their specific name/behavior
+      is not carved in stone just yet:  _values() and
+      _from_self().  We'd like feedback on these.
+      
+      - _values(*columns) is given a list of column
+        expressions, and returns a new Query that only
+        returns those columns. When evaluated, the return
+        value is a list of tuples just like when using
+        add_column() or add_entity(), the only difference is
+        that "entity zero", i.e. the mapped class, is not
+        included in the results. This means it finally makes
+        sense to use group_by() and having() on Query, which
+        have been sitting around uselessly until now.
+      
+        A future change to this method may include that its
+        ability to join, filter and allow other options not
+        related to a "resultset" are removed, so the feedback
+        we're looking for is how people want to use
+        _values()...i.e. at the very end, or do people prefer
+        to continue generating after it's called.
+      
+      - _from_self() compiles the SELECT statement for the
+        Query (minus any eager loaders), and returns a new
+        Query that selects from that SELECT. So basically you
+        can query from a Query without needing to extract the
+        SELECT statement manually. This gives meaning to
+        operations like query[3:5]._from_self().filter(some
+        criterion). There's not much controversial here
+        except that you can quickly create highly nested
+        queries that are less efficient, and we want feedback
+        on the naming choice.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.order_by() and query.group_by() will accept
+      multiple arguments using *args (like select()
+      already does).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added some convenience descriptors to Query:
+      query.statement returns the full SELECT construct,
+      query.whereclause returns just the WHERE part of the
+      SELECT construct.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed/covered case when using a False/0 value as a
+      polymorphic discriminator.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug which was preventing synonym() attributes from
+      being used with inheritance
+
+    .. change::
+        :tags: orm
+        :tickets: 996
+
+      Fixed SQL function truncation of trailing underscores
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      When attributes are expired on a pending instance, an
+      error will not be raised when the "refresh" action is
+      triggered and no result is found.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session.execute can now find binds from metadata
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Adjusted the definition of "self-referential" to be any
+      two mappers with a common parent (this affects whether or
+      not aliased=True is required when joining with Query).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Made some fixes to the "from_joinpoint" argument to
+      query.join() so that if the previous join was aliased and
+      this one isn't, the join still happens successfully.
+
+    .. change::
+        :tags: orm
+        :tickets: 895
+
+      Assorted "cascade deletes" fixes:
+        - Fixed "cascade delete" operation of dynamic relations,
+          which had only been implemented for foreign-key
+          nulling behavior in 0.4.2 and not actual cascading
+          deletes
+      
+        - Delete cascade without delete-orphan cascade on a
+          many-to-one will not delete orphans which were
+          disconnected from the parent before session.delete()
+          is called on the parent (one-to-many already had
+          this).
+      
+        - Delete cascade with delete-orphan will delete orphans
+          whether or not it remains attached to its also-deleted
+          parent.
+      
+        - delete-orphan casacde is properly detected on relations
+          that are present on superclasses when using inheritance.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed order_by calculation in Query to properly alias
+      mapper-config'ed order_by when using select_from()
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Refactored the diffing logic that kicks in when replacing
+      one collection with another into collections.bulk_replace,
+      useful to anyone building multi-level collections.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Cascade traversal algorithm converted from recursive to
+      iterative to support deep object graphs.
+
+    .. change::
+        :tags: sql
+        :tickets: 999
+
+      schema-qualified tables now will place the schemaname
+      ahead of the tablename in all column expressions as well
+      as when generating column labels.  This prevents cross-
+      schema name collisions in all cases
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      can now allow selects which correlate all FROM clauses
+      and have no FROM themselves.  These are typically
+      used in a scalar context, i.e. SELECT x, (SELECT x WHERE y)
+      FROM table.  Requires explicit correlate() call.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      'name' is no longer a required constructor argument for
+      Column().  It (and .key) may now be deferred until the
+      column is added to a Table.
+
+    .. change::
+        :tags: sql
+        :tickets: 791, 993
+
+      like(), ilike(), contains(), startswith(), endswith() take
+      an optional keyword argument "escape=<somestring>", which
+      is set as the escape character using the syntax "x LIKE y
+      ESCAPE '<somestring>'".
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      random() is now a generic sql function and will compile to
+      the database's random implementation, if any.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      update().values() and insert().values() take keyword
+      arguments.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed an issue in select() regarding its generation of
+      FROM clauses, in rare circumstances two clauses could be
+      produced when one was intended to cancel out the other.
+      Some ORM queries with lots of eager loads might have seen
+      this symptom.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The case() function now also takes a dictionary as its
+      whens parameter.  It also interprets the "THEN"
+      expressions as values by default, meaning case([(x==y,
+      "foo")]) will interpret "foo" as a bound value, not a SQL
+      expression.  use text(expr) for literal SQL expressions in
+      this case.  For the criterion itself, these may be literal
+      strings only if the "value" keyword is present, otherwise
+      SA will force explicit usage of either text() or
+      literal().
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      The "owner" keyword on Table is now deprecated, and is
+      exactly synonymous with the "schema" keyword.  Tables can
+      now be reflected with alternate "owner" attributes,
+      explicitly stated on the Table object or not using
+      "schema".
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      All of the "magic" searching for synonyms, DBLINKs etc.
+      during table reflection are disabled by default unless you
+      specify "oracle_resolve_synonyms=True" on the Table
+      object.  Resolving synonyms necessarily leads to some
+      messy guessing which we'd rather leave off by default.
+      When the flag is set, tables and related tables will be
+      resolved against synonyms in all cases, meaning if a
+      synonym exists for a particular table, reflection will use
+      it when reflecting related tables.  This is stickier
+      behavior than before which is why it's off by default.
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      The "synonym" function is now directly usable with
+      "declarative".  Pass in the decorated property using the
+      "descriptor" keyword argument, e.g.: somekey =
+      synonym('_somekey', descriptor=property(g, s))
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      The "deferred" function is usable with "declarative".
+      Simplest usage is to declare deferred and Column together,
+      e.g.: data = deferred(Column(Text))
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      Declarative also gained @synonym_for(...) and
+      @comparable_using(...), front-ends for synonym and
+      comparable_property.
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 995
+
+      Improvements to mapper compilation when using declarative;
+      already-compiled mappers will still trigger compiles of
+      other uncompiled mappers when used
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      Declarative will complete setup for Columns lacking names,
+      allows a more DRY syntax.
+      
+        class Foo(Base):
+            __tablename__ = 'foos'
+            id = Column(Integer, primary_key=True)
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      inheritance in declarative can be disabled when sending
+      "inherits=None" to __mapper_args__.
+
+    .. change::
+        :tags: declarative, extension
+        :tickets: 
+
+      declarative_base() takes optional kwarg "mapper", which
+      is any callable/class/method that produces a mapper,
+      such as declarative_base(mapper=scopedsession.mapper).
+      This property can also be set on individual declarative
+      classes using the "__mapper_cls__" property.
+
+    .. change::
+        :tags: postgres
+        :tickets: 1001
+
+      Got PG server side cursors back into shape, added fixed
+      unit tests as part of the default test suite.  Added
+      better uniqueness to the cursor ID
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      The "owner" keyword on Table is now deprecated, and is
+      exactly synonymous with the "schema" keyword.  Tables can
+      now be reflected with alternate "owner" attributes,
+      explicitly stated on the Table object or not using
+      "schema".
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      All of the "magic" searching for synonyms, DBLINKs etc.
+      during table reflection are disabled by default unless you
+      specify "oracle_resolve_synonyms=True" on the Table
+      object.  Resolving synonyms necessarily leads to some
+      messy guessing which we'd rather leave off by default.
+      When the flag is set, tables and related tables will be
+      resolved against synonyms in all cases, meaning if a
+      synonym exists for a particular table, reflection will use
+      it when reflecting related tables.  This is stickier
+      behavior than before which is why it's off by default.
+
+    .. change::
+        :tags: mssql
+        :tickets: 979
+
+      Reflected tables will now automatically load other tables
+      which are referenced by Foreign keys in the auto-loaded
+      table,.
+
+    .. change::
+        :tags: mssql
+        :tickets: 916
+
+      Added executemany check to skip identity fetch,.
+
+    .. change::
+        :tags: mssql
+        :tickets: 884
+
+      Added stubs for small date type.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Added a new 'driver' keyword parameter for the pyodbc dialect.
+      Will substitute into the ODBC connection string if given,
+      defaults to 'SQL Server'.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Added a new 'max_identifier_length' keyword parameter for
+      the pyodbc dialect.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Improvements to pyodbc + Unix. If you couldn't get that
+      combination to work before, please try again.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      The connection.info keys the dialect uses to cache server
+      settings have changed and are now namespaced.
+
+.. changelog::
+    :version: 0.4.4
+    :released: Wed Mar 12 2008
+
+    .. change::
+        :tags: sql
+        :tickets: 975
+
+      Can again create aliases of selects against textual FROM
+      clauses.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The value of a bindparam() can be a callable, in which
+      case it's evaluated at statement execution time to get the
+      value.
+
+    .. change::
+        :tags: sql
+        :tickets: 978
+
+      Added exception wrapping/reconnect support to result set
+      fetching.  Reconnect works for those databases that raise
+      a catchable data error during results (i.e. doesn't work
+      on MySQL)
+
+    .. change::
+        :tags: sql
+        :tickets: 936
+
+      Implemented two-phase API for "threadlocal" engine, via
+      engine.begin_twophase(), engine.prepare()
+
+    .. change::
+        :tags: sql
+        :tickets: 986
+
+      Fixed bug which was preventing UNIONS from being
+      cloneable.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added "bind" keyword argument to insert(), update(),
+      delete() and DDL(). The .bind property is now assignable
+      on those statements as well as on select().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Insert statements can now be compiled with extra "prefix"
+      words between INSERT and INTO, for vendor extensions like
+      MySQL's INSERT IGNORE INTO table.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      any(), has(), contains(), ~contains(), attribute level ==
+      and != now work properly with self-referential relations -
+      the clause inside the EXISTS is aliased on the "remote"
+      side to distinguish it from the parent table.  This
+      applies to single table self-referential as well as
+      inheritance-based self-referential.
+
+    .. change::
+        :tags: orm
+        :tickets: 985
+
+      Repaired behavior of == and != operators at the relation()
+      level when compared against NULL for one-to-one relations
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug whereby session.expire() attributes were not
+      loading on an polymorphically-mapped instance mapped by a
+      select_table mapper.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added query.with_polymorphic() - specifies a list of
+      classes which descend from the base class, which will be
+      added to the FROM clause of the query.  Allows subclasses
+      to be used within filter() criterion as well as eagerly
+      loads the attributes of those subclasses.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Your cries have been heard: removing a pending item from
+      an attribute or collection with delete-orphan expunges the
+      item from the session; no FlushError is raised.  Note that
+      if you session.save()'ed the pending item explicitly, the
+      attribute/collection removal still knocks it out.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      session.refresh() and session.expire() raise an error when
+      called on instances which are not persistent within the
+      session
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed potential generative bug when the same Query was
+      used to generate multiple Query objects using join().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug which was introduced in 0.4.3, whereby loading
+      an already-persistent instance mapped with joined table
+      inheritance would trigger a useless "secondary" load from
+      its joined table, when using the default "select"
+      polymorphic_fetch.  This was due to attributes being
+      marked as expired during its first load and not getting
+      unmarked from the previous "secondary" load.  Attributes
+      are now unexpired based on presence in __dict__ after any
+      load or commit operation succeeds.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Deprecated Query methods apply_sum(), apply_max(),
+      apply_min(), apply_avg().  Better methodologies are
+      coming....
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      relation() can accept a callable for its first argument,
+      which returns the class to be related.  This is in place
+      to assist declarative packages to define relations without
+      classes yet being in place.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added a new "higher level" operator called "of_type()":
+      used in join() as well as with any() and has(), qualifies
+      the subclass which will be used in filter criterion, e.g.:
+      
+        query.filter(Company.employees.of_type(Engineer).
+          any(Engineer.name=='foo'))
+      
+        or
+      
+        query.join(Company.employees.of_type(Engineer)).
+          filter(Engineer.name=='foo')
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Preventive code against a potential lost-reference bug in
+      flush().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Expressions used in filter(), filter_by() and others, when
+      they make usage of a clause generated from a relation
+      using the identity of a child object (e.g.,
+      filter(Parent.child==<somechild>)), evaluate the actual
+      primary key value of <somechild> at execution time so that
+      the autoflush step of the Query can complete, thereby
+      populating the PK value of <somechild> in the case that
+      <somechild> was pending.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      setting the relation()-level order by to a column in the
+      many-to-many "secondary" table will now work with eager
+      loading, previously the "order by" wasn't aliased against
+      the secondary table's alias.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Synonyms riding on top of existing descriptors are now
+      full proxies to those descriptors.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Invalid SQLite connection URLs now raise an error.
+
+    .. change::
+        :tags: dialects
+        :tickets: 981
+
+      postgres TIMESTAMP renders correctly
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      postgres PGArray is a "mutable" type by default; when used
+      with the ORM, mutable-style equality/ copy-on-write
+      techniques are used to test for changes.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      a new super-small "declarative" extension has been added,
+      which allows Table and mapper() configuration to take
+      place inline underneath a class declaration.  This
+      extension differs from ActiveMapper and Elixir in that it
+      does not redefine any SQLAlchemy semantics at all; literal
+      Column, Table and relation() constructs are used to define
+      the class behavior and table definition.
+
+.. changelog::
+    :version: 0.4.3
+    :released: Thu Feb 14 2008
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added "schema.DDL", an executable free-form DDL statement.
+      DDLs can be executed in isolation or attached to Table or
+      MetaData instances and executed automatically when those
+      objects are created and/or dropped.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Table columns and constraints can be overridden on a an
+      existing table (such as a table that was already reflected)
+      using the 'useexisting=True' flag, which now takes into
+      account the arguments passed along with it.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added a callable-based DDL events interface, adds hooks
+      before and after Tables and MetaData create and drop.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added generative where(<criterion>) method to delete() and
+      update() constructs which return a new object with criterion
+      joined to existing criterion via AND, just like
+      select().where().
+
+    .. change::
+        :tags: sql
+        :tickets: 727
+
+      Added "ilike()" operator to column operations.  Compiles to
+      ILIKE on postgres, lower(x) LIKE lower(y) on all
+      others.
+
+    .. change::
+        :tags: sql
+        :tickets: 943
+
+      Added "now()" as a generic function; on SQLite, Oracle
+      and MSSQL compiles as "CURRENT_TIMESTAMP"; "now()" on
+      all others.
+
+    .. change::
+        :tags: sql
+        :tickets: 962
+
+      The startswith(), endswith(), and contains() operators now
+      concatenate the wildcard operator with the given operand in
+      SQL, i.e. "'%' || <bindparam>" in all cases, accept
+      text('something') operands properly
+
+    .. change::
+        :tags: sql
+        :tickets: 962
+
+      cast() accepts text('something') and other non-literal
+      operands properly
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixed bug in result proxy where anonymously generated
+      column labels would not be accessible using their straight
+      string name
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Deferrable constraints can now be defined.
+
+    .. change::
+        :tags: sql
+        :tickets: 915
+
+      Added "autocommit=True" keyword argument to select() and
+      text(), as well as generative autocommit() method on
+      select(); for statements which modify the database through
+      some user-defined means other than the usual INSERT/UPDATE/
+      DELETE etc.  This flag will enable "autocommit" behavior
+      during execution if no transaction is in progress.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The '.c.' attribute on a selectable now gets an entry for
+      every column expression in its columns clause.  Previously,
+      "unnamed" columns like functions and CASE statements weren't
+      getting put there.  Now they will, using their full string
+      representation if no 'name' is available.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      a CompositeSelect, i.e. any union(), union_all(),
+      intersect(), etc. now asserts that each selectable contains
+      the same number of columns.  This conforms to the
+      corresponding SQL requirement.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The anonymous 'label' generated for otherwise unlabeled
+      functions and expressions now propagates outwards at compile
+      time for expressions like select([select([func.foo()])]).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Building on the above ideas, CompositeSelects now build up
+      their ".c." collection based on the names present in the
+      first selectable only; corresponding_column() now works
+      fully for all embedded selectables.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Oracle and others properly encode SQL used for defaults like
+      sequences, etc., even if no unicode idents are used since
+      identifier preparer may return a cached unicode identifier.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Column and clause comparisons to datetime objects on the
+      left hand side of the expression now work (d < table.c.col).
+      (datetimes on the RHS have always worked, the LHS exception
+      is a quirk of the datetime implementation.)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Every Session.begin() must now be accompanied by a
+      corresponding commit() or rollback() unless the session is
+      closed with Session.close().  This also includes the begin()
+      which is implicit to a session created with
+      transactional=True.  The biggest change introduced here is
+      that when a Session created with transactional=True raises
+      an exception during flush(), you must call
+      Session.rollback() or Session.close() in order for that
+      Session to continue after an exception.
+
+    .. change::
+        :tags: orm
+        :tickets: 961
+
+      Fixed merge() collection-doubling bug when merging transient
+      entities with backref'ed collections.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      merge(dont_load=True) does not accept transient entities,
+      this is in continuation with the fact that
+      merge(dont_load=True) does not accept any "dirty" objects
+      either.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added standalone "query" class attribute generated by a
+      scoped_session.  This provides MyClass.query without using
+      Session.mapper.  Use via:
+      
+        MyClass.query = Session.query_property()
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The proper error message is raised when trying to access
+      expired instance attributes with no session present
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      dynamic_loader() / lazy="dynamic" now accepts and uses
+      the order_by parameter in the same way in which it works
+      with relation().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added expire_all() method to Session.  Calls expire() for
+      all persistent instances.  This is handy in conjunction
+      with...
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Instances which have been partially or fully expired will
+      have their expired attributes populated during a regular
+      Query operation which affects those objects, preventing a
+      needless second SQL statement for each instance.
+
+    .. change::
+        :tags: orm
+        :tickets: 938
+
+      Dynamic relations, when referenced, create a strong
+      reference to the parent object so that the query still has a
+      parent to call against even if the parent is only created
+      (and otherwise dereferenced) within the scope of a single
+      expression.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added a mapper() flag "eager_defaults". When set to True,
+      defaults that are generated during an INSERT or UPDATE
+      operation are post-fetched immediately, instead of being
+      deferred until later.  This mimics the old 0.3 behavior.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.join() can now accept class-mapped attributes as
+      arguments. These can be used in place or in any combination
+      with strings.  In particular this allows construction of
+      joins to subclasses on a polymorphic relation, i.e.:
+      
+        query(Company).join(['employees', Engineer.name])
+
+    .. change::
+        :tags: orm, ('employees', people.join(engineer)), Engineer.name
+        :tickets: 
+
+      query.join() can also accept tuples of attribute name/some
+      selectable as arguments.  This allows construction of joins
+      *from* subclasses of a polymorphic relation, i.e.:
+      
+        query(Company).\
+        join(
+         
+        )
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      General improvements to the behavior of join() in
+      conjunction with polymorphic mappers, i.e. joining from/to
+      polymorphic mappers and properly applying aliases.
+
+    .. change::
+        :tags: orm
+        :tickets: 933
+
+      Fixed/improved behavior when a mapper determines the natural
+      "primary key" of a mapped join, it will more effectively
+      reduce columns which are equivalent via foreign key
+      relation.  This affects how many arguments need to be sent
+      to query.get(), among other things.
+
+    .. change::
+        :tags: orm
+        :tickets: 946
+
+      The lazy loader can now handle a join condition where the
+      "bound" column (i.e. the one that gets the parent id sent as
+      a bind parameter) appears more than once in the join
+      condition.  Specifically this allows the common task of a
+      relation() which contains a parent-correlated subquery, such
+      as "select only the most recent child item".
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in polymorphic inheritance where an incorrect
+      exception is raised when base polymorphic_on column does not
+      correspond to any columns within the local selectable of an
+      inheriting mapper more than one level deep
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in polymorphic inheritance which made it difficult
+      to set a working "order_by" on a polymorphic mapper.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed a rather expensive call in Query that was slowing down
+      polymorphic queries.
+
+    .. change::
+        :tags: orm
+        :tickets: 954
+
+      "Passive defaults" and other "inline" defaults can now be
+      loaded during a flush() call if needed; in particular, this
+      allows constructing relations() where a foreign key column
+      references a server-side-generated, non-primary-key
+      column.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Additional Session transaction fixes/changes:
+        - Fixed bug with session transaction management: parent
+          transactions weren't started on the connection when
+          adding a connection to a nested transaction.
+      
+        - session.transaction now always refers to the innermost
+          active transaction, even when commit/rollback are called
+          directly on the session transaction object.
+      
+        - Two-phase transactions can now be prepared.
+      
+        - When preparing a two-phase transaction fails on one
+          connection, all the connections are rolled back.
+      
+        - session.close() didn't close all transactions when
+          nested transactions were used.
+      
+        - rollback() previously erroneously set the current
+          transaction directly to the parent of the transaction
+          that could be rolled back to. Now it rolls back the next
+          transaction up that can handle it, but sets the current
+          transaction to it's parent and inactivates the
+          transactions in between. Inactive transactions can only
+          be rolled back or closed, any other call results in an
+          error.
+      
+        - autoflush for commit() wasn't flushing for simple
+          subtransactions.
+      
+        - unitofwork flush didn't close the failed transaction
+          when the session was not in a transaction and commiting
+          the transaction failed.
+
+    .. change::
+        :tags: orm
+        :tickets: 964, 940
+
+      Miscellaneous tickets:
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      Fixed a variety of hidden and some not-so-hidden
+      compatibility issues for Python 2.3, thanks to new support
+      for running the full test suite on 2.3.
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      Warnings are now issued as type exceptions.SAWarning.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Better support for schemas in SQLite (linked in by ATTACH
+      DATABASE ... AS name).  In some cases in the past, schema
+      names were ommitted from generated SQL for SQLite.  This is
+      no longer the case.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      table_names on SQLite now picks up temporary tables as well.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Auto-detect an unspecified MySQL ANSI_QUOTES mode during
+      reflection operations, support for changing the mode
+      midstream.  Manual mode setting is still required if no
+      reflection is used.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Fixed reflection of TIME columns on SQLite.
+
+    .. change::
+        :tags: dialects
+        :tickets: 580
+
+      Finally added PGMacAddr type to postgres
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Reflect the sequence associated to a PK field (typically
+      with a BEFORE INSERT trigger) under Firebird
+
+    .. change::
+        :tags: dialects
+        :tickets: 941
+
+      Oracle assembles the correct columns in the result set
+      column mapping when generating a LIMIT/OFFSET subquery,
+      allows columns to map properly to result sets even if
+      long-name truncation kicks in
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      MSSQL now includes EXEC in the _is_select regexp, which
+      should allow row-returning stored procedures to be used.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      MSSQL now includes an experimental implementation of
+      LIMIT/OFFSET using the ANSI SQL row_number() function, so it
+      requires MSSQL-2005 or higher. To enable the feature, add
+      "has_window_funcs" to the keyword arguments for connect, or
+      add "?has_window_funcs=1" to your dburi query arguments.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      Changed ext.activemapper to use a non-transactional session
+      for the objectstore.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      Fixed output order of "['a'] + obj.proxied" binary operation
+      on association-proxied lists.
+
+.. changelog::
+    :version: 0.4.2p3
+    :released: Wed Jan 09 2008
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      sub version numbering scheme changed to suite
+      setuptools version number rules; easy_install -u
+      should now get this version over 0.4.2.
+
+    .. change::
+        :tags: sql
+        :tickets: 912
+
+      Text type is properly exported now and does not
+      raise a warning on DDL create; String types with no
+      length only raise warnings during CREATE TABLE
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      new UnicodeText type is added, to specify an
+      encoded, unlengthed Text type
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixed bug in union() so that select() statements
+      which don't derive from FromClause objects can be
+      unioned
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug with session.dirty when using "mutable
+      scalars" (such as PickleTypes)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added a more descriptive error message when flushing
+      on a relation() that has non-locally-mapped columns
+      in its primary or secondary join condition
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Fixed reflection of mysql empty string column
+      defaults.
+
+    .. change::
+        :tags: sql
+        :tickets: 912
+
+      changed name of TEXT to Text since its a "generic"
+      type; TEXT name is deprecated until 0.5. The
+      "upgrading" behavior of String to Text when no
+      length is present is also deprecated until 0.5; will
+      issue a warning when used for CREATE TABLE
+      statements (String with no length for SQL expression
+      purposes is still fine)
+
+    .. change::
+        :tags: sql
+        :tickets: 924
+
+      generative select.order_by(None) / group_by(None)
+      was not managing to reset order by/group by
+      criterion, fixed
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      suppressing *all* errors in
+      InstanceState.__cleanup() now.
+
+    .. change::
+        :tags: orm
+        :tickets: 922
+
+      fixed an attribute history bug whereby assigning a
+      new collection to a collection-based attribute which
+      already had pending changes would generate incorrect
+      history
+
+    .. change::
+        :tags: orm
+        :tickets: 925
+
+      fixed delete-orphan cascade bug whereby setting the
+      same object twice to a scalar attribute could log it
+      as an orphan
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed cascades on a += assignment to a list-based
+      relation.
+
+    .. change::
+        :tags: orm
+        :tickets: 919
+
+      synonyms can now be created against props that don't
+      exist yet, which are later added via add_property().
+      This commonly includes backrefs. (i.e. you can make
+      synonyms for backrefs without worrying about the
+      order of operations)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug which could occur with polymorphic "union"
+      mapper which falls back to "deferred" loading of
+      inheriting tables
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "columns" collection on a mapper/mapped class
+      (i.e. 'c') is against the mapped table, not the
+      select_table in the case of polymorphic "union"
+      loading (this shouldn't be noticeable).
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      '+', '*', '+=' and '*=' support for association
+      proxied lists.
+
+    .. change::
+        :tags: dialects
+        :tickets: 923
+
+      mssql - narrowed down the test for "date"/"datetime"
+      in MSDate/ MSDateTime subclasses so that incoming
+      "datetime" objects don't get mis-interpreted as
+      "date" objects and vice versa.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed fairly critical bug whereby the same instance could be listed
+      more than once in the unitofwork.new collection; most typically
+      reproduced when using a combination of inheriting mappers and
+      ScopedSession.mapper, as the multiple __init__ calls per instance
+      could save() the object with distinct _state objects
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added very rudimentary yielding iterator behavior to Query.  Call
+      query.yield_per(<number of rows>) and evaluate the Query in an
+      iterative context; every collection of N rows will be packaged up
+      and yielded.  Use this method with extreme caution since it does
+      not attempt to reconcile eagerly loaded collections across
+      result batch boundaries, nor will it behave nicely if the same
+      instance occurs in more than one batch.  This means that an eagerly
+      loaded collection will get cleared out if it's referenced in more than
+      one batch, and in all cases attributes will be overwritten on instances
+      that occur in more than one batch.
+
+    .. change::
+        :tags: orm
+        :tickets: 920
+
+      Fixed in-place set mutation operators for set collections and association
+      proxied sets.
+
+    .. change::
+        :tags: dialects
+        :tickets: 913
+
+      Fixed the missing call to subtype result processor for the PGArray
+      type.
+
+.. changelog::
+    :version: 0.4.2
+    :released: Wed Jan 02 2008
+
+    .. change::
+        :tags: sql
+        :tickets: 615
+
+      generic functions ! we introduce a database of known SQL functions, such
+      as current_timestamp, coalesce, and create explicit function objects
+      representing them. These objects have constrained argument lists, are
+      type aware, and can compile in a dialect-specific fashion. So saying
+      func.char_length("foo", "bar") raises an error (too many args),
+      func.coalesce(datetime.date(2007, 10, 5), datetime.date(2005, 10, 15))
+      knows that its return type is a Date. We only have a few functions
+      represented so far but will continue to add to the system
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      auto-reconnect support improved; a Connection can now automatically
+      reconnect after its underlying connection is invalidated, without
+      needing to connect() again from the engine.  This allows an ORM session
+      bound to a single Connection to not need a reconnect.
+      Open transactions on the Connection must be rolled back after an invalidation
+      of the underlying connection else an error is raised.  Also fixed
+      bug where disconnect detect was not being called for cursor(), rollback(),
+      or commit().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added new flag to String and create_engine(),
+      assert_unicode=(True|False|'warn'|None). Defaults to `False` or `None` on
+      create_engine() and String, `'warn'` on the Unicode type. When `True`,
+      results in all unicode conversion operations raising an exception when a
+      non-unicode bytestring is passed as a bind parameter. 'warn' results
+      in a warning. It is strongly advised that all unicode-aware applications
+      make proper use of Python unicode objects (i.e. u'hello' and not 'hello')
+      so that data round trips accurately.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      generation of "unique" bind parameters has been simplified to use the same
+      "unique identifier" mechanisms as everything else.  This doesn't affect
+      user code, except any code that might have been hardcoded against the generated
+      names.  Generated bind params now have the form "<paramname>_<num>",
+      whereas before only the second bind of the same name would have this form.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      select().as_scalar() will raise an exception if the select does not have
+      exactly one expression in its columns clause.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      bindparam() objects themselves can be used as keys for execute(), i.e.
+      statement.execute({bind1:'foo', bind2:'bar'})
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added new methods to TypeDecorator, process_bind_param() and
+      process_result_value(), which automatically take advantage of the processing
+      of the underlying type.  Ideal for using with Unicode or Pickletype.
+      TypeDecorator should now be the primary way to augment the behavior of any
+      existing type including other TypeDecorator subclasses such as PickleType.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      selectables (and others) will issue a warning when two columns in
+      their exported columns collection conflict based on name.
+
+    .. change::
+        :tags: sql
+        :tickets: 890
+
+      tables with schemas can still be used in sqlite, firebird,
+      schema name just gets dropped
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      changed the various "literal" generation functions to use an anonymous
+      bind parameter.  not much changes here except their labels now look
+      like ":param_1", ":param_2" instead of ":literal"
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      column labels in the form "tablename.columname", i.e. with a dot, are now
+      supported.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      from_obj keyword argument to select() can be a scalar or a list.
+
+    .. change::
+        :tags: orm
+        :tickets: 871
+
+      a major behavioral change to collection-based backrefs: they no
+      longer trigger lazy loads !  "reverse" adds and removes
+      are queued up and are merged with the collection when it is
+      actually read from and loaded; but do not trigger a load beforehand.
+      For users who have noticed this behavior, this should be much more
+      convenient than using dynamic relations in some cases; for those who
+      have not, you might notice your apps using a lot fewer queries than
+      before in some situations.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      mutable primary key support is added. primary key columns can be
+      changed freely, and the identity of the instance will change upon
+      flush. In addition, update cascades of foreign key referents (primary
+      key or not) along relations are supported, either in tandem with the
+      database's ON UPDATE CASCADE (required for DB's like Postgres) or
+      issued directly by the ORM in the form of UPDATE statements, by setting
+      the flag "passive_cascades=False".
+
+    .. change::
+        :tags: orm
+        :tickets: 490
+
+      inheriting mappers now inherit the MapperExtensions of their parent
+      mapper directly, so that all methods for a particular MapperExtension
+      are called for subclasses as well.  As always, any MapperExtension
+      can return either EXT_CONTINUE to continue extension processing
+      or EXT_STOP to stop processing.  The order of mapper resolution is:
+      <extensions declared on the classes mapper> <extensions declared on the
+      classes' parent mapper> <globally declared extensions>.
+      
+      Note that if you instantiate the same extension class separately
+      and then apply it individually for two mappers in the same inheritance
+      chain, the extension will be applied twice to the inheriting class,
+      and each method will be called twice.
+      
+      To apply a mapper extension explicitly to each inheriting class but
+      have each method called only once per operation, use the same
+      instance of the extension for both mappers.
+
+    .. change::
+        :tags: orm
+        :tickets: 907
+
+      MapperExtension.before_update() and after_update() are now called
+      symmetrically; previously, an instance that had no modified column
+      attributes (but had a relation() modification) could be called with
+      before_update() but not after_update()
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      columns which are missing from a Query's select statement
+      now get automatically deferred during load.
+
+    .. change::
+        :tags: orm
+        :tickets: 908
+
+      mapped classes which extend "object" and do not provide an
+      __init__() method will now raise TypeError if non-empty *args
+      or **kwargs are present at instance construction time (and are
+      not consumed by any extensions such as the scoped_session mapper),
+      consistent with the behavior of normal Python classes
+
+    .. change::
+        :tags: orm
+        :tickets: 899
+
+      fixed Query bug when filter_by() compares a relation against None
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      improved support for pickling of mapped entities.  Per-instance
+      lazy/deferred/expired callables are now serializable so that
+      they serialize and deserialize with _state.
+
+    .. change::
+        :tags: orm
+        :tickets: 801
+
+      new synonym() behavior: an attribute will be placed on the mapped
+      class, if one does not exist already, in all cases. if a property
+      already exists on the class, the synonym will decorate the property
+      with the appropriate comparison operators so that it can be used in in
+      column expressions just like any other mapped attribute (i.e. usable in
+      filter(), etc.) the "proxy=True" flag is deprecated and no longer means
+      anything. Additionally, the flag "map_column=True" will automatically
+      generate a ColumnProperty corresponding to the name of the synonym,
+      i.e.: 'somename':synonym('_somename', map_column=True) will map the
+      column named 'somename' to the attribute '_somename'. See the example
+      in the mapper docs.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.select_from() now replaces all existing FROM criterion with
+      the given argument; the previous behavior of constructing a list
+      of FROM clauses was generally not useful as is required
+      filter() calls to create join criterion, and new tables introduced
+      within filter() already add themselves to the FROM clause.  The
+      new behavior allows not just joins from the main table, but select
+      statements as well.  Filter criterion, order bys, eager load
+      clauses will be "aliased" against the given statement.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      this month's refactoring of attribute instrumentation changes
+      the "copy-on-load" behavior we've had since midway through 0.3
+      with "copy-on-modify" in most cases.  This takes a sizable chunk
+      of latency out of load operations and overall does less work
+      as only attributes which are actually modified get their
+      "committed state" copied.  Only "mutable scalar" attributes
+      (i.e. a pickled object or other mutable item), the reason for
+      the copy-on-load change in the first place, retain the old
+      behavior.
+
+    .. change::
+        :tags: attrname, orm
+        :tickets: 
+
+      a slight behavioral change to attributes is, del'ing an attribute
+      does *not* cause the lazyloader of that attribute to fire off again;
+      the "del" makes the effective value of the attribute "None".  To
+      re-trigger the "loader" for an attribute, use
+      session.expire(instance,).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.filter(SomeClass.somechild == None), when comparing
+      a many-to-one property to None, properly generates "id IS NULL"
+      including that the NULL is on the right side.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.order_by() takes into account aliased joins, i.e.
+      query.join('orders', aliased=True).order_by(Order.id)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      eagerload(), lazyload(), eagerload_all() take an optional
+      second class-or-mapper argument, which will select the mapper
+      to apply the option towards.  This can select among other
+      mappers which were added using add_entity().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      eagerloading will work with mappers added via add_entity().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "cascade delete" behavior to "dynamic" relations just like
+      that of regular relations.  if passive_deletes flag (also just added)
+      is not set, a delete of the parent item will trigger a full load of
+      the child items so that they can be deleted or updated accordingly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      also with dynamic, implemented correct count() behavior as well
+      as other helper methods.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fix to cascades on polymorphic relations, such that cascades
+      from an object to a polymorphic collection continue cascading
+      along the set of attributes specific to each element in the collection.
+
+    .. change::
+        :tags: orm
+        :tickets: 893
+
+      query.get() and query.load() do not take existing filter or other
+      criterion into account; these methods *always* look up the given id
+      in the database or return the current instance from the identity map,
+      disregarding any existing filter, join, group_by or other criterion
+      which has been configured.
+
+    .. change::
+        :tags: orm
+        :tickets: 883
+
+      added support for version_id_col in conjunction with inheriting mappers.
+      version_id_col is typically set on the base mapper in an inheritance
+      relationship where it takes effect for all inheriting mappers.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      relaxed rules on column_property() expressions having labels; any
+      ColumnElement is accepted now, as the compiler auto-labels non-labeled
+      ColumnElements now.  a selectable, like a select() statement, still
+      requires conversion to ColumnElement via as_scalar() or label().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed backref bug where you could not del instance.attr if attr
+      was None
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      several ORM attributes have been removed or made private:
+      mapper.get_attr_by_column(), mapper.set_attr_by_column(),
+      mapper.pks_by_table, mapper.cascade_callable(),
+      MapperProperty.cascade_callable(), mapper.canload(),
+      mapper.save_obj(), mapper.delete_obj(), mapper._mapper_registry,
+      attributes.AttributeManager
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Assigning an incompatible collection type to a relation attribute now
+      raises TypeError instead of sqlalchemy's ArgumentError.
+
+    .. change::
+        :tags: orm
+        :tickets: 886
+
+      Bulk assignment of a MappedCollection now raises an error if a key in the
+      incoming dictionary does not match the key that the collection's keyfunc
+      would use for that value.
+
+    .. change::
+        :tags: orm, newval1, newval2
+        :tickets: 
+
+      Custom collections can now specify a @converter method to translate
+      objects used in "bulk" assignment into a stream of values, as in::
+      
+         obj.col =
+         # or
+         obj.dictcol = {'foo': newval1, 'bar': newval2}
+      
+      The MappedCollection uses this hook to ensure that incoming key/value
+      pairs are sane from the collection's perspective.
+
+    .. change::
+        :tags: orm
+        :tickets: 872
+
+      fixed endless loop issue when using lazy="dynamic" on both
+      sides of a bi-directional relationship
+
+    .. change::
+        :tags: orm
+        :tickets: 904
+
+      more fixes to the LIMIT/OFFSET aliasing applied with Query + eagerloads,
+      in this case when mapped against a select statement
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fix to self-referential eager loading such that if the same mapped
+      instance appears in two or more distinct sets of columns in the same
+      result set, its eagerly loaded collection will be populated regardless
+      of whether or not all of the rows contain a set of "eager" columns for
+      that collection.  this would also show up as a KeyError when fetching
+      results with join_depth turned on.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug where Query would not apply a subquery to the SQL when LIMIT
+      was used in conjunction with an inheriting mapper where the eager
+      loader was only in the parent mapper.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      clarified the error message which occurs when you try to update()
+      an instance with the same identity key as an instance already present
+      in the session.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      some clarifications and fixes to merge(instance, dont_load=True).
+      fixed bug where lazy loaders were getting disabled on returned instances.
+      Also, we currently do not support merging an instance which has uncommitted
+      changes on it, in the case that dont_load=True is used....this will
+      now raise an error.  This is due to complexities in merging the
+      "committed state" of the given instance to correctly correspond to the
+      newly copied instance, as well as other modified state.
+      Since the use case for dont_load=True is caching, the given instances
+      shouldn't have any uncommitted changes on them anyway.
+      We also copy the instances over without using any events now, so that
+      the 'dirty' list on the new session remains unaffected.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed bug which could arise when using session.begin_nested() in conjunction
+      with more than one level deep of enclosing session.begin() statements
+
+    .. change::
+        :tags: orm
+        :tickets: 914
+
+      fixed session.refresh() with instance that has custom entity_name
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      sqlite SLDate type will not erroneously render "microseconds" portion
+      of a datetime or time object.
+
+    .. change::
+        :tags: dialects
+        :tickets: 902
+
+      oracle
+       - added disconnect detection support for Oracle
+       - some cleanup to binary/raw types so that cx_oracle.LOB is detected
+         on an ad-hoc basis
+
+    .. change::
+        :tags: dialects
+        :tickets: 824, 839, 842, 901
+
+      MSSQL
+       - PyODBC no longer has a global "set nocount on".
+       - Fix non-identity integer PKs on autload
+       - Better support for convert_unicode
+       - Less strict date conversion for pyodbc/adodbapi
+       - Schema-qualified tables / autoload
+
+    .. change::
+        :tags: firebird, backend
+        :tickets: 410
+
+      does properly reflect domains (partially fixing) and
+      PassiveDefaults
+
+    .. change::
+        :tags: 3562, firebird, backend
+        :tickets: 
+
+      reverted to use default poolclass (was set to SingletonThreadPool in
+      0.4.0 for test purposes)
+
+    .. change::
+        :tags: firebird, backend
+        :tickets: 
+
+      map func.length() to 'char_length' (easily overridable with the UDF
+      'strlen' on old versions of Firebird)
+
+.. changelog::
+    :version: 0.4.1
+    :released: Sun Nov 18 2007
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the "shortname" keyword parameter on bindparam() has been
+      deprecated.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added contains operator (generates a "LIKE %<other>%" clause).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      anonymous column expressions are automatically labeled.
+      e.g. select([x* 5]) produces "SELECT x * 5 AS anon_1".
+      This allows the labelname to be present in the cursor.description
+      which can then be appropriately matched to result-column processing
+      rules. (we can't reliably use positional tracking for result-column
+      matches since text() expressions may represent multiple columns).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      operator overloading is now controlled by TypeEngine objects - the
+      one built-in operator overload so far is String types overloading
+      '+' to be the string concatenation operator.
+      User-defined types can also define their own operator overloading
+      by overriding the adapt_operator(self, op) method.
+
+    .. change::
+        :tags: sql
+        :tickets: 819
+
+      untyped bind parameters on the right side of a binary expression
+      will be assigned the type of the left side of the operation, to better
+      enable the appropriate bind parameter processing to take effect
+
+    .. change::
+        :tags: sql
+        :tickets: 833
+
+      Removed regular expression step from most statement compilations.
+      Also fixes
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed empty (zero column) sqlite inserts, allowing inserts on
+      autoincrementing single column tables.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed expression translation of text() clauses; this repairs various
+      ORM scenarios where literal text is used for SQL expressions
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Removed ClauseParameters object; compiled.params returns a regular
+      dictionary now, as well as result.last_inserted_params() /
+      last_updated_params().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed INSERT statements w.r.t. primary key columns that have
+      SQL-expression based default generators on them; SQL expression
+      executes inline as normal but will not trigger a "postfetch" condition
+      for the column, for those DB's who provide it via cursor.lastrowid
+
+    .. change::
+        :tags: sql
+        :tickets: 844
+
+      func. objects can be pickled/unpickled
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      rewrote and simplified the system used to "target" columns across
+      selectable expressions.  On the SQL side this is represented by the
+      "corresponding_column()" method. This method is used heavily by the ORM
+      to "adapt" elements of an expression to similar, aliased expressions,
+      as well as to target result set columns originally bound to a
+      table or selectable to an aliased, "corresponding" expression.  The new
+      rewrite features completely consistent and accurate behavior.
+
+    .. change::
+        :tags: sql
+        :tickets: 573
+
+      Added a field ("info") for storing arbitrary data on schema items
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The "properties" collection on Connections has been renamed "info" to
+      match schema's writable collections.  Access is still available via
+      the "properties" name until 0.5.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixed the close() method on Transaction when using strategy='threadlocal'
+
+    .. change::
+        :tags: sql
+        :tickets: 853
+
+      fix to compiled bind parameters to not mistakenly populate None
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      <Engine|Connection>._execute_clauseelement becomes a public method
+      Connectable.execute_clauseelement
+
+    .. change::
+        :tags: orm
+        :tickets: 843
+
+      eager loading with LIMIT/OFFSET applied no longer adds the primary
+      table joined to a limited subquery of itself; the eager loads now
+      join directly to the subquery which also provides the primary table's
+      columns to the result set.  This eliminates a JOIN from all eager loads
+      with LIMIT/OFFSET.
+
+    .. change::
+        :tags: orm
+        :tickets: 802
+
+      session.refresh() and session.expire() now support an additional argument
+      "attribute_names", a list of individual attribute keynames to be refreshed
+      or expired, allowing partial reloads of attributes on an already-loaded
+      instance.
+
+    .. change::
+        :tags: orm
+        :tickets: 767
+
+      added op() operator to instrumented attributes; i.e.
+      User.name.op('ilike')('%somename%')
+
+    .. change::
+        :tags: orm
+        :tickets: 676
+
+      Mapped classes may now define __eq__, __hash__, and __nonzero__ methods
+      with arbitrary semantics.  The orm now handles all mapped instances on
+      an identity-only basis. (e.g. 'is' vs '==')
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "properties" accessor on Mapper is removed; it now throws an informative
+      exception explaining the usage of mapper.get_property() and
+      mapper.iterate_properties
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added having() method to Query, applies HAVING to the generated statement
+      in the same way as filter() appends to the WHERE clause.
+
+    .. change::
+        :tags: orm
+        :tickets: 777
+
+      The behavior of query.options() is now fully based on paths, i.e. an
+      option such as eagerload_all('x.y.z.y.x') will apply eagerloading to
+      only those paths, i.e. and not 'x.y.x'; eagerload('children.children')
+      applies only to exactly two-levels deep, etc.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      PickleType will compare using `==` when set up with mutable=False,
+      and not the `is` operator.  To use `is` or any other comparator, send
+      in a custom comparison function using PickleType(comparator=my_custom_comparator).
+
+    .. change::
+        :tags: orm
+        :tickets: 848
+
+      query doesn't throw an error if you use distinct() and an order_by()
+      containing UnaryExpressions (or other) together
+
+    .. change::
+        :tags: orm
+        :tickets: 786
+
+      order_by() expressions from joined tables are properly added to columns
+      clause when using distinct()
+
+    .. change::
+        :tags: orm
+        :tickets: 858
+
+      fixed error where Query.add_column() would not accept a class-bound
+      attribute as an argument; Query also raises an error if an invalid
+      argument was sent to add_column() (at instances() time)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added a little more checking for garbage-collection dereferences in
+      InstanceState.__cleanup() to reduce "gc ignored" errors on app
+      shutdown
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The session API has been solidified:
+
+    .. change::
+        :tags: orm
+        :tickets: 840
+
+      It's an error to session.save() an object which is already
+      persistent
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      It's an error to session.delete() an object which is *not*
+      persistent.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      session.update() and session.delete() raise an error when updating
+      or deleting an instance that is already in the session with a
+      different identity.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The session checks more carefully when determining "object X already
+      in another session"; e.g. if you pickle a series of objects and
+      unpickle (i.e. as in a Pylons HTTP session or similar), they can go
+      into a new session without any conflict
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      merge() includes a keyword argument "dont_load=True".  setting this
+      flag will cause the merge operation to not load any data from the
+      database in response to incoming detached objects, and will accept
+      the incoming detached object as though it were already present in
+      that session.  Use this to merge detached objects from external
+      caching systems into the session.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Deferred column attributes no longer trigger a load operation when the
+      attribute is assigned to.  In those cases, the newly assigned value
+      will be present in the flushes' UPDATE statement unconditionally.
+
+    .. change::
+        :tags: orm
+        :tickets: 834
+
+      Fixed a truncation error when re-assigning a subset of a collection
+      (obj.relation = obj.relation[1:])
+
+    .. change::
+        :tags: orm
+        :tickets: 832
+
+      De-cruftified backref configuration code, backrefs which step on
+      existing properties now raise an error
+
+    .. change::
+        :tags: orm
+        :tickets: 831
+
+      Improved behavior of add_property() etc., fixed involving
+      synonym/deferred.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed clear_mappers() behavior to better clean up after itself.
+
+    .. change::
+        :tags: orm
+        :tickets: 841
+
+      Fix to "row switch" behavior, i.e. when an INSERT/DELETE is combined
+      into a single UPDATE; many-to-many relations on the parent object
+      update properly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed __hash__ for association proxy- these collections are unhashable,
+      just like their mutable Python counterparts.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added proxying of save_or_update, __contains__ and __iter__ methods for
+      scoped sessions.
+
+    .. change::
+        :tags: orm
+        :tickets: 852
+
+      fixed very hard-to-reproduce issue where by the FROM clause of Query
+      could get polluted by certain generative calls
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Added experimental support for MaxDB (versions >= 7.6.03.007 only).
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      oracle will now reflect "DATE" as an OracleDateTime column, not
+      OracleDate
+
+    .. change::
+        :tags: dialects
+        :tickets: 847
+
+      added awareness of schema name in oracle table_names() function,
+      fixes metadata.reflect(schema='someschema')
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      MSSQL anonymous labels for selection of functions made deterministic
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      sqlite will reflect "DECIMAL" as a numeric column.
+
+    .. change::
+        :tags: dialects
+        :tickets: 828
+
+      Made access dao detection more reliable
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Renamed the Dialect attribute 'preexecute_sequences' to
+      'preexecute_pk_sequences'.  An attribute porxy is in place for
+      out-of-tree dialects using the old name.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Added test coverage for unknown type reflection. Fixed sqlite/mysql
+      handling of type reflection for unknown types.
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      Added REAL for mysql dialect (for folks exploiting the
+      REAL_AS_FLOAT sql mode).
+
+    .. change::
+        :tags: dialects
+        :tickets: 
+
+      mysql Float, MSFloat and MSDouble constructed without arguments
+      now produce no-argument DDL, e.g.'FLOAT'.
+
+    .. change::
+        :tags: misc
+        :tickets: 
+
+      Removed unused util.hash().
+
+.. changelog::
+    :version: 0.4.0
+    :released: Wed Oct 17 2007
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      (see 0.4.0beta1 for the start of major changes against 0.3,
+      as well as http://www.sqlalchemy.org/trac/wiki/WhatsNewIn04 )
+
+    .. change::
+        :tags: 
+        :tickets: 785
+
+      Added initial Sybase support (mxODBC so far)
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added partial index support for PostgreSQL. Use the postgres_where keyword
+      on the Index.
+
+    .. change::
+        :tags: 
+        :tickets: 817
+
+      string-based query param parsing/config file parser understands
+      wider range of string values for booleans
+
+    .. change::
+        :tags: 
+        :tickets: 813
+
+      backref remove object operation doesn't fail if the other-side
+      collection doesn't contain the item, supports noload collections
+
+    .. change::
+        :tags: 
+        :tickets: 818
+
+      removed __len__ from "dynamic" collection as it would require issuing
+      a SQL "count()" operation, thus forcing all list evaluations to issue
+      redundant SQL
+
+    .. change::
+        :tags: 
+        :tickets: 816
+
+      inline optimizations added to locate_dirty() which can greatly speed up
+      repeated calls to flush(), as occurs with autoflush=True
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The IdentifierPreprarer's _requires_quotes test is now regex based.  Any
+      out-of-tree dialects that provide custom sets of legal_characters or
+      illegal_initial_characters will need to move to regexes or override
+      _requires_quotes.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Firebird has supports_sane_rowcount and supports_sane_multi_rowcount set
+      to False due to ticket #370 (right way).
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Improvements and fixes on Firebird reflection:
+      . FBDialect now mimics OracleDialect, regarding case-sensitivity of TABLE and
+        COLUMN names (see 'case_sensitive remotion' topic on this current file).
+      . FBDialect.table_names() doesn't bring system tables (ticket:796).
+      . FB now reflects Column's nullable property correctly.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Fixed SQL compiler's awareness of top-level column labels as used
+      in result-set processing; nested selects which contain the same column
+      names don't affect the result or conflict with result-column metadata.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      query.get() and related functions (like many-to-one lazyloading)
+      use compile-time-aliased bind parameter names, to prevent
+      name conflicts with bind parameters that already exist in the
+      mapped selectable.
+
+    .. change::
+        :tags: 
+        :tickets: 795
+
+      Fixed three- and multi-level select and deferred inheritance loading
+      (i.e. abc inheritance with no select_table).
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Ident passed to id_chooser in shard.py always a list.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The no-arg ResultProxy._row_processor() is now the class attribute
+      `_process_row`.
+
+    .. change::
+        :tags: 
+        :tickets: 797
+
+      Added support for returning values from inserts and updates for
+      PostgreSQL 8.2+.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      PG reflection, upon seeing the default schema name being used explicitly
+      as the "schema" argument in a Table, will assume that this is the the
+      user's desired convention, and will explicitly set the "schema" argument
+      in foreign-key-related reflected tables, thus making them match only
+      with Table constructors that also use the explicit "schema" argument
+      (even though its the default schema).
+      In other words, SA assumes the user is being consistent in this usage.
+
+    .. change::
+        :tags: 
+        :tickets: 808
+
+      fixed sqlite reflection of BOOL/BOOLEAN
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added support for UPDATE with LIMIT on mysql.
+
+    .. change::
+        :tags: 
+        :tickets: 803
+
+      null foreign key on a m2o doesn't trigger a lazyload
+
+    .. change::
+        :tags: 
+        :tickets: 800
+
+      oracle does not implicitly convert to unicode for non-typed result
+      sets (i.e. when no TypeEngine/String/Unicode type is even being used;
+      previously it was detecting DBAPI types and converting regardless).
+      should fix
+
+    .. change::
+        :tags: 
+        :tickets: 806
+
+      fix to anonymous label generation of long table/column names
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Firebird dialect now uses SingletonThreadPool as poolclass.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Firebird now uses dialect.preparer to format sequences names
+
+    .. change::
+        :tags: 
+        :tickets: 810
+
+      Fixed breakage with postgres and multiple two-phase transactions. Two-phase
+      commits and and rollbacks didn't automatically end up with a new transaction
+      as the usual dbapi commits/rollbacks do.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added an option to the _ScopedExt mapper extension to not automatically
+      save new objects to session on object initialization.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      fixed Oracle non-ansi join syntax
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      PickleType and Interval types (on db not supporting it natively) are now
+      slightly faster.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added Float and Time types to Firebird (FBFloat and FBTime). Fixed
+      BLOB SUB_TYPE for TEXT and Binary types.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Changed the API for the in_ operator. in_() now accepts a single argument
+      that is a sequence of values or a selectable. The old API of passing in
+      values as varargs still works but is deprecated.
+
+.. changelog::
+    :version: 0.4.0beta6
+    :released: Thu Sep 27 2007
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The Session identity map is now *weak referencing* by default, use
+      weak_identity_map=False to use a regular dict.  The weak dict we are using
+      is customized to detect instances which are "dirty" and maintain a
+      temporary strong reference to those instances until changes are flushed.
+
+    .. change::
+        :tags: 
+        :tickets: 758
+
+      Mapper compilation has been reorganized such that most compilation occurs
+      upon mapper construction.  This allows us to have fewer calls to
+      mapper.compile() and also to allow class-based properties to force a
+      compilation (i.e. User.addresses == 7 will compile all mappers; this is).  The only caveat here is that an inheriting mapper now
+      looks for its inherited mapper upon construction; so mappers within
+      inheritance relationships need to be constructed in inheritance order
+      (which should be the normal case anyway).
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      added "FETCH" to the keywords detected by Postgres to indicate a
+      result-row holding statement (i.e. in addition to "SELECT").
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added full list of SQLite reserved keywords so that they get escaped
+      properly.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Tightened up the relationship between the Query's generation of "eager
+      load" aliases, and Query.instances() which actually grabs the eagerly
+      loaded rows.  If the aliases were not specifically generated for that
+      statement by EagerLoader, the EagerLoader will not take effect when the
+      rows are fetched.  This prevents columns from being grabbed accidentally
+      as being part of an eager load when they were not meant for such, which
+      can happen with textual SQL as well as some inheritance situations.  It's
+      particularly important since the "anonymous aliasing" of columns uses
+      simple integer counts now to generate labels.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Removed "parameters" argument from clauseelement.compile(), replaced with
+      "column_keys".  The parameters sent to execute() only interact with the
+      insert/update statement compilation process in terms of the column names
+      present but not the values for those columns.  Produces more consistent
+      execute/executemany behavior, simplifies things a bit internally.
+
+    .. change::
+        :tags: 
+        :tickets: 560
+
+      Added 'comparator' keyword argument to PickleType.  By default, "mutable"
+      PickleType does a "deep compare" of objects using their dumps()
+      representation.  But this doesn't work for dictionaries.  Pickled objects
+      which provide an adequate __eq__() implementation can be set up with
+      "PickleType(comparator=operator.eq)"
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added session.is_modified(obj) method; performs the same "history"
+      comparison operation as occurs within a flush operation; setting
+      include_collections=False gives the same result as is used when the flush
+      determines whether or not to issue an UPDATE for the instance's row.
+
+    .. change::
+        :tags: 
+        :tickets: 584, 761
+
+      Added "schema" argument to Sequence; use this with Postgres /Oracle when
+      the sequence is located in an alternate schema.  Implements part of, should fix.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Fixed reflection of the empty string for mysql enums.
+
+    .. change::
+        :tags: 
+        :tickets: 794
+
+      Changed MySQL dialect to use the older LIMIT <offset>, <limit> syntax
+      instead of LIMIT <l> OFFSET <o> for folks using 3.23.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added 'passive_deletes="all"' flag to relation(), disables all nulling-out
+      of foreign key attributes during a flush where the parent object is
+      deleted.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Column defaults and onupdates, executing inline, will add parenthesis for
+      subqueries and other parenthesis-requiring expressions
+
+    .. change::
+        :tags: 
+        :tickets: 793
+
+      The behavior of String/Unicode types regarding that they auto-convert to
+      TEXT/CLOB when no length is present now occurs *only* for an exact type of
+      String or Unicode with no arguments.  If you use VARCHAR or NCHAR
+      (subclasses of String/Unicode) with no length, they will be interpreted by
+      the dialect as VARCHAR/NCHAR; no "magic" conversion happens there.  This
+      is less surprising behavior and in particular this helps Oracle keep
+      string-based bind parameters as VARCHARs and not CLOBs.
+
+    .. change::
+        :tags: 
+        :tickets: 771
+
+      Fixes to ShardedSession to work with deferred columns.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      User-defined shard_chooser() function must accept "clause=None" argument;
+      this is the ClauseElement passed to session.execute(statement) and can be
+      used to determine correct shard id (since execute() doesn't take an
+      instance.)
+
+    .. change::
+        :tags: 
+        :tickets: 764
+
+      Adjusted operator precedence of NOT to match '==' and others, so that
+      ~(x <operator> y) produces NOT (x <op> y), which is better compatible
+      with older MySQL versions..  This doesn't apply to "~(x==y)"
+      as it does in 0.3 since ~(x==y) compiles to "x != y", but still applies
+      to operators like BETWEEN.
+
+    .. change::
+        :tags: 
+        :tickets: 757, 768, 779, 728
+
+      Other tickets:,,.
+
+.. changelog::
+    :version: 0.4.0beta5
+    :released: 
+
+    .. change::
+        :tags: 
+        :tickets: 754
+
+      Connection pool fixes; the better performance of beta4 remains but fixes
+      "connection overflow" and other bugs which were present (like).
+
+    .. change::
+        :tags: 
+        :tickets: 769
+
+      Fixed bugs in determining proper sync clauses from custom inherit
+      conditions.
+
+    .. change::
+        :tags: 
+        :tickets: 763
+
+      Extended 'engine_from_config' coercion for QueuePool size / overflow.
+
+    .. change::
+        :tags: 
+        :tickets: 748
+
+      mysql views can be reflected again.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      AssociationProxy can now take custom getters and setters.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Fixed malfunctioning BETWEEN in orm queries.
+
+    .. change::
+        :tags: 
+        :tickets: 762
+
+      Fixed OrderedProperties pickling
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      SQL-expression defaults and sequences now execute "inline" for all
+      non-primary key columns during an INSERT or UPDATE, and for all columns
+      during an executemany()-style call. inline=True flag on any insert/update
+      statement also forces the same behavior with a single execute().
+      result.postfetch_cols() is a collection of columns for which the previous
+      single insert or update statement contained a SQL-side default expression.
+
+    .. change::
+        :tags: 
+        :tickets: 759
+
+      Fixed PG executemany() behavior.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      postgres reflects tables with autoincrement=False for primary key columns
+      which have no defaults.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      postgres no longer wraps executemany() with individual execute() calls,
+      instead favoring performance.  "rowcount"/"concurrency" checks with
+      deleted items (which use executemany) are disabled with PG since psycopg2
+      does not report proper rowcount for executemany().
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 742
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 748
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 760
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 762
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 763
+
+      
+
+.. changelog::
+    :version: 0.4.0beta4
+    :released: Wed Aug 22 2007
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Tidied up what ends up in your namespace when you 'from sqlalchemy import *':
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      'table' and 'column' are no longer imported.  They remain available by
+      direct reference (as in 'sql.table' and 'sql.column') or a glob import
+      from the sql package.  It was too easy to accidentally use a
+      sql.expressions.table instead of schema.Table when just starting out
+      with SQLAlchemy, likewise column.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Internal-ish classes like ClauseElement, FromClause, NullTypeEngine,
+      etc., are also no longer imported into your namespace
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The 'Smallinteger' compatiblity name (small i!) is no longer imported,
+      but remains in schema.py for now.  SmallInteger (big I!) is still
+      imported.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The connection pool uses a "threadlocal" strategy internally to return
+      the same connection already bound to a thread, for "contextual" connections;
+      these are the connections used when you do a "connectionless" execution
+      like insert().execute().  This is like a "partial" version of the
+      "threadlocal" engine strategy but without the thread-local transaction part
+      of it.  We're hoping it reduces connection pool overhead as well as
+      database usage.  However, if it proves to impact stability in a negative way,
+      we'll roll it right back.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Fix to bind param processing such that "False" values (like blank strings)
+      still get processed/encoded.
+
+    .. change::
+        :tags: 
+        :tickets: 752
+
+      Fix to select() "generative" behavior, such that calling column(),
+      select_from(), correlate(), and with_prefix() does not modify the
+      original select object
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added a "legacy" adapter to types, such that user-defined TypeEngine
+      and TypeDecorator classes which define convert_bind_param() and/or
+      convert_result_value() will continue to function.  Also supports
+      calling the super() version of those methods.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added session.prune(), trims away instances cached in a session that
+      are no longer referenced elsewhere. (A utility for strong-ref
+      identity maps).
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added close() method to Transaction.  Closes out a transaction using
+      rollback if it's the outermost transaction, otherwise just ends
+      without affecting the outer transaction.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Transactional and non-transactional Session integrates better with
+      bound connection; a close() will ensure that connection
+      transactional state is the same as that which existed on it before
+      being bound to the Session.
+
+    .. change::
+        :tags: 
+        :tickets: 735
+
+      Modified SQL operator functions to be module-level operators,
+      allowing SQL expressions to be pickleable.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Small adjustment to mapper class.__init__ to allow for Py2.6
+      object.__init__() behavior.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Fixed 'prefix' argument for select()
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Connection.begin() no longer accepts nested=True, this logic is now
+      all in begin_nested().
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Fixes to new "dynamic" relation loader involving cascades
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 735
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 752
+
+      
+
+.. changelog::
+    :version: 0.4.0beta3
+    :released: Thu Aug 16 2007
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      SQL types optimization:
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      New performance tests show a combined mass-insert/mass-select test as
+      having 68% fewer function calls than the same test run against 0.3.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      General performance improvement of result set iteration is around 10-20%.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      In types.AbstractType, convert_bind_param() and convert_result_value()
+      have migrated to callable-returning bind_processor() and
+      result_processor() methods.  If no callable is returned, no pre/post
+      processing function is called.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Hooks added throughout base/sql/defaults to optimize the calling of bind
+      aram/result processors so that method call overhead is minimized.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Support added for executemany() scenarios such that unneeded "last row id"
+      logic doesn't kick in, parameters aren't excessively traversed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added 'inherit_foreign_keys' arg to mapper().
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Added support for string date passthrough in sqlite.
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 738
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 739
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 743
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 744
+
+      
+
+.. changelog::
+    :version: 0.4.0beta2
+    :released: Tue Aug 14 2007
+
+    .. change::
+        :tags: oracle, improvements.
+        :tickets: 
+
+      Auto-commit after LOAD DATA INFILE for mysql.
+
+    .. change::
+        :tags: oracle, improvements.
+        :tickets: 
+
+      A rudimental SessionExtension class has been added, allowing user-defined
+      functionality to take place at flush(), commit(), and rollback() boundaries.
+
+    .. change::
+        :tags: oracle, improvements.
+        :tickets: 
+
+      Added engine_from_config() function for helping to create_engine() from an
+      .ini style config.
+
+    .. change::
+        :tags: oracle, improvements.
+        :tickets: 
+
+      base_mapper() becomes a plain attribute.
+
+    .. change::
+        :tags: oracle, improvements.
+        :tickets: 
+
+      session.execute() and scalar() can search for a Table with which to bind from
+      using the given ClauseElement.
+
+    .. change::
+        :tags: oracle, improvements.
+        :tickets: 
+
+      Session automatically extrapolates tables from mappers with binds, also uses
+      base_mapper so that inheritance hierarchies bind automatically.
+
+    .. change::
+        :tags: oracle, improvements.
+        :tickets: 
+
+      Moved ClauseVisitor traversal back to inlined non-recursive.
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 730
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 732
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 733
+
+      
+
+    .. change::
+        :tags: tickets, fixed
+        :tickets: 734
+
+      
+
+.. changelog::
+    :version: 0.4.0beta1
+    :released: Sun Aug 12 2007
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Speed! Along with recent speedups to ResultProxy, total number of function
+      calls significantly reduced for large loads.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      test/perf/masseagerload.py reports 0.4 as having the fewest number of
+      function calls across all SA versions (0.1, 0.2, and 0.3).
+
+    .. change::
+        :tags: orm
+        :tickets: 213
+
+      New collection_class api and implementation. Collections are
+      now instrumented via decorations rather than proxying.  You can now have
+      collections that manage their own membership, and your class instance will
+      be directly exposed on the relation property.  The changes are transparent
+      for most users.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      InstrumentedList (as it was) is removed, and relation properties no
+      longer have 'clear()', '.data', or any other added methods beyond those
+      provided by the collection type. You are free, of course, to add them to
+      a custom class.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      __setitem__-like assignments now fire remove events for the existing
+      value, if any.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      dict-likes used as collection classes no longer need to change __iter__
+      semantics- itervalues() is used by default instead. This is a backwards
+      incompatible change.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Subclassing dict for a mapped collection is no longer needed in most
+      cases. orm.collections provides canned implementations that key objects
+      by a specified column or a custom function of your choice.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Collection assignment now requires a compatible type- assigning None to
+      clear a collection or assigning a list to a dict collection will now
+      raise an argument error.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      AttributeExtension moved to interfaces, and .delete is now .remove The
+      event method signature has also been swapped around.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Major overhaul for Query:
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      All selectXXX methods are deprecated.  Generative methods are now the
+      standard way to do things, i.e. filter(), filter_by(), all(), one(),
+      etc.  Deprecated methods are docstring'ed with their new replacements.
+
+    .. change::
+        :tags: orm
+        :tickets: 643
+
+      Class-level properties are now usable as query elements... no more
+      '.c.'!  "Class.c.propname" is now superceded by "Class.propname".  All
+      clause operators are supported, as well as higher level operators such
+      as Class.prop==<some instance> for scalar attributes,
+      Class.prop.contains(<some instance>) and Class.prop.any(<some
+      expression>) for collection-based attributes (all are also
+      negatable).  Table-based column expressions as well as columns mounted
+      on mapped classes via 'c' are of course still fully available and can be
+      freely mixed with the new attributes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Removed ancient query.select_by_attributename() capability.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The aliasing logic used by eager loading has been generalized, so that
+      it also adds full automatic aliasing support to Query.  It's no longer
+      necessary to create an explicit Alias to join to the same tables
+      multiple times; *even for self-referential relationships*.
+      
+      - join() and outerjoin() take arguments "aliased=True".  Yhis causes
+        their joins to be built on aliased tables; subsequent calls to
+        filter() and filter_by() will translate all table expressions (yes,
+        real expressions using the original mapped Table) to be that of the
+        Alias for the duration of that join() (i.e. until reset_joinpoint() or
+        another join() is called).
+      
+      - join() and outerjoin() take arguments "id=<somestring>".  When used
+        with "aliased=True", the id can be referenced by add_entity(cls,
+        id=<somestring>) so that you can select the joined instances even if
+        they're from an alias.
+      
+      - join() and outerjoin() now work with self-referential relationships!
+        Using "aliased=True", you can join as many levels deep as desired,
+        i.e. query.join(['children', 'children'], aliased=True); filter
+        criterion will be against the rightmost joined table
+
+    .. change::
+        :tags: orm
+        :tickets: 660
+
+      Added query.populate_existing(), marks the query to reload all
+      attributes and collections of all instances touched in the query,
+      including eagerly-loaded entities.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added eagerload_all(), allows eagerload_all('x.y.z') to specify eager
+      loading of all properties in the given path.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Major overhaul for Session:
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      New function which "configures" a session called "sessionmaker()".  Send
+      various keyword arguments to this function once, returns a new class
+      which creates a Session against that stereotype.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      SessionTransaction removed from "public" API.  You now can call begin()/
+      commit()/rollback() on the Session itself.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session also supports SAVEPOINT transactions; call begin_nested().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session supports two-phase commit behavior when vertically or
+      horizontally partitioning (i.e., using more than one engine).  Use
+      twophase=True.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session flag "transactional=True" produces a session which always places
+      itself into a transaction when first used.  Upon commit(), rollback() or
+      close(), the transaction ends; but begins again on the next usage.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session supports "autoflush=True".  This issues a flush() before each
+      query.  Use in conjunction with transactional, and you can just
+      save()/update() and then query, the new objects will be there.  Use
+      commit() at the end (or flush() if non-transactional) to flush remaining
+      changes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      New scoped_session() function replaces SessionContext and assignmapper.
+      Builds onto "sessionmaker()" concept to produce a class whos Session()
+      construction returns the thread-local session.  Or, call all Session
+      methods as class methods, i.e. Session.save(foo); Session.commit().
+      just like the old "objectstore" days.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added new "binds" argument to Session to support configuration of
+      multiple binds with sessionmaker() function.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      A rudimental SessionExtension class has been added, allowing
+      user-defined functionality to take place at flush(), commit(), and
+      rollback() boundaries.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query-based relation()s available with dynamic_loader().  This is a
+      *writable* collection (supporting append() and remove()) which is also a
+      live Query object when accessed for reads.  Ideal for dealing with very
+      large collections where only partial loading is desired.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      flush()-embedded inline INSERT/UPDATE expressions.  Assign any SQL
+      expression, like "sometable.c.column + 1", to an instance's attribute.
+      Upon flush(), the mapper detects the expression and embeds it directly in
+      the INSERT or UPDATE statement; the attribute gets deferred on the
+      instance so it loads the new value the next time you access it.
+
+    .. change::
+        :tags: orm
+        :tickets: 618
+
+      A rudimental sharding (horizontal scaling) system is introduced.  This
+      system uses a modified Session which can distribute read and write
+      operations among multiple databases, based on user-defined functions
+      defining the "sharding strategy".  Instances and their dependents can be
+      distributed and queried among multiple databases based on attribute
+      values, round-robin approaches or any other user-defined
+      system.
+
+    .. change::
+        :tags: orm
+        :tickets: 659
+
+      Eager loading has been enhanced to allow even more joins in more places.
+      It now functions at any arbitrary depth along self-referential and
+      cyclical structures.  When loading cyclical structures, specify
+      "join_depth" on relation() indicating how many times you'd like the table
+      to join to itself; each level gets a distinct table alias.  The alias
+      names themselves are generated at compile time using a simple counting
+      scheme now and are a lot easier on the eyes, as well as of course
+      completely deterministic.
+
+    .. change::
+        :tags: orm
+        :tickets: 211
+
+      Added composite column properties.  This allows you to create a type which
+      is represented by more than one column, when using the ORM.  Objects of
+      the new type are fully functional in query expressions, comparisons,
+      query.get() clauses, etc. and act as though they are regular single-column
+      scalars... except they're not!  Use the function composite(cls, *columns)
+      inside of the mapper's "properties" dict, and instances of cls will be
+      created/mapped to a single attribute, comprised of the values correponding
+      to *columns.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Improved support for custom column_property() attributes which feature
+      correlated subqueries, works better with eager loading now.
+
+    .. change::
+        :tags: orm
+        :tickets: 611
+
+      Primary key "collapse" behavior; the mapper will analyze all columns in
+      its given selectable for primary key "equivalence", that is, columns which
+      are equivalent via foreign key relationship or via an explicit
+      inherit_condition. primarily for joined-table inheritance scenarios where
+      different named PK columns in inheriting tables should "collapse" into a
+      single-valued (or fewer-valued) primary key.  Fixes things like.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Joined-table inheritance will now generate the primary key columns of all
+      inherited classes against the root table of the join only.  This implies
+      that each row in the root table is distinct to a single instance.  If for
+      some rare reason this is not desireable, explicit primary_key settings on
+      individual mappers will override it.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      When "polymorphic" flags are used with joined-table or single-table
+      inheritance, all identity keys are generated against the root class of the
+      inheritance hierarchy; this allows query.get() to work polymorphically
+      using the same caching semantics as a non-polymorphic get.  Note that this
+      currently does not work with concrete inheritance.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Secondary inheritance loading: polymorphic mappers can be constructed
+      *without* a select_table argument. inheriting mappers whose tables were
+      not represented in the initial load will issue a second SQL query
+      immediately, once per instance (i.e. not very efficient for large lists),
+      in order to load the remaining columns.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Secondary inheritance loading can also move its second query into a
+      column-level "deferred" load, via the "polymorphic_fetch" argument, which
+      can be set to 'select' or 'deferred'
+
+    .. change::
+        :tags: orm
+        :tickets: 696
+
+      It's now possible to map only a subset of available selectable columns
+      onto mapper properties, using include_columns/exclude_columns..
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added undefer_group() MapperOption, sets a set of "deferred" columns
+      joined by a "group" to load as "undeferred".
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Rewrite of the "deterministic alias name" logic to be part of the SQL
+      layer, produces much simpler alias and label names more in the style of
+      Hibernate
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Speed!  Clause compilation as well as the mechanics of SQL constructs have
+      been streamlined and simplified to a signficant degree, for a 20-30%
+      improvement of the statement construction/compilation overhead of 0.3.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      All "type" keyword arguments, such as those to bindparam(), column(),
+      Column(), and func.<something>(), renamed to "type_".  Those objects still
+      name their "type" attribute as "type".
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      case_sensitive=(True|False) setting removed from schema items, since
+      checking this state added a lot of method call overhead and there was no
+      decent reason to ever set it to False.  Table and column names which are
+      all lower case will be treated as case-insenstive (yes we adjust for
+      Oracle's UPPERCASE style too).
+
+    .. change::
+        :tags: transactions
+        :tickets: 
+
+      Added context manager (with statement) support for transactions.
+
+    .. change::
+        :tags: transactions
+        :tickets: 
+
+      Added support for two phase commit, works with mysql and postgres so far.
+
+    .. change::
+        :tags: transactions
+        :tickets: 
+
+      Added a subtransaction implementation that uses savepoints.
+
+    .. change::
+        :tags: transactions
+        :tickets: 
+
+      Added support for savepoints.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      Tables can be reflected from the database en-masse without declaring
+      them in advance.  MetaData(engine, reflect=True) will load all tables
+      present in the database, or use metadata.reflect() for finer control.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      DynamicMetaData has been renamed to ThreadLocalMetaData
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      The ThreadLocalMetaData constructor now takes no arguments.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      BoundMetaData has been removed- regular MetaData is equivalent
+
+    .. change::
+        :tags: metadata
+        :tickets: 646
+
+      Numeric and Float types now have an "asdecimal" flag; defaults to True for
+      Numeric, False for Float.  When True, values are returned as
+      decimal.Decimal objects; when False, values are returned as float().  The
+      defaults of True/False are already the behavior for PG and MySQL's DBAPI
+      modules.
+
+    .. change::
+        :tags: metadata
+        :tickets: 475
+
+      New SQL operator implementation which removes all hardcoded operators from
+      expression structures and moves them into compilation; allows greater
+      flexibility of operator compilation; for example, "+" compiles to "||"
+      when used in a string context, or "concat(a,b)" on MySQL; whereas in a
+      numeric context it compiles to "+".  Fixes.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      "Anonymous" alias and label names are now generated at SQL compilation
+      time in a completely deterministic fashion... no more random hex IDs
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      Significant architectural overhaul to SQL elements (ClauseElement).  All
+      elements share a common "mutability" framework which allows a consistent
+      approach to in-place modifications of elements as well as generative
+      behavior.  Improves stability of the ORM which makes heavy usage of
+      mutations to SQL expressions.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      select() and union()'s now have "generative" behavior.  Methods like
+      order_by() and group_by() return a *new* instance - the original instance
+      is left unchanged.  Non-generative methods remain as well.
+
+    .. change::
+        :tags: metadata
+        :tickets: 569, 52
+
+      The internals of select/union vastly simplified- all decision making
+      regarding "is subquery" and "correlation" pushed to SQL generation phase.
+      select() elements are now *never* mutated by their enclosing containers or
+      by any dialect's compilation process
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      select(scalar=True) argument is deprecated; use select(..).as_scalar().
+      The resulting object obeys the full "column" interface and plays better
+      within expressions.
+
+    .. change::
+        :tags: metadata
+        :tickets: 504
+
+      Added select().with_prefix('foo') allowing any set of keywords to be
+      placed before the columns clause of the SELECT
+
+    .. change::
+        :tags: metadata
+        :tickets: 686
+
+      Added array slice support to row[<index>]
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      Result sets make a better attempt at matching the DBAPI types present in
+      cursor.description to the TypeEngine objects defined by the dialect, which
+      are then used for result-processing. Note this only takes effect for
+      textual SQL; constructed SQL statements always have an explicit type map.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      Result sets from CRUD operations close their underlying cursor immediately
+      and will also autoclose the connection if defined for the operation; this
+      allows more efficient usage of connections for successive CRUD operations
+      with less chance of "dangling connections".
+
+    .. change::
+        :tags: metadata
+        :tickets: 559
+
+      Column defaults and onupdate Python functions (i.e. passed to
+      ColumnDefault) may take zero or one arguments; the one argument is the
+      ExecutionContext, from which you can call "context.parameters[someparam]"
+      to access the other bind parameter values affixed to the statement.  The connection used for the execution is available as well
+      so that you can pre-execute statements.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      Added "explcit" create/drop/execute support for sequences (i.e. you can
+      pass a "connectable" to each of those methods on Sequence).
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      Better quoting of identifiers when manipulating schemas.
+
+    .. change::
+        :tags: metadata
+        :tickets: 
+
+      Standardized the behavior for table reflection where types can't be
+      located; NullType is substituted instead, warning is raised.
+
+    .. change::
+        :tags: metadata
+        :tickets: 606
+
+      ColumnCollection (i.e. the 'c' attribute on tables) follows dictionary
+      semantics for "__contains__"
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Speed! The mechanics of result processing and bind parameter processing
+      have been overhauled, streamlined and optimized to issue as little method
+      calls as possible.  Bench tests for mass INSERT and mass rowset iteration
+      both show 0.4 to be over twice as fast as 0.3, using 68% fewer function
+      calls.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      You can now hook into the pool lifecycle and run SQL statements or other
+      logic at new each DBAPI connection, pool check-out and check-in.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Connections gain a .properties collection, with contents scoped to the
+      lifetime of the underlying DBAPI connection
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Removed auto_close_cursors and disallow_open_cursors arguments from Pool;
+      reduces overhead as cursors are normally closed by ResultProxy and
+      Connection.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      proxyengine is temporarily removed, pending an actually working
+      replacement.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      SelectResults has been replaced by Query.  SelectResults /
+      SelectResultsExt still exist but just return a slightly modified Query
+      object for backwards-compatibility.  join_to() method from SelectResults
+      isn't present anymore, need to use join().
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Table and column names loaded via reflection are now Unicode.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      All standard column types are now supported, including SET.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Table reflection can now be performed in as little as one round-trip.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      ANSI and ANSI_QUOTES sql modes are now supported.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Indexes are now reflected.
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      Added PGArray datatype for using postgres array datatypes.
+
+    .. change::
+        :tags: oracle
+        :tickets: 507
+
+      Very rudimental support for OUT parameters added; use sql.outparam(name,
+      type) to set up an OUT parameter, just like bindparam(); after execution,
+      values are avaiable via result.out_parameters dictionary.
diff --git a/doc/build/changelog/changelog_05.rst b/doc/build/changelog/changelog_05.rst
new file mode 100644 (file)
index 0000000..0bcc1aa
--- /dev/null
@@ -0,0 +1,3775 @@
+
+==============
+0.5 Changelog
+==============
+
+                
+.. changelog::
+    :version: 0.5.9
+    :released: 
+
+    .. change::
+        :tags: sql
+        :tickets: 1661
+
+      Fixed erroneous self_group() call in expression package.
+
+.. changelog::
+    :version: 0.5.8
+    :released: Sat Jan 16 2010
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The copy() method on Column now supports uninitialized,
+      unnamed Column objects. This allows easy creation of
+      declarative helpers which place common columns on multiple
+      subclasses.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Default generators like Sequence() translate correctly
+      across a copy() operation.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Sequence() and other DefaultGenerator objects are accepted
+      as the value for the "default" and "onupdate" keyword
+      arguments of Column, in addition to being accepted
+      positionally.
+
+    .. change::
+        :tags: sql
+        :tickets: 1568, 1617
+
+      Fixed a column arithmetic bug that affected column
+      correspondence for cloned selectables which contain
+      free-standing column expressions.   This bug is
+      generally only noticeable when exercising newer
+      ORM behavior only availble in 0.6 via,
+      but is more correct at the SQL expression level
+      as well.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1647
+
+      The extract() function, which was slightly improved in
+      0.5.7, needed a lot more work to generate the correct
+      typecast (the typecasts appear to be necessary in PG's
+      EXTRACT quite a lot of the time).  The typecast is
+      now generated using a rule dictionary based
+      on PG's documentation for date/time/interval arithmetic.
+      It also accepts text() constructs again, which was broken
+      in 0.5.7.
+
+    .. change::
+        :tags: firebird
+        :tickets: 1646
+
+      Recognize more errors as disconnections.
+
+.. changelog::
+    :version: 0.5.7
+    :released: Sat Dec 26 2009
+
+    .. change::
+        :tags: orm
+        :tickets: 1543
+
+      contains_eager() now works with the automatically
+      generated subquery that results when you say
+      "query(Parent).join(Parent.somejoinedsubclass)", i.e.
+      when Parent joins to a joined-table-inheritance subclass.
+      Previously contains_eager() would erroneously add the
+      subclass table to the query separately producing a
+      cartesian product.  An example is in the ticket
+      description.
+
+    .. change::
+        :tags: orm
+        :tickets: 1553
+
+      query.options() now only propagate to loaded objects
+      for potential further sub-loads only for options where
+      such behavior is relevant, keeping
+      various unserializable options like those generated
+      by contains_eager() out of individual instance states.
+
+    .. change::
+        :tags: orm
+        :tickets: 1054
+
+      Session.execute() now locates table- and
+      mapper-specific binds based on a passed
+      in expression which is an insert()/update()/delete()
+      construct.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session.merge() now properly overwrites a many-to-one or
+      uselist=False attribute to None if the attribute
+      is also None in the given object to be merged.
+
+    .. change::
+        :tags: orm
+        :tickets: 1618
+
+      Fixed a needless select which would occur when merging
+      transient objects that contained a null primary key
+      identifier.
+
+    .. change::
+        :tags: orm
+        :tickets: 1585
+
+      Mutable collection passed to the "extension" attribute
+      of relation(), column_property() etc. will not be mutated
+      or shared among multiple instrumentation calls, preventing
+      duplicate extensions, such as backref populators,
+      from being inserted into the list.
+
+    .. change::
+        :tags: orm
+        :tickets: 1504
+
+      Fixed the call to get_committed_value() on CompositeProperty.
+
+    .. change::
+        :tags: orm
+        :tickets: 1602
+
+      Fixed bug where Query would crash if a join() with no clear
+      "left" side were called when a non-mapped column entity
+      appeared in the columns list.
+
+    .. change::
+        :tags: orm
+        :tickets: 1616, 1480
+
+      Fixed bug whereby composite columns wouldn't load properly
+      when configured on a joined-table subclass, introduced in
+      version 0.5.6 as a result of the fix for. thx to Scott Torborg.
+
+    .. change::
+        :tags: orm
+        :tickets: 1556
+
+      The "use get" behavior of many-to-one relations, i.e. that a
+      lazy load will fallback to the possibly cached query.get()
+      value, now works across join conditions where the two compared
+      types are not exactly the same class, but share the same
+      "affinity" - i.e. Integer and SmallInteger.  Also allows
+      combinations of reflected and non-reflected types to work
+      with 0.5 style type reflection, such as PGText/Text (note 0.6
+      reflects types as their generic versions).
+
+    .. change::
+        :tags: orm
+        :tickets: 1436
+
+      Fixed bug in query.update() when passing Cls.attribute
+      as keys in the value dict and using synchronize_session='expire'
+      ('fetch' in 0.6).
+
+    .. change::
+        :tags: sql
+        :tickets: 1603
+
+      Fixed bug in two-phase transaction whereby commit() method
+      didn't set the full state which allows subsequent close()
+      call to succeed.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed the "numeric" paramstyle, which apparently is the
+      default paramstyle used by Informixdb.
+
+    .. change::
+        :tags: sql
+        :tickets: 1574
+
+      Repeat expressions in the columns clause of a select
+      are deduped based on the identity of each clause element,
+      not the actual string.  This allows positional
+      elements to render correctly even if they all render
+      identically, such as "qmark" style bind parameters.
+
+    .. change::
+        :tags: sql
+        :tickets: 1632
+
+      The cursor associated with connection pool connections
+      (i.e. _CursorFairy) now proxies `__iter__()` to the
+      underlying cursor correctly.
+
+    .. change::
+        :tags: sql
+        :tickets: 1556
+
+      types now support an "affinity comparison" operation, i.e.
+      that an Integer/SmallInteger are "compatible", or
+      a Text/String, PickleType/Binary, etc.  Part of.
+
+    .. change::
+        :tags: sql
+        :tickets: 1641
+
+      Fixed bug preventing alias() of an alias() from being
+      cloned or adapted (occurs frequently in ORM operations).
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1439
+
+      sqlite dialect properly generates CREATE INDEX for a table
+      that is in an alternate schema.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1085
+
+      Added support for reflecting the DOUBLE PRECISION type,
+      via a new postgres.PGDoublePrecision object.
+      This is postgresql.DOUBLE_PRECISION in 0.6.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 460
+
+      Added support for reflecting the INTERVAL YEAR TO MONTH
+      and INTERVAL DAY TO SECOND syntaxes of the INTERVAL
+      type.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1576
+
+      Corrected the "has_sequence" query to take current schema,
+      or explicit sequence-stated schema, into account.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1611
+
+      Fixed the behavior of extract() to apply operator
+      precedence rules to the "::" operator when applying
+      the "timestamp" cast - ensures proper parenthesization.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1561
+
+      Changed the name of TrustedConnection to
+      Trusted_Connection when constructing pyodbc connect
+      arguments
+
+    .. change::
+        :tags: oracle
+        :tickets: 1637
+
+      The "table_names" dialect function, used by MetaData
+      .reflect(), omits "index overflow tables", a system
+      table generated by Oracle when "index only tables"
+      with overflow are used.  These tables aren't accessible
+      via SQL and can't be reflected.
+
+    .. change::
+        :tags: ext
+        :tickets: 1570, 1523
+
+      A column can be added to a joined-table declarative
+      superclass after the class has been constructed
+      (i.e. via class-level attribute assignment), and
+      the column will be propagated down to
+      subclasses.  This is the reverse
+      situation as that of, fixed in 0.5.6.
+
+    .. change::
+        :tags: ext
+        :tickets: 1491
+
+      Fixed a slight inaccuracy in the sharding example.
+      Comparing equivalence of columns in the ORM is best
+      accomplished using col1.shares_lineage(col2).
+
+    .. change::
+        :tags: ext
+        :tickets: 1606
+
+      Removed unused `load()` method from ShardedQuery.
+
+.. changelog::
+    :version: 0.5.6
+    :released: Sat Sep 12 2009
+
+    .. change::
+        :tags: orm
+        :tickets: 1300
+
+      Fixed bug whereby inheritance discriminator part of a
+      composite primary key would fail on updates.
+      Continuation of.
+
+    .. change::
+        :tags: orm
+        :tickets: 1507
+
+      Fixed bug which disallowed one side of a many-to-many
+      bidirectional reference to declare itself as "viewonly"
+
+    .. change::
+        :tags: orm
+        :tickets: 1526
+
+      Added an assertion that prevents a @validates function
+      or other AttributeExtension from loading an unloaded
+      collection such that internal state may be corrupted.
+
+    .. change::
+        :tags: orm
+        :tickets: 1519
+
+      Fixed bug which prevented two entities from mutually
+      replacing each other's primary key values within a single
+      flush() for some orderings of operations.
+
+    .. change::
+        :tags: orm
+        :tickets: 1485
+
+      Fixed an obscure issue whereby a joined-table subclass
+      with a self-referential eager load on the base class
+      would populate the related object's "subclass" table with
+      data from the "subclass" table of the parent.
+
+    .. change::
+        :tags: orm
+        :tickets: 1477
+
+      relations() now have greater ability to be "overridden",
+      meaning a subclass that explicitly specifies a relation()
+      overriding that of the parent class will be honored
+      during a flush.  This is currently to support
+      many-to-many relations from concrete inheritance setups.
+      Outside of that use case, YMMV.
+
+    .. change::
+        :tags: orm
+        :tickets: 1483
+
+      Squeezed a few more unnecessary "lazy loads" out of
+      relation().  When a collection is mutated, many-to-one
+      backrefs on the other side will not fire off to load
+      the "old" value, unless "single_parent=True" is set.
+      A direct assignment of a many-to-one still loads
+      the "old" value in order to update backref collections
+      on that value, which may be present in the session
+      already, thus maintaining the 0.5 behavioral contract.
+
+    .. change::
+        :tags: orm
+        :tickets: 1480
+
+      Fixed bug whereby a load/refresh of joined table
+      inheritance attributes which were based on
+      column_property() or similar would fail to evaluate.
+
+    .. change::
+        :tags: orm
+        :tickets: 1488
+
+      Improved support for MapperProperty objects overriding
+      that of an inherited mapper for non-concrete
+      inheritance setups - attribute extensions won't randomly
+      collide with each other.
+
+    .. change::
+        :tags: orm
+        :tickets: 1487
+
+      UPDATE and DELETE do not support ORDER BY, LIMIT, OFFSET,
+      etc. in standard SQL.  Query.update() and Query.delete()
+      now raise an exception if any of limit(), offset(),
+      order_by(), group_by(), or distinct() have been
+      called.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added AttributeExtension to sqlalchemy.orm.__all__
+
+    .. change::
+        :tags: orm
+        :tickets: 1476
+
+      Improved error message when query() is called with
+      a non-SQL /entity expression.
+
+    .. change::
+        :tags: orm
+        :tickets: 1440
+
+      Using False or 0 as a polymorphic discriminator now
+      works on the base class as well as a subclass.
+
+    .. change::
+        :tags: orm
+        :tickets: 1424
+
+      Added enable_assertions(False) to Query which disables
+      the usual assertions for expected state - used
+      by Query subclasses to engineer custom state..  See
+      http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PreFilteredQuery
+      for an example.
+
+    .. change::
+        :tags: orm
+        :tickets: 1501
+
+      Fixed recursion issue which occured if a mapped object's
+      `__len__()` or `__nonzero__()` method resulted in state
+      changes.
+
+    .. change::
+        :tags: orm
+        :tickets: 1506
+
+      Fixed incorrect exception raise in
+      Weak/StrongIdentityMap.add()
+
+    .. change::
+        :tags: orm
+        :tickets: 1522
+
+      Fixed the error message for "could not find a FROM clause"
+      in query.join() which would fail to issue correctly
+      if the query was against a pure SQL construct.
+
+    .. change::
+        :tags: orm
+        :tickets: 1486
+
+      Fixed a somewhat hypothetical issue which would result
+      in the wrong primary key being calculated for a mapper
+      using the old polymorphic_union function - but this
+      is old stuff.
+
+    .. change::
+        :tags: sql
+        :tickets: 1373
+
+      Fixed column.copy() to copy defaults and onupdates.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed a bug in extract() introduced in 0.5.4 whereby
+      the string "field" argument was getting treated as a
+      ClauseElement, causing various errors within more
+      complex SQL transformations.
+
+    .. change::
+        :tags: sql
+        :tickets: 1420
+
+      Unary expressions such as DISTINCT propagate their
+      type handling to result sets, allowing conversions like
+      unicode and such to take place.
+
+    .. change::
+        :tags: sql
+        :tickets: 1482
+
+      Fixed bug in Table and Column whereby passing empty
+      dict for "info" argument would raise an exception.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1309
+
+      Backported 0.6 fix for Oracle alias names not getting
+      truncated.
+
+    .. change::
+        :tags: ext
+        :tickets: 1446
+
+      The collection proxies produced by associationproxy are now
+      pickleable.  A user-defined proxy_factory however
+      is still not pickleable unless it defines __getstate__
+      and __setstate__.
+
+    .. change::
+        :tags: ext
+        :tickets: 1468
+
+      Declarative will raise an informative exception if
+      __table_args__ is passed as a tuple with no dict argument.
+      Improved documentation.
+
+    .. change::
+        :tags: ext
+        :tickets: 1527
+
+      Table objects declared in the MetaData can now be used
+      in string expressions sent to primaryjoin/secondaryjoin/
+      secondary - the name is pulled from the MetaData of the
+      declarative base.
+
+    .. change::
+        :tags: ext
+        :tickets: 1523
+
+      A column can be added to a joined-table subclass after
+      the class has been constructed (i.e. via class-level
+      attribute assignment).  The column is added to the underlying
+      Table as always, but now the mapper will rebuild its
+      "join" to include the new column, instead of raising
+      an error about "no such column, use column_property()
+      instead".
+
+    .. change::
+        :tags: test
+        :tickets: 
+
+      Added examples into the test suite so they get exercised
+      regularly and cleaned up a couple deprecation warnings.
+
+.. changelog::
+    :version: 0.5.5
+    :released: Mon Jul 13 2009
+
+    .. change::
+        :tags: general
+        :tickets: 970
+
+      unit tests have been migrated from unittest to nose.  See
+      README.unittests for information on how to run the tests.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The "foreign_keys" argument of relation() will now propagate
+      automatically to the backref in the same way that primaryjoin
+      and secondaryjoin do.  For the extremely rare use case where
+      the backref of a relation() has intentionally different
+      "foreign_keys" configured, both sides now need to be
+      configured explicity (if they do in fact require this setting,
+      see the next note...).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      ...the only known (and really, really rare) use case where a
+      different foreign_keys setting was used on the
+      forwards/backwards side, a composite foreign key that
+      partially points to its own columns, has been enhanced such
+      that the fk->itself aspect of the relation won't be used to
+      determine relation direction.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session.mapper is now *deprecated*.
+      
+      Call session.add() if you'd like a free-standing object to be
+      part of your session.  Otherwise, a DIY version of
+      Session.mapper is now documented at
+      http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
+      The method will remain deprecated throughout 0.6.
+
+    .. change::
+        :tags: orm
+        :tickets: 1431
+
+      Fixed Query being able to join() from individual columns of a
+      joined-table subclass entity, i.e.  query(SubClass.foo,
+      SubcClass.bar).join(<anything>).  In most cases, an error
+      "Could not find a FROM clause to join from" would be
+      raised. In a few others, the result would be returned in terms
+      of the base class rather than the subclass - so applications
+      which relied on this erroneous result need to be
+      adjusted.
+
+    .. change::
+        :tags: orm
+        :tickets: 1461
+
+      Fixed a bug involving contains_eager(), which would apply
+      itself to a secondary (i.e. lazy) load in a particular rare
+      case, producing cartesian products.  improved the targeting of
+      query.options() on secondary loads overall.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug introduced in 0.5.4 whereby Composite types fail
+      when default-holding columns are flushed.
+
+    .. change::
+        :tags: orm
+        :tickets: 1426
+
+      Fixed another 0.5.4 bug whereby mutable attributes
+      (i.e. PickleType) wouldn't be deserialized correctly when the
+      whole object was serialized.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug whereby session.is_modified() would raise an
+      exception if any synonyms were in use.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed potential memory leak whereby previously pickled objects
+      placed back in a session would not be fully garbage collected
+      unless the Session were explicitly closed out.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug whereby list-based attributes, like pickletype and
+      PGArray, failed to be merged() properly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Repaired non-working attributes.set_committed_value function.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Trimmed the pickle format for InstanceState which should
+      further reduce the memory footprint of pickled instances.  The
+      format should be backwards compatible with that of 0.5.4 and
+      previous.
+
+    .. change::
+        :tags: orm
+        :tickets: 1463
+
+      sqlalchemy.orm.join and sqlalchemy.orm.outerjoin are now
+      added to __all__ in sqlalchemy.orm.*.
+
+    .. change::
+        :tags: orm
+        :tickets: 1458
+
+      Fixed bug where Query exception raise would fail when
+      a too-short composite primary key value were passed to
+      get().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Removed an obscure feature of execute() (including connection,
+      engine, Session) whereby a bindparam() construct can be sent
+      as a key to the params dictionary.  This usage is undocumented
+      and is at the core of an issue whereby the bindparam() object
+      created implicitly by a text() construct may have the same
+      hash value as a string placed in the params dictionary and may
+      result in an inappropriate match when computing the final bind
+      parameters.  Internal checks for this condition would add
+      significant latency to the critical task of parameter
+      rendering, so the behavior is removed.  This is a backwards
+      incompatible change for any application that may have been
+      using this feature, however the feature has never been
+      documented.
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 
+
+      Implemented recreate() for StaticPool.
+
+.. changelog::
+    :version: 0.5.4p2
+    :released: Tue May 26 2009
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Repaired the printing of SQL exceptions which are not
+      based on parameters or are not executemany() style.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Deprecated the hardcoded TIMESTAMP function, which when
+      used as func.TIMESTAMP(value) would render "TIMESTAMP value".
+      This breaks on some platforms as PostgreSQL doesn't allow
+      bind parameters to be used in this context.  The hard-coded
+      uppercase is also inappropriate and there's lots of other
+      PG casts that we'd need to support.  So instead, use
+      text constructs i.e. select(["timestamp '12/05/09'"]).
+
+.. changelog::
+    :version: 0.5.4p1
+    :released: Mon May 18 2009
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed an attribute error introduced in 0.5.4 which would
+      occur when merge() was used with an incomplete object.
+
+.. changelog::
+    :version: 0.5.4
+    :released: Sun May 17 2009
+
+    .. change::
+        :tags: orm
+        :tickets: 1398
+
+      Significant performance enhancements regarding Sessions/flush()
+      in conjunction with large mapper graphs, large numbers of
+      objects:
+      
+      - Removed all* O(N) scanning behavior from the flush() process,
+        i.e. operations that were scanning the full session,
+        including an extremely expensive one that was erroneously
+        assuming primary key values were changing when this
+        was not the case.
+      
+        * one edge case remains which may invoke a full scan,
+          if an existing primary key attribute is modified
+          to a new value.
+      
+      - The Session's "weak referencing" behavior is now *full* -
+        no strong references whatsoever are made to a mapped object
+        or related items/collections in its __dict__.  Backrefs and
+        other cycles in objects no longer affect the Session's ability
+        to lose all references to unmodified objects.  Objects with
+        pending changes still are maintained strongly until flush.
+       
+      
+        The implementation also improves performance by moving
+        the "resurrection" process of garbage collected items
+        to only be relevant for mappings that map "mutable"
+        attributes (i.e. PickleType, composite attrs).  This removes
+        overhead from the gc process and simplifies internal
+        behavior.
+      
+        If a "mutable" attribute change is the sole change on an object
+        which is then dereferenced, the mapper will not have access to
+        other attribute state when the UPDATE is issued.  This may present
+        itself differently to some MapperExtensions.
+      
+        The change also affects the internal attribute API, but not
+        the AttributeExtension interface nor any of the publically
+        documented attribute functions.
+      
+      - The unit of work no longer genererates a graph of "dependency"
+        processors for the full graph of mappers during flush(), instead
+        creating such processors only for those mappers which represent
+        objects with pending changes.  This saves a tremendous number
+        of method calls in the context of a large interconnected
+        graph of mappers.
+      
+      - Cached a wasteful "table sort" operation that previously
+        occured multiple times per flush, also removing significant
+        method call count from flush().
+      
+      - Other redundant behaviors have been simplified in
+        mapper._save_obj().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Modified query_cls on DynamicAttributeImpl to accept a full
+      mixin version of the AppenderQuery, which allows subclassing
+      the AppenderMixin.
+
+    .. change::
+        :tags: orm
+        :tickets: 1300
+
+      The "polymorphic discriminator" column may be part of a
+      primary key, and it will be populated with the correct
+      discriminator value.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed the evaluator not being able to evaluate IS NULL clauses.
+
+    .. change::
+        :tags: orm
+        :tickets: 1352
+
+      Fixed the "set collection" function on "dynamic" relations to
+      initiate events correctly.  Previously a collection could only
+      be assigned to a pending parent instance, otherwise modified
+      events would not be fired correctly.  Set collection is now
+      compatible with merge(), fixes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Allowed pickling of PropertyOption objects constructed with
+      instrumented descriptors; previously, pickle errors would occur
+      when pickling an object which was loaded with a descriptor-based
+      option, such as query.options(eagerload(MyClass.foo)).
+
+    .. change::
+        :tags: orm
+        :tickets: 1357
+
+      Lazy loader will not use get() if the "lazy load" SQL clause
+      matches the clause used by get(), but contains some parameters
+      hardcoded.  Previously the lazy strategy would fail with the
+      get().  Ideally get() would be used with the hardcoded
+      parameters but this would require further development.
+
+    .. change::
+        :tags: orm
+        :tickets: 1391
+
+      MapperOptions and other state associated with query.options()
+      is no longer bundled within callables associated with each
+      lazy/deferred-loading attribute during a load.
+      The options are now associated with the instance's
+      state object just once when it's populated.  This removes
+      the need in most cases for per-instance/attribute loader
+      objects, improving load speed and memory overhead for
+      individual instances.
+
+    .. change::
+        :tags: orm
+        :tickets: 1360
+
+      Fixed another location where autoflush was interfering
+      with session.merge().  autoflush is disabled completely
+      for the duration of merge() now.
+
+    .. change::
+        :tags: orm
+        :tickets: 1406
+
+      Fixed bug which prevented "mutable primary key" dependency
+      logic from functioning properly on a one-to-one
+      relation().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in relation(), introduced in 0.5.3,
+      whereby a self referential relation
+      from a base class to a joined-table subclass would
+      not configure correctly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed obscure mapper compilation issue when inheriting
+      mappers are used which would result in un-initialized
+      attributes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed documentation for session weak_identity_map -
+      the default value is True, indicating a weak
+      referencing map in use.
+
+    .. change::
+        :tags: orm
+        :tickets: 1376
+
+      Fixed a unit of work issue whereby the foreign
+      key attribute on an item contained within a collection
+      owned by an object being deleted would not be set to
+      None if the relation() was self-referential.
+
+    .. change::
+        :tags: orm
+        :tickets: 1378
+
+      Fixed Query.update() and Query.delete() failures with eagerloaded
+      relations.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      It is now an error to specify both columns of a binary primaryjoin
+      condition in the foreign_keys or remote_side collection.  Whereas
+      previously it was just nonsensical, but would succeed in a
+      non-deterministic way.
+
+    .. change::
+        :tags: ticket: 594, 1341, schema
+        :tickets: 
+
+      Added a quote_schema() method to the IdentifierPreparer class
+      so that dialects can override how schemas get handled. This
+      enables the MSSQL dialect to treat schemas as multipart
+      identifiers, such as 'database.owner'.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Back-ported the "compiler" extension from SQLA 0.6.  This
+      is a standardized interface which allows the creation of custom
+      ClauseElement subclasses and compilers.  In particular it's
+      handy as an alternative to text() when you'd like to
+      build a construct that has database-specific compilations.
+      See the extension docs for details.
+
+    .. change::
+        :tags: sql
+        :tickets: 1413
+
+      Exception messages are truncated when the list of bound
+      parameters is larger than 10, preventing enormous
+      multi-page exceptions from filling up screens and logfiles
+      for large executemany() statements.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      ``sqlalchemy.extract()`` is now dialect sensitive and can
+      extract components of timestamps idiomatically across the
+      supported databases, including SQLite.
+
+    .. change::
+        :tags: sql
+        :tickets: 1353
+
+      Fixed __repr__() and other _get_colspec() methods on
+      ForeignKey constructed from __clause_element__() style
+      construct (i.e. declarative columns).
+
+    .. change::
+        :tags: mysql
+        :tickets: 1405
+
+      Reflecting a FOREIGN KEY construct will take into account
+      a dotted schema.tablename combination, if the foreign key
+      references a table in a remote schema.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Modified how savepoint logic works to prevent it from
+      stepping on non-savepoint oriented routines. Savepoint
+      support is still very experimental.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1310
+
+      Added in reserved words for MSSQL that covers version 2008
+      and all prior versions.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1343
+
+      Corrected problem with information schema not working with a
+      binary collation based database. Cleaned up information schema
+      since it is only used by mssql now.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1402
+
+      Corrected the SLBoolean type so that it properly treats only 1
+      as True.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1273
+
+      Corrected the float type so that it correctly maps to a
+      SLFloat type when being reflected.
+
+    .. change::
+        :tags: extensions
+        :tickets: 1379
+
+      Fixed adding of deferred or other column properties to a
+      declarative class.
+
+.. changelog::
+    :version: 0.5.3
+    :released: Tue Mar 24 2009
+
+    .. change::
+        :tags: orm
+        :tickets: 1315
+
+      The "objects" argument to session.flush() is deprecated.
+      State which represents the linkage between a parent and
+      child object does not support "flushed" status on
+      one side of the link and not the other, so supporting
+      this operation leads to misleading results.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query now implements __clause_element__() which produces
+      its selectable, which means a Query instance can be accepted
+      in many SQL expressions, including col.in_(query),
+      union(query1, query2), select([foo]).select_from(query),
+      etc.
+
+    .. change::
+        :tags: orm
+        :tickets: 1337
+
+      Query.join() can now construct multiple FROM clauses, if
+      needed.  Such as, query(A, B).join(A.x).join(B.y)
+      might say SELECT A.*, B.* FROM A JOIN X, B JOIN Y.
+      Eager loading can also tack its joins onto those
+      multiple FROM clauses.
+
+    .. change::
+        :tags: orm
+        :tickets: 1347
+
+      Fixed bug in dynamic_loader() where append/remove events
+      after construction time were not being propagated to the
+      UOW to pick up on flush().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug where column_prefix wasn't being checked before
+      not mapping an attribute that already had class-level
+      name present.
+
+    .. change::
+        :tags: orm
+        :tickets: 1315
+
+      a session.expire() on a particular collection attribute
+      will clear any pending backref additions as well, so that
+      the next access correctly returns only what was present
+      in the database.  Presents some degree of a workaround for, although we are considering removing the
+      flush([objects]) feature altogether.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session.scalar() now converts raw SQL strings to text()
+      the same way Session.execute() does and accepts same
+      alternative **kw args.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      improvements to the "determine direction" logic of
+      relation() such that the direction of tricky situations
+      like mapper(A.join(B)) -> relation-> mapper(B) can be
+      determined.
+
+    .. change::
+        :tags: orm
+        :tickets: 1306
+
+      When flushing partial sets of objects using session.flush([somelist]),
+      pending objects which remain pending after the operation won't
+      inadvertently be added as persistent.
+
+    .. change::
+        :tags: orm
+        :tickets: 1314
+
+      Added "post_configure_attribute" method to InstrumentationManager,
+      so that the "listen_for_events.py" example works again.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a forward and complementing backwards reference which are both
+      of the same direction, i.e. ONETOMANY or MANYTOONE,
+      is now detected, and an error message is raised.
+      Saves crazy CircularDependencyErrors later on.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bugs in Query regarding simultaneous selection of
+      multiple joined-table inheritance entities with common base
+      classes:
+      
+      - previously the adaption applied to "B" on
+        "A JOIN B" would be erroneously partially applied
+        to "A".
+      
+      - comparisons on relations (i.e. A.related==someb)
+        were not getting adapted when they should.
+      
+      - Other filterings, like
+        query(A).join(A.bs).filter(B.foo=='bar'), were erroneously
+        adapting "B.foo" as though it were an "A".
+
+    .. change::
+        :tags: orm
+        :tickets: 1325
+
+      Fixed adaptation of EXISTS clauses via any(), has(), etc.
+      in conjunction with an aliased object on the left and
+      of_type() on the right.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added an attribute helper method ``set_committed_value`` in
+      sqlalchemy.orm.attributes.  Given an object, attribute name,
+      and value, will set the value on the object as part of its
+      "committed" state, i.e. state that is understood to have
+      been loaded from the database.   Helps with the creation of
+      homegrown collection loaders and such.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query won't fail with weakref error when a non-mapper/class
+      instrumented descriptor is passed, raises
+      "Invalid column expession".
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.group_by() properly takes into account aliasing applied
+      to the FROM clause, such as with select_from(), using
+      with_polymorphic(), or using from_self().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      An alias() of a select() will convert to a "scalar subquery"
+      when used in an unambiguously scalar context, i.e. it's used
+      in a comparison operation.  This applies to
+      the ORM when using query.subquery() as well.
+
+    .. change::
+        :tags: sql
+        :tickets: 1302
+
+      Fixed missing _label attribute on Function object, others
+      when used in a select() with use_labels (such as when used
+      in an ORM column_property()).
+
+    .. change::
+        :tags: sql
+        :tickets: 1309
+
+      anonymous alias names now truncate down to the max length
+      allowed by the dialect.  More significant on DBs like
+      Oracle with very small character limits.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the __selectable__() interface has been replaced entirely
+      by __clause_element__().
+
+    .. change::
+        :tags: sql
+        :tickets: 1299
+
+      The per-dialect cache used by TypeEngine to cache
+      dialect-specific types is now a WeakKeyDictionary.
+      This to prevent dialect objects from
+      being referenced forever for an application that
+      creates an arbitrarily large number of engines
+      or dialects.   There is a small performance penalty
+      which will be resolved in 0.6.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      Fixed SQLite reflection methods so that non-present
+      cursor.description, which triggers an auto-cursor
+      close, will be detected so that no results doesn't
+      fail on recent versions of pysqlite which raise
+      an error when fetchone() called with no rows present.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Index reflection won't fail when an index with
+      multiple expressions is encountered.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1327
+
+      Added PGUuid and PGBit types to
+      sqlalchemy.databases.postgres.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1327
+
+      Refection of unknown PG types won't crash when those
+      types are specified within a domain.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Preliminary support for pymssql 1.0.1
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Corrected issue on mssql where max_identifier_length was
+      not being respected.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      Fixed a recursive pickling issue in serializer, triggered
+      by an EXISTS or other embedded FROM construct.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      Declarative locates the "inherits" class using a search
+      through __bases__, to skip over mixins that are local
+      to subclasses.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      Declarative figures out joined-table inheritance primary join
+      condition even if "inherits" mapper argument is given
+      explicitly.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      Declarative will properly interpret the "foreign_keys" argument
+      on a backref() if it's a string.
+
+    .. change::
+        :tags: extensions
+        :tickets: 
+
+      Declarative will accept a table-bound column as a property
+      when used in conjunction with __table__, if the column is already
+      present in __table__.  The column will be remapped to the given
+      key the same way as when added to the mapper() properties dict.
+
+.. changelog::
+    :version: 0.5.2
+    :released: Sat Jan 24 2009
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Further refined 0.5.1's warning about delete-orphan cascade
+      placed on a many-to-many relation.   First, the bad news:
+      the warning will apply to both many-to-many as well as
+      many-to-one relations.  This is necessary since in both
+      cases, SQLA does not scan the full set of potential parents
+      when determining "orphan" status - for a persistent object
+      it only detects an in-python de-association event to establish
+      the object as an "orphan".  Next, the good news: to support
+      one-to-one via a foreign key or assocation table, or to
+      support one-to-many via an association table, a new flag
+      single_parent=True may be set which indicates objects
+      linked to the relation are only meant to have a single parent.
+      The relation will raise an error if multiple parent-association
+      events occur within Python.
+
+    .. change::
+        :tags: orm
+        :tickets: 1292
+
+      Adjusted the attribute instrumentation change from 0.5.1 to
+      fully establish instrumentation for subclasses where the mapper
+      was created after the superclass had already been fully
+      instrumented.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in delete-orphan cascade whereby two one-to-one
+      relations from two different parent classes to the same target
+      class would prematurely expunge the instance.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed an eager loading bug whereby self-referential eager
+      loading would prevent other eager loads, self referential or not,
+      from joining to the parent JOIN properly.  Thanks to Alex K
+      for creating a great test case.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      session.expire() and related methods will not expire() unloaded
+      deferred attributes.  This prevents them from being needlessly
+      loaded when the instance is refreshed.
+
+    .. change::
+        :tags: orm
+        :tickets: 1293
+
+      query.join()/outerjoin() will now properly join an aliased()
+      construct to the existing left side, even if query.from_self()
+      or query.select_from(someselectable) has been called.
+
+    .. change::
+        :tags: sql
+        :tickets: 1284
+
+      Further fixes to the "percent signs and spaces in column/table
+       names" functionality.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1291
+
+      Restored convert_unicode handling. Results were being passed
+      on through without conversion.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1282
+
+      Really fixing the decimal handling this time..
+
+    .. change::
+        :tags: Ticket:1289, mssql
+        :tickets: 
+
+      Modified table reflection code to use only kwargs when
+      constructing tables.
+
+.. changelog::
+    :version: 0.5.1
+    :released: Sat Jan 17 2009
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Removed an internal join cache which could potentially leak
+      memory when issuing query.join() repeatedly to ad-hoc
+      selectables.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The "clear()", "save()", "update()", "save_or_update()"
+      Session methods have been deprecated, replaced by
+      "expunge_all()" and "add()".  "expunge_all()" has also
+      been added to ScopedSession.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Modernized the "no mapped table" exception and added a more
+      explicit __table__/__tablename__ exception to declarative.
+
+    .. change::
+        :tags: orm
+        :tickets: 1237
+
+      Concrete inheriting mappers now instrument attributes which
+      are inherited from the superclass, but are not defined for
+      the concrete mapper itself, with an InstrumentedAttribute that
+      issues a descriptive error when accessed.
+
+    .. change::
+        :tags: orm
+        :tickets: 1237, 781
+
+      Added a new `relation()` keyword `back_populates`. This
+      allows configuation of backreferences using explicit
+      relations. This is required when creating
+      bidirectional relations between a hierarchy of concrete
+      mappers and another class.
+
+    .. change::
+        :tags: orm
+        :tickets: 1237
+
+      Test coverage added for `relation()` objects specified on
+      concrete mappers.
+
+    .. change::
+        :tags: orm
+        :tickets: 1276
+
+      Query.from_self() as well as query.subquery() both disable
+      the rendering of eager joins inside the subquery produced.
+      The "disable all eager joins" feature is available publically
+      via a new query.enable_eagerloads() generative.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added a rudimental series of set operations to Query that
+      receive Query objects as arguments, including union(),
+      union_all(), intersect(), except_(), insertsect_all(),
+      except_all().  See the API documentation for
+      Query.union() for examples.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug that prevented Query.join() and eagerloads from
+      attaching to a query that selected from a union or aliased union.
+
+    .. change::
+        :tags: orm
+        :tickets: 1237
+
+      A short documentation example added for bidirectional
+      relations specified on concrete mappers.
+
+    .. change::
+        :tags: orm
+        :tickets: 1269
+
+      Mappers now instrument class attributes upon construction
+      with the final InstrumentedAttribute object which remains
+      persistent. The `_CompileOnAttr`/`__getattribute__()`
+      methodology has been removed. The net effect is that
+      Column-based mapped class attributes can now be used fully
+      at the class level without invoking a mapper compilation
+      operation, greatly simplifying typical usage patterns
+      within declarative.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      ColumnProperty (and front-end helpers such as ``deferred``) no
+      longer ignores unknown **keyword arguments.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed a bug with the unitofwork's "row switch" mechanism,
+      i.e. the conversion of INSERT/DELETE into an UPDATE, when
+      combined with joined-table inheritance and an object
+      which contained no defined values for the child table where
+      an UPDATE with no SET clause would be rendered.
+
+    .. change::
+        :tags: orm
+        :tickets: 1281
+
+      Using delete-orphan on a many-to-many relation is deprecated.
+      This produces misleading or erroneous results since SQLA does
+      not retrieve the full list of "parents" for m2m.  To get delete-orphan
+      behavior with an m2m table, use an explcit association class
+      so that the individual association row is treated as a parent.
+
+    .. change::
+        :tags: orm
+        :tickets: 1281
+
+      delete-orphan cascade always requires delete cascade.  Specifying
+      delete-orphan without delete now raises a deprecation warning.
+
+    .. change::
+        :tags: sql
+        :tickets: 1256
+
+      Improved the methodology to handling percent signs in column
+      names from.  Added more tests.  MySQL and
+      PostgreSQL dialects still do not issue correct CREATE TABLE
+      statements for identifiers with percent signs in them.
+
+    .. change::
+        :tags: schema
+        :tickets: 1214
+
+      Index now accepts column-oriented InstrumentedAttributes
+      (i.e. column-based mapped class attributes) as column
+      arguments.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Column with no name (as in declarative) won't raise a
+      NoneType error when it's string output is requsted
+      (such as in a stack trace).
+
+    .. change::
+        :tags: schema
+        :tickets: 1278
+
+      Fixed bug when overriding a Column with a ForeignKey
+      on a reflected table, where derived columns (i.e. the
+      "virtual" columns of a select, etc.) would inadvertently
+      call upon schema-level cleanup logic intended only
+      for the original column.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      Can now specify Column objects on subclasses which have no
+      table of their own (i.e. use single table inheritance).
+      The columns will be appended to the base table, but only
+      mapped by the subclass.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      For both joined and single inheriting subclasses, the subclass
+      will only map those columns which are already mapped on the
+      superclass and those explicit on the subclass.  Other
+      columns that are present on the `Table` will be excluded
+      from the mapping by default, which can be disabled
+      by passing a blank `exclude_properties` collection to the
+      `__mapper_args__`.  This is so that single-inheriting
+      classes which define their own columns are the only classes
+      to map those columns.   The effect is actually a more organized
+      mapping than you'd normally get with explicit `mapper()`
+      calls unless you set up the `exclude_properties` arguments
+      explicitly.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      It's an error to add new Column objects to a declarative class
+      that specified an existing table using __table__.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Added the missing keywords from MySQL 4.1 so they get escaped
+      properly.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1280
+
+      Corrected handling of large decimal values with more robust
+      tests. Removed string manipulation on floats.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Modified the do_begin handling in mssql to use the Cursor not
+      the Connection so it is DBAPI compatible.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Corrected SAVEPOINT support on adodbapi by changing the
+      handling of savepoint_release, which is unsupported on mssql.
+
+.. changelog::
+    :version: 0.5.0
+    :released: Tue Jan 06 2009
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      Documentation has been converted to Sphinx.  In particular,
+      the generated API documentation has been constructed into a
+      full blown "API Reference" section which organizes editorial
+      documentation combined with generated docstrings.  Cross
+      linking between sections and API docs are vastly improved, a
+      javascript-powered search feature is provided, and a full
+      index of all classes, functions and members is provided.
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      setup.py now imports setuptools only optionally.  If not
+      present, distutils is used.  The new "pip" installer is
+      recommended over easy_install as it installs in a more
+      simplified way.
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      added an extremely basic illustration of a PostGIS integration
+      to the examples folder.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.with_polymorphic() now accepts a third argument
+      "discriminator" which will replace the value of
+      mapper.polymorphic_on for that query.  Mappers themselves no
+      longer require polymorphic_on to be set, even if the mapper
+      has a polymorphic_identity.  When not set, the mapper will
+      load non-polymorphically by default. Together, these two
+      features allow a non-polymorphic concrete inheritance setup to
+      use polymorphic loading on a per-query basis, since concrete
+      setups are prone to many issues when used polymorphically in
+      all cases.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      dynamic_loader accepts a query_class= to customize the Query
+      classes used for both the dynamic collection and the queries
+      built from it.
+
+    .. change::
+        :tags: orm
+        :tickets: 1079
+
+      query.order_by() accepts None which will remove any pending
+      order_by state from the query, as well as cancel out any
+      mapper/relation configured ordering. This is primarily useful
+      for overriding the ordering specified on a dynamic_loader().
+
+    .. change::
+        :tags: sql
+        :tickets: 935
+
+      RowProxy objects can be used in place of dictionary arguments
+      sent to connection.execute() and friends.
+
+    .. change::
+        :tags: dialect
+        :tickets: 
+
+      Added a new description_encoding attribute on the dialect that
+      is used for encoding the column name when processing the
+      metadata. This usually defaults to utf-8.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Added in a new MSGenericBinary type. This maps to the Binary
+      type so it can implement the specialized behavior of treating
+      length specified types as fixed-width Binary types and
+      non-length types as an unbound variable length Binary type.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1249
+
+      Added in new types: MSVarBinary and MSImage.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Added in the MSReal, MSNText, MSSmallDateTime, MSTime,
+      MSDateTimeOffset, and MSDateTime2 types
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1266
+
+      Table reflection now stores the actual DefaultClause value for
+      the column.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      bugfixes, behavioral changes
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Exceptions raised during compile_mappers() are now preserved
+      to provide "sticky behavior" - if a hasattr() call on a
+      pre-compiled mapped attribute triggers a failing compile and
+      suppresses the exception, subsequent compilation is blocked
+      and the exception will be reiterated on the next compile()
+      call.  This issue occurs frequently when using declarative.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      property.of_type() is now recognized on a single-table
+      inheriting target, when used in the context of
+      prop.of_type(..).any()/has(), as well as
+      query.join(prop.of_type(...)).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.join() raises an error when the target of the join
+      doesn't match the property-based attribute - while it's
+      unlikely anyone is doing this, the SQLAlchemy author was
+      guilty of this particular loosey-goosey behavior.
+
+    .. change::
+        :tags: orm
+        :tickets: 1272
+
+      Fixed bug when using weak_instance_map=False where modified
+      events would not be intercepted for a flush().
+
+    .. change::
+        :tags: orm
+        :tickets: 1268
+
+      Fixed some deep "column correspondence" issues which could
+      impact a Query made against a selectable containing multiple
+      versions of the same table, as well as unions and similar
+      which contained the same table columns in different column
+      positions at different levels.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Custom comparator classes used in conjunction with
+      column_property(), relation() etc. can define new comparison
+      methods on the Comparator, which will become available via
+      __getattr__() on the InstrumentedAttribute.  In the case of
+      synonym() or comparable_property(), attributes are resolved
+      first on the user-defined descriptor, then on the user-defined
+      comparator.
+
+    .. change::
+        :tags: orm
+        :tickets: 976
+
+      Added ScopedSession.is_active accessor.
+
+    .. change::
+        :tags: orm
+        :tickets: 1262
+
+      Can pass mapped attributes and column objects as keys to
+      query.update({}).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Mapped attributes passed to the values() of an expression
+      level insert() or update() will use the keys of the mapped
+      columns, not that of the mapped attribute.
+
+    .. change::
+        :tags: orm
+        :tickets: 1242
+
+      Corrected problem with Query.delete() and Query.update() not
+      working properly with bind parameters.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.select_from(), from_statement() ensure that the given
+      argument is a FromClause, or Text/Select/Union, respectively.
+
+    .. change::
+        :tags: orm
+        :tickets: 1253
+
+      Query() can be passed a "composite" attribute as a column
+      expression and it will be expanded.  Somewhat related to.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query() is a little more robust when passed various column
+      expressions such as strings, clauselists, text() constructs
+      (which may mean it just raises an error more nicely).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      first() works as expected with Query.from_statement().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug introduced in 0.5rc4 involving eager loading not
+      functioning for properties which were added to a mapper
+      post-compile using add_property() or equivalent.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug where many-to-many relation() with viewonly=True
+      would not correctly reference the link between
+      secondary->remote.
+
+    .. change::
+        :tags: orm
+        :tickets: 1232
+
+      Duplicate items in a list-based collection will be maintained
+      when issuing INSERTs to a "secondary" table in a many-to-many
+      relation.  Assuming the m2m table has a unique or primary key
+      constraint on it, this will raise the expected constraint
+      violation instead of silently dropping the duplicate
+      entries. Note that the old behavior remains for a one-to-many
+      relation since collection entries in that case don't result in
+      INSERT statements and SQLA doesn't manually police
+      collections.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.add_column() can accept FromClause objects in the same
+      manner as session.query() can.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Comparison of many-to-one relation to NULL is properly
+      converted to IS NOT NULL based on not_().
+
+    .. change::
+        :tags: orm
+        :tickets: 1087
+
+      Extra checks added to ensure explicit
+      primaryjoin/secondaryjoin are ClauseElement instances, to
+      prevent more confusing errors later on.
+
+    .. change::
+        :tags: orm
+        :tickets: 1236
+
+      Improved mapper() check for non-class classes.
+
+    .. change::
+        :tags: orm
+        :tickets: 5051
+
+      comparator_factory argument is now documented and supported by
+      all MapperProperty types, including column_property(),
+      relation(), backref(), and synonym().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Changed the name of PropertyLoader to RelationProperty, to be
+      consistent with all the other names.  PropertyLoader is still
+      present as a synonym.
+
+    .. change::
+        :tags: orm
+        :tickets: 1099, 1228
+
+      fixed "double iter()" call causing bus errors in shard API,
+      removed errant result.close() left over from the 0.4
+      version.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      made Session.merge cascades not trigger autoflush.  Fixes
+      merged instances getting prematurely inserted with missing
+      values.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Two fixes to help prevent out-of-band columns from being
+      rendered in polymorphic_union inheritance scenarios (which
+      then causes extra tables to be rendered in the FROM clause
+      causing cartesian products):
+      
+        - improvements to "column adaption" for a->b->c inheritance
+          situations to better locate columns that are related to
+          one another via multiple levels of indirection, rather
+          than rendering the non-adapted column.
+      
+        - the "polymorphic discriminator" column is only rendered
+          for the actual mapper being queried against. The column
+          won't be "pulled in" from a subclass or superclass mapper
+          since it's not needed.
+
+    .. change::
+        :tags: orm
+        :tickets: 1072
+
+      Fixed shard_id argument on ShardedSession.execute().
+
+    .. change::
+        :tags: sql
+        :tickets: 1256
+
+      Columns can again contain percent signs within their
+      names.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      sqlalchemy.sql.expression.Function is now a public class.  It
+      can be subclassed to provide user-defined SQL functions in an
+      imperative style, including with pre-established behaviors.
+      The postgis.py example illustrates one usage of this.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      PickleType now favors == comparison by default, if the
+      incoming object (such as a dict) implements __eq__().  If the
+      object does not implement __eq__() and mutable=True, a
+      deprecation warning is raised.
+
+    .. change::
+        :tags: sql
+        :tickets: 1215
+
+      Fixed the import weirdness in sqlalchemy.sql to not export
+      __names__.
+
+    .. change::
+        :tags: sql
+        :tickets: 1238
+
+      Using the same ForeignKey object repeatedly raises an error
+      instead of silently failing later.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added NotImplementedError for params() method on
+      Insert/Update/Delete constructs.  These items currently don't
+      support this functionality, which also would be a little
+      misleading compared to values().
+
+    .. change::
+        :tags: sql
+        :tickets: 650
+
+      Reflected foreign keys will properly locate their referenced
+      column, even if the column was given a "key" attribute
+      different from the reflected name.  This is achieved via a new
+      flag on ForeignKey/ForeignKeyConstraint called "link_to_name",
+      if True means the given name is the referred-to column's name,
+      not its assigned key.
+
+    .. change::
+        :tags: sql
+        :tickets: 1253
+
+      select() can accept a ClauseList as a column in the same way
+      as a Table or other selectable and the interior expressions
+      will be used as column elements.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the "passive" flag on session.is_modified() is correctly
+      propagated to the attribute manager.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      union() and union_all() will not whack any order_by() that has
+      been applied to the select()s inside.  If you union() a
+      select() with order_by() (presumably to support LIMIT/OFFSET),
+      you should also call self_group() on it to apply parenthesis.
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 1246
+
+      Connection.invalidate() checks for closed status to avoid
+      attribute errors.
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 1094
+
+      NullPool supports reconnect on failure behavior.
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 799
+
+      Added a mutex for the initial pool creation when using
+      pool.manage(dbapi).  This prevents a minor case of "dogpile"
+      behavior which would otherwise occur upon a heavy load
+      startup.
+
+    .. change::
+        :tags: engine/pool
+        :tickets: 
+
+      _execute_clauseelement() goes back to being a private method.
+      Subclassing Connection is not needed now that ConnectionProxy
+      is available.
+
+    .. change::
+        :tags: documentation
+        :tickets: 1149, 1200
+
+      Tickets.
+
+    .. change::
+        :tags: documentation
+        :tickets: 
+
+      Added note about create_session() defaults.
+
+    .. change::
+        :tags: documentation
+        :tickets: 
+
+      Added section about metadata.reflect().
+
+    .. change::
+        :tags: documentation
+        :tickets: 
+
+      Updated `TypeDecorator` section.
+
+    .. change::
+        :tags: documentation
+        :tickets: 
+
+      Rewrote the "threadlocal" strategy section of the docs due to
+      recent confusion over this feature.
+
+    .. change::
+        :tags: documentation
+        :tickets: 
+
+      Removed badly out of date 'polymorphic_fetch' and
+      'select_table' docs from inheritance, reworked the second half
+      of "joined table inheritance".
+
+    .. change::
+        :tags: documentation
+        :tickets: 
+
+      Documented `comparator_factory` kwarg, added new doc section
+      "Custom Comparators".
+
+    .. change::
+        :tags: mssql
+        :tickets: 1254
+
+      Refactored the Date/Time types. The ``smalldatetime`` data
+      type no longer truncates to a date only, and will now be
+      mapped to the MSSmallDateTime type.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Corrected an issue with Numerics to accept an int.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Mapped ``char_length`` to the ``LEN()`` function.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      If an ``INSERT`` includes a subselect the ``INSERT`` is
+      converted from an ``INSERT INTO VALUES`` construct to a
+      ``INSERT INTO SELECT`` construct.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      If the column is part of a ``primary_key`` it will be ``NOT
+      NULL`` since MSSQL doesn't allow ``NULL`` in primary_key
+      columns.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1249
+
+      ``MSBinary`` now returns a ``BINARY`` instead of an
+      ``IMAGE``. This is a backwards incompatible change in that
+      ``BINARY`` is a fixed length data type whereas ``IMAGE`` is a
+      variable length data type.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1258
+
+      ``get_default_schema_name`` is now reflected from the database
+      based on the user's default schema. This only works with MSSQL
+      2005 and later.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1248
+
+      Added collation support through the use of a new collation
+      argument. This is supported on the following types: char,
+      nchar, varchar, nvarchar, text, ntext.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Changes to the connection string parameters favor DSN as the
+      default specification for pyodbc. See the mssql.py docstring
+      for detailed usage instructions.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Added experimental support of savepoints. It currently does
+      not work fully with sessions.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1243
+
+      Support for three levels of column nullability: NULL, NOT
+      NULL, and the database's configured default.  The default
+      Column configuration (nullable=True) will now generate NULL in
+      the DDL. Previously no specification was emitted and the
+      database default would take effect (usually NULL, but not
+      always).  To explicitly request the database default,
+      configure columns with nullable=None and no specification will
+      be emitted in DDL. This is backwards incompatible
+      behavior.
+
+    .. change::
+        :tags: postgres
+        :tickets: 1267
+
+      "%" signs in text() constructs are automatically escaped to
+      "%%".  Because of the backwards incompatible nature of this
+      change, a warning is emitted if '%%' is detected in the
+      string.
+
+    .. change::
+        :tags: postgres
+        :tickets: 
+
+      Calling alias.execute() in conjunction with
+      server_side_cursors won't raise AttributeError.
+
+    .. change::
+        :tags: postgres
+        :tickets: 714
+
+      Added Index reflection support to PostgreSQL, using a great
+      patch we long neglected, submitted by Ken
+      Kuhlman.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Adjusted the format of create_xid() to repair two-phase
+      commit.  We now have field reports of Oracle two-phase commit
+      working properly with this change.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1233
+
+      Added OracleNVarchar type, produces NVARCHAR2, and also
+      subclasses Unicode so that convert_unicode=True by default.
+      NVARCHAR2 reflects into this type automatically so these
+      columns pass unicode on a reflected table with no explicit
+      convert_unicode=True flags.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1265
+
+      Fixed bug which was preventing out params of certain types
+      from being received; thanks a ton to huddlej at wwu.edu !
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      "%" signs in text() constructs are automatically escaped to
+      "%%".  Because of the backwards incompatible nature of this
+      change, a warning is emitted if '%%' is detected in the
+      string.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1241
+
+      Fixed bug in exception raise when FK columns not present
+      during reflection.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Fixed bug involving reflection of a remote-schema table with a
+      foreign key ref to another table in that schema.
+
+    .. change::
+        :tags: associationproxy
+        :tickets: 
+
+      The association proxy properties are make themselves available
+      at the class level, e.g. MyClass.aproxy.  Previously this
+      evaluated to None.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      The full list of arguments accepted as string by backref()
+      includes 'primaryjoin', 'secondaryjoin', 'secondary',
+      'foreign_keys', 'remote_side', 'order_by'.
+
+.. changelog::
+    :version: 0.5.0rc4
+    :released: Fri Nov 14 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.count() has been enhanced to do the "right thing" in a
+      wider variety of cases. It can now count multiple-entity
+      queries, as well as column-based queries. Note that this means
+      if you say query(A, B).count() without any joining criterion,
+      it's going to count the cartesian product of A*B. Any query
+      which is against column-based entities will automatically
+      issue "SELECT count(1) FROM (SELECT...)" so that the real
+      rowcount is returned, meaning a query such as
+      query(func.count(A.name)).count() will return a value of one,
+      since that query would return one row.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Lots of performance tuning.  A rough guesstimate over various
+      ORM operations places it 10% faster over 0.5.0rc3, 25-30% over
+      0.4.8.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      bugfixes and behavioral changes
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      global "propigate"->"propagate" change.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Adjustments to the enhanced garbage collection on
+      InstanceState to better guard against errors due to lost
+      state.
+
+    .. change::
+        :tags: orm
+        :tickets: 1220
+
+      Query.get() returns a more informative error message when
+      executed against multiple entities.
+
+    .. change::
+        :tags: orm
+        :tickets: 1140, 1221
+
+      Restored NotImplementedError on Cls.relation.in_()
+
+    .. change::
+        :tags: orm
+        :tickets: 1226
+
+      Fixed PendingDeprecationWarning involving order_by parameter
+      on relation().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Removed the 'properties' attribute of the Connection object,
+      Connection.info should be used.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Restored "active rowcount" fetch before ResultProxy autocloses
+      the cursor.  This was removed in 0.5rc3.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Rearranged the `load_dialect_impl()` method in `TypeDecorator`
+      such that it will take effect even if the user-defined
+      `TypeDecorator` uses another `TypeDecorator` as its impl.
+
+    .. change::
+        :tags: access
+        :tickets: 
+
+      Added support for Currency type.
+
+    .. change::
+        :tags: access
+        :tickets: 1017
+
+      Functions were not return their result.
+
+    .. change::
+        :tags: access
+        :tickets: 1017
+
+      Corrected problem with joins. Access only support LEFT OUTER
+      or INNER not just JOIN by itself.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Lots of cleanup and fixes to correct problems with limit and
+      offset.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Correct situation where subqueries as part of a binary
+      expression need to be translated to use the IN and NOT IN
+      syntax.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1216
+
+      Fixed E Notation issue that prevented the ability to insert
+      decimal values less than 1E-6.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1217
+
+      Corrected problems with reflection when dealing with schemas,
+      particularly when those schemas are the default
+      schema.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Corrected problem with casting a zero length item to a
+      varchar. It now correctly adjusts the CAST.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      Can now use a custom "inherit_condition" in __mapper_args__
+      when using declarative.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      fixed string-based "remote_side", "order_by" and others not
+      propagating correctly when used in backref().
+
+.. changelog::
+    :version: 0.5.0rc3
+    :released: Fri Nov 07 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added two new hooks to SessionExtension: after_bulk_delete()
+      and after_bulk_update().  after_bulk_delete() is called after
+      a bulk delete() operation on a query. after_bulk_update() is
+      called after a bulk update() operation on a query.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      SQL compiler optimizations and complexity reduction. The call
+      count for compiling a typical select() construct is 20% less
+      versus 0.5.0rc2.
+
+    .. change::
+        :tags: sql
+        :tickets: 1211
+
+      Dialects can now generate label names of adjustable
+      length. Pass in the argument "label_length=<value>" to
+      create_engine() to adjust how many characters max will be
+      present in dynamically generated column labels, i.e.
+      "somecolumn AS somelabel". Any value less than 6 will result
+      in a label of minimal size, consisting of an underscore and a
+      numeric counter. The compiler uses the value of
+      dialect.max_identifier_length as a default.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      Added a new extension sqlalchemy.ext.serializer.  Provides
+      Serializer/Deserializer "classes" which mirror
+      Pickle/Unpickle, as well as dumps() and loads(). This
+      serializer implements an "external object" pickler which keeps
+      key context-sensitive objects, including engines, sessions,
+      metadata, Tables/Columns, and mappers, outside of the pickle
+      stream, and can later restore the pickle using any
+      engine/metadata/session provider. This is used not for
+      pickling regular object instances, which are pickleable
+      without any special logic, but for pickling expression objects
+      and full Query objects, such that all mapper/engine/session
+      dependencies can be restored at unpickle time.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Wrote a docstring for Oracle dialect. Apparently that Ohloh
+      "few source code comments" label is starting to sting :).
+
+    .. change::
+        :tags: oracle
+        :tickets: 536
+
+      Removed FIRST_ROWS() optimize flag when using LIMIT/OFFSET,
+      can be reenabled with optimize_limits=True create_engine()
+      flag.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      bugfixes and behavioral changes
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      "not equals" comparisons of simple many-to-one relation to an
+      instance will not drop into an EXISTS clause and will compare
+      foreign key columns instead.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Removed not-really-working use cases of comparing a collection
+      to an iterable. Use contains() to test for collection
+      membership.
+
+    .. change::
+        :tags: orm
+        :tickets: 1171
+
+      Improved the behavior of aliased() objects such that they more
+      accurately adapt the expressions generated, which helps
+      particularly with self-referential comparisons.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug involving primaryjoin/secondaryjoin conditions
+      constructed from class-bound attributes (as often occurs when
+      using declarative), which later would be inappropriately
+      aliased by Query, particularly with the various EXISTS based
+      comparators.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug when using multiple query.join() with an
+      aliased-bound descriptor which would lose the left alias.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Improved weakref identity map memory management to no longer
+      require mutexing, resurrects garbage collected instance on a
+      lazy basis for an InstanceState with pending changes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      InstanceState object now removes circular references to itself
+      upon disposal to keep it outside of cyclic garbage collection.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      relation() won't hide unrelated ForeignKey errors inside of
+      the "please specify primaryjoin" message when determining join
+      condition.
+
+    .. change::
+        :tags: orm
+        :tickets: 1218
+
+      Fixed bug in Query involving order_by() in conjunction with
+      multiple aliases of the same class (will add tests in)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      When using Query.join() with an explicit clause for the ON
+      clause, the clause will be aliased in terms of the left side
+      of the join, allowing scenarios like query(Source).
+      from_self().join((Dest, Source.id==Dest.source_id)) to work
+      properly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      polymorphic_union() function respects the "key" of each Column
+      if they differ from the column's name.
+
+    .. change::
+        :tags: orm
+        :tickets: 1183
+
+      Repaired support for "passive-deletes" on a many-to-one
+      relation() with "delete" cascade.
+
+    .. change::
+        :tags: orm
+        :tickets: 1213
+
+      Fixed bug in composite types which prevented a primary-key
+      composite type from being mutated.
+
+    .. change::
+        :tags: orm
+        :tickets: 1202
+
+      Added more granularity to internal attribute access, such that
+      cascade and flush operations will not initialize unloaded
+      attributes and collections, leaving them intact for a
+      lazy-load later on. Backref events still initialize attrbutes
+      and collections for pending instances.
+
+    .. change::
+        :tags: sql
+        :tickets: 1212
+
+      Simplified the check for ResultProxy "autoclose without
+      results" to be based solely on presence of
+      cursor.description. All the regexp-based guessing about
+      statements returning rows has been removed.
+
+    .. change::
+        :tags: sql
+        :tickets: 1194
+
+      Direct execution of a union() construct will properly set up
+      result-row processing.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The internal notion of an "OID" or "ROWID" column has been
+      removed. It's basically not used by any dialect, and the
+      possibility of its usage with psycopg2's cursor.lastrowid is
+      basically gone now that INSERT..RETURNING is available.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Removed "default_order_by()" method on all FromClause objects.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Repaired the table.tometadata() method so that a passed-in
+      schema argument is propagated to ForeignKey constructs.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Slightly changed behavior of IN operator for comparing to
+      empty collections. Now results in inequality comparison
+      against self. More portable, but breaks with stored procedures
+      that aren't pure functions.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Setting the auto_convert_lobs to False on create_engine() will
+      also instruct the OracleBinary type to return the cx_oracle
+      LOB object unchanged.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Fixed foreign key reflection in the edge case where a Table's
+      explicit schema= is the same as the schema (database) the
+      connection is attached to.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      No longer expects include_columns in table reflection to be
+      lower case.
+
+    .. change::
+        :tags: ext
+        :tickets: 1174
+
+      Fixed bug preventing declarative-bound "column" objects from
+      being used in column_mapped_collection().
+
+    .. change::
+        :tags: misc
+        :tickets: 1077
+
+      util.flatten_iterator() func doesn't interpret strings with
+      __iter__() methods as iterators, such as in pypy.
+
+.. changelog::
+    :version: 0.5.0rc2
+    :released: Sun Oct 12 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug involving read/write relation()s that contain
+      literal or other non-column expressions within their
+      primaryjoin condition equated to a foreign key column.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      "non-batch" mode in mapper(), a feature which allows mapper
+      extension methods to be called as each instance is
+      updated/inserted, now honors the insert order of the objects
+      given.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed RLock-related bug in mapper which could deadlock upon
+      reentrant mapper compile() calls, something that occurs when
+      using declarative constructs inside of ForeignKey objects.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      ScopedSession.query_property now accepts a query_cls factory,
+      overriding the session's configured query_cls.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed shared state bug interfering with ScopedSession.mapper's
+      ability to apply default __init__ implementations on object
+      subclasses.
+
+    .. change::
+        :tags: orm
+        :tickets: 1177
+
+      Fixed up slices on Query (i.e. query[x:y]) to work properly
+      for zero length slices, slices with None on either end.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added an example illustrating Celko's "nested sets" as a
+      SQLA mapping.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      contains_eager() with an alias argument works even when
+      the alias is embedded in a SELECT, as when sent to the
+      Query via query.select_from().
+
+    .. change::
+        :tags: orm
+        :tickets: 1180
+
+      contains_eager() usage is now compatible with a Query that
+      also contains a regular eager load and limit/offset, in that
+      the columns are added to the Query-generated subquery.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      session.execute() will execute a Sequence object passed to
+      it (regression from 0.4).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Removed the "raiseerror" keyword argument from object_mapper()
+      and class_mapper().  These functions raise in all cases
+      if the given class/instance is not mapped.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed session.transaction.commit() on a autocommit=False
+      session not starting a new transaction.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Some adjustments to Session.identity_map's weak referencing
+      behavior to reduce asynchronous GC side effects.
+
+    .. change::
+        :tags: orm
+        :tickets: 1182
+
+      Adjustment to Session's post-flush accounting of newly
+      "clean" objects to better protect against operating on
+      objects as they're asynchronously gc'ed.
+
+    .. change::
+        :tags: sql
+        :tickets: 1074
+
+      column.in_(someselect) can now be used as a columns-clause
+      expression without the subquery bleeding into the FROM clause
+
+    .. change::
+        :tags: sqlite
+        :tickets: 968
+
+      Overhauled SQLite date/time bind/result processing to use
+      regular expressions and format strings, rather than
+      strptime/strftime, to generically support pre-1900 dates,
+      dates with microseconds.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      String's (and Unicode's, UnicodeText's, etc.) convert_unicode
+      logic disabled in the sqlite dialect, to adjust for pysqlite
+      2.5.0's new requirement that only Python unicode objects are
+      accepted;
+      http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Temporary tables are now reflectable.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1187
+
+      Oracle will detect string-based statements which contain
+      comments at the front before a SELECT as SELECT statements.
+
+.. changelog::
+    :version: 0.5.0rc1
+    :released: Thu Sep 11 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query now has delete() and update(values) methods. This allows
+      to perform bulk deletes/updates with the Query object.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The RowTuple object returned by Query(*cols) now features
+      keynames which prefer mapped attribute names over column keys,
+      column keys over column names, i.e.  Query(Class.foo,
+      Class.bar) will have names "foo" and "bar" even if those are
+      not the names of the underlying Column objects.  Direct Column
+      objects such as Query(table.c.col) will return the "key"
+      attribute of the Column.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added scalar() and value() methods to Query, each return a
+      single scalar value.  scalar() takes no arguments and is
+      roughly equivalent to first()[0], value()
+      takes a single column expression and is roughly equivalent to
+      values(expr).next()[0].
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Improved the determination of the FROM clause when placing SQL
+      expressions in the query() list of entities.  In particular
+      scalar subqueries should not "leak" their inner FROM objects
+      out into the enclosing query.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Joins along a relation() from a mapped class to a mapped
+      subclass, where the mapped subclass is configured with single
+      table inheritance, will include an IN clause which limits the
+      subtypes of the joined class to those requested, within the ON
+      clause of the join.  This takes effect for eager load joins as
+      well as query.join().  Note that in some scenarios the IN
+      clause will appear in the WHERE clause of the query as well
+      since this discrimination has multiple trigger points.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      AttributeExtension has been refined such that the event
+      is fired before the mutation actually occurs.  Additionally,
+      the append() and set() methods must now return the given value,
+      which is used as the value to be used in the mutation operation.
+      This allows creation of validating AttributeListeners which
+      raise before the action actually occurs, and which can change
+      the given value into something else before its used.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      column_property(), composite_property(), and relation() now
+      accept a single or list of AttributeExtensions using the
+      "extension" keyword argument.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.order_by().get() silently drops the "ORDER BY" from
+      the query issued by GET but does not raise an exception.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added a Validator AttributeExtension, as well as a
+      @validates decorator which is used in a similar fashion
+      as @reconstructor, and marks a method as validating
+      one or more mapped attributes.
+
+    .. change::
+        :tags: orm
+        :tickets: 1140
+
+      class.someprop.in_() raises NotImplementedError pending the
+      implementation of "in_" for relation
+
+    .. change::
+        :tags: orm
+        :tickets: 1127
+
+      Fixed primary key update for many-to-many collections where
+      the collection had not been loaded yet
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug whereby deferred() columns with a group in conjunction
+      with an otherwise unrelated synonym() would produce
+      an AttributeError during deferred load.
+
+    .. change::
+        :tags: orm
+        :tickets: 1128
+
+      The before_flush() hook on SessionExtension takes place before
+      the list of new/dirty/deleted is calculated for the final
+      time, allowing routines within before_flush() to further
+      change the state of the Session before the flush proceeds.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The "extension" argument to Session and others can now
+      optionally be a list, supporting events sent to multiple
+      SessionExtension instances.  Session places SessionExtensions
+      in Session.extensions.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Reentrant calls to flush() raise an error.  This also serves
+      as a rudimentary, but not foolproof, check against concurrent
+      calls to Session.flush().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Improved the behavior of query.join() when joining to
+      joined-table inheritance subclasses, using explicit join
+      criteria (i.e. not on a relation).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      @orm.attributes.reconstitute and
+      MapperExtension.reconstitute have been renamed to
+      @orm.reconstructor and MapperExtension.reconstruct_instance
+
+    .. change::
+        :tags: orm
+        :tickets: 1129
+
+      Fixed @reconstructor hook for subclasses which inherit from a
+      base class.
+
+    .. change::
+        :tags: orm
+        :tickets: 1132
+
+      The composite() property type now supports a
+      __set_composite_values__() method on the composite class which
+      is required if the class represents state using attribute
+      names other than the column's keynames; default-generated
+      values now get populated properly upon flush.  Also,
+      composites with attributes set to None compare correctly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The 3-tuple of iterables returned by attributes.get_history()
+      may now be a mix of lists and tuples.  (Previously members
+      were always lists.)
+
+    .. change::
+        :tags: orm
+        :tickets: 1151
+
+      Fixed bug whereby changing a primary key attribute on an
+      entity where the attribute's previous value had been expired
+      would produce an error upon flush().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed custom instrumentation bug whereby get_instance_dict()
+      was not called for newly constructed instances not loaded
+      by the ORM.
+
+    .. change::
+        :tags: orm
+        :tickets: 1150
+
+      Session.delete() adds the given object to the session if
+      not already present.  This was a regression bug from 0.4.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The `echo_uow` flag on `Session` is deprecated, and unit-of-work
+      logging is now application-level only, not per-session level.
+
+    .. change::
+        :tags: orm
+        :tickets: 1153
+
+      Removed conflicting `contains()` operator from
+      `InstrumentedAttribute` which didn't accept `escape` kwaarg.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1161
+
+      Fixed bug whereby mapper couldn't initialize if a composite
+      primary key referenced another table that was not defined
+      yet.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      Fixed exception throw which would occur when string-based
+      primaryjoin condition was used in conjunction with backref.
+
+    .. change::
+        :tags: schema
+        :tickets: 1033
+
+      Added "sorted_tables" accessor to MetaData, which returns
+      Table objects sorted in order of dependency as a list.
+      This deprecates the MetaData.table_iterator() method.
+      The "reverse=False" keyword argument has also been
+      removed from util.sort_tables(); use the Python
+      'reversed' function to reverse the results.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      The 'length' argument to all Numeric types has been renamed
+      to 'scale'.  'length' is deprecated and is still accepted
+      with a warning.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Dropped 0.3-compatibility for user defined types
+      (convert_result_value, convert_bind_param).
+
+    .. change::
+        :tags: sql
+        :tickets: 1068
+
+      Temporarily rolled back the "ORDER BY" enhancement from.  This feature is on hold pending further
+      development.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The exists() construct won't "export" its contained list
+      of elements as FROM clauses, allowing them to be used more
+      effectively in the columns clause of a SELECT.
+
+    .. change::
+        :tags: sql
+        :tickets: 798
+
+      and_() and or_() now generate a ColumnElement, allowing
+      boolean expressions as result columns, i.e.
+      select([and_(1, 0)]).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Bind params now subclass ColumnElement which allows them to be
+      selectable by orm.query (they already had most ColumnElement
+      semantics).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added select_from() method to exists() construct, which becomes
+      more and more compatible with a regular select().
+
+    .. change::
+        :tags: sql
+        :tickets: 1160
+
+      Added func.min(), func.max(), func.sum() as "generic functions",
+      which basically allows for their return type to be determined
+      automatically.  Helps with dates on SQLite, decimal types,
+      others.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      added decimal.Decimal as an "auto-detect" type; bind parameters
+      and generic functions will set their type to Numeric when a
+      Decimal is used.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      The 'length' argument to MSInteger, MSBigInteger, MSTinyInteger,
+      MSSmallInteger and MSYear has been renamed to 'display_width'.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1146
+
+      Added MSMediumInteger type.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      the function func.utc_timestamp() compiles to UTC_TIMESTAMP, without
+      the parenthesis, which seem to get in the way when using in
+      conjunction with executemany().
+
+    .. change::
+        :tags: oracle
+        :tickets: 536
+
+      limit/offset no longer uses ROW NUMBER OVER to limit rows,
+      and instead uses subqueries in conjunction with a special
+      Oracle optimization comment.  Allows LIMIT/OFFSET to work
+      in conjunction with DISTINCT.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1155
+
+      has_sequence() now takes the current "schema" argument into
+      account
+
+    .. change::
+        :tags: oracle
+        :tickets: 1121
+
+      added BFILE to reflected type names
+
+.. changelog::
+    :version: 0.5.0beta3
+    :released: Mon Aug 04 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The "entity_name" feature of SQLAlchemy mappers has been
+      removed.  For rationale, see http://tinyurl.com/6nm2ne
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "autoexpire" flag on Session, sessionmaker(), and
+      scoped_session() has been renamed to "expire_on_commit".  It
+      does not affect the expiration behavior of rollback().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      fixed endless loop bug which could occur within a mapper's
+      deferred load of inherited attributes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a legacy-support flag "_enable_transaction_accounting" flag
+      added to Session which when False, disables all
+      transaction-level object accounting, including expire on
+      rollback, expire on commit, new/deleted list maintenance, and
+      autoflush on begin.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The 'cascade' parameter to relation() accepts None as a value,
+      which is equivalent to no cascades.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      A critical fix to dynamic relations allows the "modified"
+      history to be properly cleared after a flush().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      user-defined @properties on a class are detected and left in
+      place during mapper initialization.  This means that a
+      table-bound column of the same name will not be mapped at all
+      if a @property is in the way (and the column is not remapped
+      to a different name), nor will an instrumented attribute from
+      an inherited class be applied.  The same rules apply for names
+      excluded using the include_properties/exclude_properties
+      collections.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added a new SessionExtension hook called after_attach().  This
+      is called at the point of attachment for objects via add(),
+      add_all(), delete(), and merge().
+
+    .. change::
+        :tags: orm
+        :tickets: 1111
+
+      A mapper which inherits from another, when inheriting the
+      columns of its inherited mapper, will use any reassigned
+      property names specified in that inheriting mapper.
+      Previously, if "Base" had reassigned "base_id" to the name
+      "id", "SubBase(Base)" would still get an attribute called
+      "base_id".  This could be worked around by explicitly stating
+      the column in each submapper as well but this is fairly
+      unworkable and also impossible when using declarative.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed a series of potential race conditions in Session whereby
+      asynchronous GC could remove unmodified, no longer referenced
+      items from the session as they were present in a list of items
+      to be processed, typically during session.expunge_all() and
+      dependent methods.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Some improvements to the _CompileOnAttr mechanism which should
+      reduce the probability of "Attribute x was not replaced during
+      compile" warnings. (this generally applies to SQLA hackers,
+      like Elixir devs).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug whereby the "unsaved, pending instance" FlushError
+      raised for a pending orphan would not take superclass mappers
+      into account when generating the list of relations responsible
+      for the error.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      func.count() with no arguments renders as COUNT(*), equivalent
+      to func.count(text('*')).
+
+    .. change::
+        :tags: sql
+        :tickets: 1068
+
+      simple label names in ORDER BY expressions render as
+      themselves, and not as a re-statement of their corresponding
+      expression.  This feature is currently enabled only for
+      SQLite, MySQL, and PostgreSQL.  It can be enabled on other
+      dialects as each is shown to support this
+      behavior.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      Class-bound attributes sent as arguments to relation()'s
+      remote_side and foreign_keys parameters are now accepted,
+      allowing them to be used with declarative.  Additionally fixed
+      bugs involving order_by being specified as a class-bound
+      attribute in conjunction with eager loading.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      declarative initialization of Columns adjusted so that
+      non-renamed columns initialize in the same way as a non
+      declarative mapper.  This allows an inheriting mapper to set
+      up its same-named "id" columns in particular such that the
+      parent "id" column is favored over the child column, reducing
+      database round trips when this value is requested.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1110
+
+      Quoting of MSEnum values for use in CREATE TABLE is now
+      optional & will be quoted on demand as required.  (Quoting was
+      always optional for use with existing tables.)
+
+.. changelog::
+    :version: 0.5.0beta2
+    :released: Mon Jul 14 2008
+
+    .. change::
+        :tags: orm
+        :tickets: 870
+
+      In addition to expired attributes, deferred attributes also
+      load if their data is present in the result set.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      session.refresh() raises an informative error message if the
+      list of attributes does not include any column-based
+      attributes.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query() raises an informative error message if no columns or
+      mappers are specified.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      lazy loaders now trigger autoflush before proceeding.  This
+      allows expire() of a collection or scalar relation to function
+      properly in the context of autoflush.
+
+    .. change::
+        :tags: orm
+        :tickets: 887
+
+      column_property() attributes which represent SQL expressions
+      or columns that are not present in the mapped tables (such as
+      those from views) are automatically expired after an INSERT or
+      UPDATE, assuming they have not been locally modified, so that
+      they are refreshed with the most recent data upon access.
+
+    .. change::
+        :tags: orm
+        :tickets: 1082
+
+      Fixed explicit, self-referential joins between two
+      joined-table inheritance mappers when using query.join(cls,
+      aliased=True).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed query.join() when used in conjunction with a
+      columns-only clause and an SQL-expression ON clause in the
+      join.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The "allow_column_override" flag from mapper() has been
+      removed.  This flag is virtually always misunderstood.  Its
+      specific functionality is available via the
+      include_properties/exclude_properties mapper arguments.
+
+    .. change::
+        :tags: orm
+        :tickets: 1066
+
+      Repaired `__str__()` method on Query.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session.bind gets used as a default even when table/mapper
+      specific binds are defined.
+
+    .. change::
+        :tags: schema
+        :tickets: 1075
+
+      Added prefixes option to `Table` that accepts a list of
+      strings to insert after CREATE in the CREATE TABLE statement.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Unicode, UnicodeText types now set "assert_unicode" and
+      "convert_unicode" by default, but accept overriding
+      **kwargs for these values.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added new match() operator that performs a full-text search.
+      Supported on PostgreSQL, SQLite, MySQL, MS-SQL, and Oracle
+      backends.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1090
+
+      Modified SQLite's representation of "microseconds" to match
+      the output of str(somedatetime), i.e. in that the microseconds
+      are represented as fractional seconds in string format.  This
+      makes SQLA's SQLite date type compatible with datetimes that
+      were saved directly using Pysqlite (which just calls str()).
+      Note that this is incompatible with the existing microseconds
+      values in a SQLA 0.4 generated SQLite database file.
+      
+      To get the old behavior globally:
+      
+           from sqlalchemy.databases.sqlite import DateTimeMixin
+           DateTimeMixin.__legacy_microseconds__ = True
+      
+      To get the behavior on individual DateTime types:
+      
+            t = sqlite.SLDateTime()
+            t.__legacy_microseconds__ = True
+      
+      Then use "t" as the type on the Column.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      SQLite Date, DateTime, and Time types only accept Python
+      datetime objects now, not strings.  If you'd like to format
+      dates as strings yourself with SQLite, use a String type.  If
+      you'd like them to return datetime objects anyway despite
+      their accepting strings as input, make a TypeDecorator around
+      String - SQLA doesn't encourage this pattern.
+
+    .. change::
+        :tags: extensions
+        :tickets: 1096
+
+      Declarative supports a __table_args__ class variable, which is
+      either a dictionary, or tuple of the form (arg1, arg2, ...,
+      {kwarg1:value, ...}) which contains positional + kw arguments
+      to be passed to the Table constructor.
+
+.. changelog::
+    :version: 0.5.0beta1
+    :released: Thu Jun 12 2008
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The "__init__" trigger/decorator added by mapper now attempts
+      to exactly mirror the argument signature of the original
+      __init__.  The pass-through for '_sa_session' is no longer
+      implicit- you must allow for this keyword argument in your
+      constructor.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      ClassState is renamed to ClassManager.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Classes may supply their own InstrumentationManager by
+      providing a __sa_instrumentation_manager__ property.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Custom instrumentation may use any mechanism to associate a
+      ClassManager with a class and an InstanceState with an
+      instance.  Attributes on those objects are still the default
+      association mechanism used by SQLAlchemy's native
+      instrumentation.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Moved entity_name, _sa_session_id, and _instance_key from the
+      instance object to the instance state.  These values are still
+      available in the old way, which is now deprecated, using
+      descriptors attached to the class.  A deprecation warning will
+      be issued when accessed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The _prepare_instrumentation alias for prepare_instrumentation
+      has been removed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      sqlalchemy.exceptions has been renamed to sqlalchemy.exc.  The
+      module may be imported under either name.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      ORM-related exceptions are now defined in sqlalchemy.orm.exc.
+      ConcurrentModificationError, FlushError, and
+      UnmappedColumnError compatibility aliases are installed in
+      sqlalchemy.exc during the import of sqlalchemy.orm.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      sqlalchemy.logging has been renamed to sqlalchemy.log.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The transitional sqlalchemy.log.SADeprecationWarning alias for
+      the warning's definition in sqlalchemy.exc has been removed.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      exc.AssertionError has been removed and usage replaced with
+      Python's built-in AssertionError.
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      The behavior of MapperExtensions attached to multiple,
+      entity_name= primary mappers for a single class has been
+      altered.  The first mapper() defined for a class is the only
+      mapper eligible for the MapperExtension 'instrument_class',
+      'init_instance' and 'init_failed' events.  This is backwards
+      incompatible; previously the extensions of last mapper defined
+      would receive these events.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      Added support for returning values from inserts (2.0+ only),
+      updates and deletes (2.1+ only).
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      global "propigate"->"propagate" change.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      polymorphic_union() function respects the "key" of each
+      Column if they differ from the column's name.
+
+    .. change::
+        :tags: orm
+        :tickets: 1199
+
+      Fixed 0.4-only bug preventing composite columns
+      from working properly with inheriting mappers
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed RLock-related bug in mapper which could deadlock upon
+      reentrant mapper compile() calls, something that occurs when
+      using declarative constructs inside of ForeignKey objects.
+      Ported from 0.5.
+
+    .. change::
+        :tags: orm
+        :tickets: 1213
+
+      Fixed bug in composite types which prevented a primary-key
+      composite type from being mutated.
+
+    .. change::
+        :tags: orm
+        :tickets: 976
+
+      Added ScopedSession.is_active accessor.
+
+    .. change::
+        :tags: orm
+        :tickets: 939
+
+      Class-bound accessor can be used as the argument to
+      relation() order_by.
+
+    .. change::
+        :tags: orm
+        :tickets: 1072
+
+      Fixed shard_id argument on ShardedSession.execute().
+
+    .. change::
+        :tags: sql
+        :tickets: 1246
+
+      Connection.invalidate() checks for closed status
+      to avoid attribute errors.
+
+    .. change::
+        :tags: sql
+        :tickets: 1094
+
+      NullPool supports reconnect on failure behavior.
+
+    .. change::
+        :tags: sql
+        :tickets: 1299
+
+      The per-dialect cache used by TypeEngine to cache
+      dialect-specific types is now a WeakKeyDictionary.
+      This to prevent dialect objects from
+      being referenced forever for an application that
+      creates an arbitrarily large number of engines
+      or dialects.   There is a small performance penalty
+      which will be resolved in 0.6.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed SQLite reflection methods so that non-present
+      cursor.description, which triggers an auto-cursor
+      close, will be detected so that no results doesn't
+      fail on recent versions of pysqlite which raise
+      an error when fetchone() called with no rows present.
+
+    .. change::
+        :tags: postgres
+        :tickets: 714
+
+      Added Index reflection support to Postgres, using a
+      great patch we long neglected, submitted by
+      Ken Kuhlman.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1241
+
+      Fixed bug in exception raise when FK columns not present
+      during reflection.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1265
+
+      Fixed bug which was preventing out params of certain types
+      from being received; thanks a ton to huddlej at wwu.edu !
diff --git a/doc/build/changelog/changelog_06.rst b/doc/build/changelog/changelog_06.rst
new file mode 100644 (file)
index 0000000..0ec7027
--- /dev/null
@@ -0,0 +1,5406 @@
+
+==============
+0.6 Changelog
+==============
+
+                
+.. changelog::
+    :version: 0.6.9
+    :released: Sat May 05 2012
+
+    .. change::
+        :tags: general
+        :tickets: 2279
+
+      Adjusted the "importlater" mechanism, which is
+      used internally to resolve import cycles,
+      such that the usage of __import__ is completed
+      when the import of sqlalchemy or sqlalchemy.orm
+      is done, thereby avoiding any usage of __import__
+      after the application starts new threads,
+      fixes.
+
+    .. change::
+        :tags: orm
+        :tickets: 2197
+
+      Fixed bug whereby the source clause
+      used by query.join() would be inconsistent
+      if against a column expression that combined
+      multiple entities together.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2310
+
+      fixed inappropriate evaluation of user-mapped
+      object in a boolean context within query.get().
+
+    .. change::
+        :tags: orm
+        :tickets: 2228
+
+      Fixed bug apparent only in Python 3 whereby
+      sorting of persistent + pending objects during
+      flush would produce an illegal comparison,
+      if the persistent object primary key
+      is not a single integer.
+
+    .. change::
+        :tags: orm
+        :tickets: 2234
+
+      Fixed bug where query.join() + aliased=True
+      from a joined-inh structure to itself on
+      relationship() with join condition on the child
+      table would convert the lead entity into the
+      joined one inappropriately.
+
+    .. change::
+        :tags: orm
+        :tickets: 2287
+
+      Fixed bug whereby mapper.order_by attribute would
+      be ignored in the "inner" query within a
+      subquery eager load. .
+
+    .. change::
+        :tags: orm
+        :tickets: 2215
+
+      Fixed bug whereby if a mapped class
+      redefined __hash__() or __eq__() to something
+      non-standard, which is a supported use case
+      as SQLA should never consult these,
+      the methods would be consulted if the class
+      was part of a "composite" (i.e. non-single-entity)
+      result set.
+
+    .. change::
+        :tags: orm
+        :tickets: 2188
+
+      Fixed subtle bug that caused SQL to blow
+      up if: column_property() against subquery +
+      joinedload + LIMIT + order by the column
+      property() occurred. .
+
+    .. change::
+        :tags: orm
+        :tickets: 2207
+
+      The join condition produced by with_parent
+      as well as when using a "dynamic" relationship
+      against a parent will generate unique
+      bindparams, rather than incorrectly repeating
+      the same bindparam. .
+
+    .. change::
+        :tags: orm
+        :tickets: 2199
+
+      Repaired the "no statement condition"
+      assertion in Query which would attempt
+      to raise if a generative method were called
+      after from_statement() were called..
+
+    .. change::
+        :tags: orm
+        :tickets: 1776
+
+      Cls.column.collate("some collation") now
+      works.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2297
+
+      Fixed the error formatting raised when
+      a tuple is inadvertently passed to session.query().
+
+    .. change::
+        :tags: engine
+        :tickets: 2317
+
+      Backported the fix for introduced
+      in 0.7.4, which ensures that the connection
+      is in a valid state before attempting to call
+      rollback()/prepare()/release() on savepoint
+      and two-phase transactions.
+
+    .. change::
+        :tags: sql
+        :tickets: 2188
+
+      Fixed two subtle bugs involving column
+      correspondence in a selectable,
+      one with the same labeled subquery repeated, the other
+      when the label has been "grouped" and
+      loses itself.  Affects.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug whereby "warn on unicode" flag
+      would get set for the String type
+      when used with certain dialects.  This
+      bug is not in 0.7.
+
+    .. change::
+        :tags: sql
+        :tickets: 2270
+
+      Fixed bug whereby with_only_columns() method of
+      Select would fail if a selectable were passed..   However, the FROM behavior is
+      still incorrect here, so you need 0.7 in
+      any case for this use case to be usable.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Added an informative error message when
+      ForeignKeyConstraint refers to a column name in
+      the parent that is not found.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2291, 2141
+
+      Fixed bug related to whereby the
+      same modified index behavior in PG 9 affected
+      primary key reflection on a renamed column..
+
+    .. change::
+        :tags: mysql
+        :tickets: 2186
+
+      Fixed OurSQL dialect to use ansi-neutral
+      quote symbol "'" for XA commands instead
+      of '"'. .
+
+    .. change::
+        :tags: mysql
+        :tickets: 2225
+
+      a CREATE TABLE will put the COLLATE option
+      after CHARSET, which appears to be part of
+      MySQL's arbitrary rules regarding if it will actually
+      work or not.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2269
+
+      Decode incoming values when retrieving
+      list of index names and the names of columns
+      within those indexes.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2200
+
+      Added ORA-00028 to disconnect codes, use
+      cx_oracle _Error.code to get at the code,.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2220
+
+      repaired the oracle.RAW type which did not
+      generate the correct DDL.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2212
+
+      added CURRENT to reserved word list.
+
+    .. change::
+        :tags: examples
+        :tickets: 2266
+
+      Adjusted dictlike-polymorphic.py example
+      to apply the CAST such that it works on
+      PG, other databases.
+
+.. changelog::
+    :version: 0.6.8
+    :released: Sun Jun 05 2011
+
+    .. change::
+        :tags: orm
+        :tickets: 2144
+
+      Calling query.get() against a column-based entity is
+      invalid, this condition now raises a deprecation warning.
+
+    .. change::
+        :tags: orm
+        :tickets: 2151
+
+      a non_primary mapper will inherit the _identity_class
+      of the primary mapper.  This so that a non_primary
+      established against a class that's normally in an
+      inheritance mapping will produce results that are
+      identity-map compatible with that of the primary
+      mapper
+
+    .. change::
+        :tags: orm
+        :tickets: 2148
+
+      Backported 0.7's identity map implementation, which
+      does not use a mutex around removal.  This as some users
+      were still getting deadlocks despite the adjustments
+      in 0.6.7; the 0.7 approach that doesn't use a mutex
+      does not appear to produce "dictionary changed size"
+      issues, the original rationale for the mutex.
+
+    .. change::
+        :tags: orm
+        :tickets: 2163
+
+      Fixed the error message emitted for "can't
+      execute syncrule for destination column 'q';
+      mapper 'X' does not map this column" to
+      reference the correct mapper. .
+
+    .. change::
+        :tags: orm
+        :tickets: 2149
+
+      Fixed bug where determination of "self referential"
+      relationship would fail with no workaround
+      for joined-inh subclass related to itself,
+      or joined-inh subclass related to a subclass
+      of that with no cols in the sub-sub class
+      in the join condition.
+
+    .. change::
+        :tags: orm
+        :tickets: 2153
+
+      mapper() will ignore non-configured foreign keys
+      to unrelated tables when determining inherit
+      condition between parent and child class.
+      This is equivalent to behavior already
+      applied to declarative.  Note that 0.7 has a
+      more comprehensive solution to this, altering
+      how join() itself determines an FK error.
+
+    .. change::
+        :tags: orm
+        :tickets: 2171
+
+      Fixed bug whereby mapper mapped to an anonymous
+      alias would fail if logging were used, due to
+      unescaped % sign in the alias name.
+
+    .. change::
+        :tags: orm
+        :tickets: 2170
+
+      Modify the text of the message which occurs
+      when the "identity" key isn't detected on
+      flush, to include the common cause that
+      the Column isn't set up to detect
+      auto-increment correctly;.
+
+    .. change::
+        :tags: orm
+        :tickets: 2182
+
+      Fixed bug where transaction-level "deleted"
+      collection wouldn't be cleared of expunged
+      states, raising an error if they later
+      became transient.
+
+    .. change::
+        :tags: sql
+        :tickets: 2147
+
+      Fixed bug whereby if FetchedValue was passed
+      to column server_onupdate, it would not
+      have its parent "column" assigned, added
+      test coverage for all column default assignment
+      patterns.
+
+    .. change::
+        :tags: sql
+        :tickets: 2167
+
+      Fixed bug whereby nesting a label of a select()
+      with another label in it would produce incorrect
+      exported columns.   Among other things this would
+      break an ORM column_property() mapping against
+      another column_property(). .
+
+    .. change::
+        :tags: engine
+        :tickets: 2178
+
+      Adjusted the __contains__() method of
+      a RowProxy result row such that no exception
+      throw is generated internally;
+      NoSuchColumnError() also will generate its
+      message regardless of whether or not the column
+      construct can be coerced to a string..
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2141
+
+      Fixed bug affecting PG 9 whereby index reflection
+      would fail if against a column whose name
+      had changed. .
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2175
+
+      Some unit test fixes regarding numeric arrays,
+      MATCH operator.   A potential floating-point
+      inaccuracy issue was fixed, and certain tests
+      of the MATCH operator only execute within an
+      EN-oriented locale for now. .
+
+    .. change::
+        :tags: mssql
+        :tickets: 2169
+
+      Fixed bug in MSSQL dialect whereby the aliasing
+      applied to a schema-qualified table would leak
+      into enclosing select statements.
+
+    .. change::
+        :tags: mssql
+        :tickets: 2159
+
+      Fixed bug whereby DATETIME2 type would fail on
+      the "adapt" step when used in result sets or
+      bound parameters.  This issue is not in 0.7.
+
+.. changelog::
+    :version: 0.6.7
+    :released: Wed Apr 13 2011
+
+    .. change::
+        :tags: orm
+        :tickets: 2087
+
+      Tightened the iterate vs. remove mutex around the
+      identity map iteration, attempting to reduce the
+      chance of an (extremely rare) reentrant gc operation
+      causing a deadlock.  Might remove the mutex in
+      0.7.
+
+    .. change::
+        :tags: orm
+        :tickets: 2030
+
+      Added a `name` argument to `Query.subquery()`, to allow
+      a fixed name to be assigned to the alias object.
+
+    .. change::
+        :tags: orm
+        :tickets: 2019
+
+      A warning is emitted when a joined-table inheriting mapper
+      has no primary keys on the locally mapped table
+      (but has pks on the superclass table).
+
+    .. change::
+        :tags: orm
+        :tickets: 2038
+
+      Fixed bug where "middle" class in a polymorphic hierarchy
+      would have no 'polymorphic_on' column if it didn't also
+      specify a 'polymorphic_identity', leading to strange
+      errors upon refresh, wrong class loaded when querying
+      from that target. Also emits the correct WHERE criterion
+      when using single table inheritance.
+
+    .. change::
+        :tags: orm
+        :tickets: 1995
+
+      Fixed bug where a column with a SQL or server side default
+      that was excluded from a mapping with include_properties
+      or exclude_properties would result in UnmappedColumnError.
+
+    .. change::
+        :tags: orm
+        :tickets: 2046
+
+      A warning is emitted in the unusual case that an
+      append or similar event on a collection occurs after
+      the parent object has been dereferenced, which
+      prevents the parent from being marked as "dirty"
+      in the session.  This will be an exception in 0.7.
+
+    .. change::
+        :tags: orm
+        :tickets: 2098
+
+      Fixed bug in query.options() whereby a path
+      applied to a lazyload using string keys could
+      overlap a same named attribute on the wrong
+      entity.  Note 0.7 has an updated version of this
+      fix.
+
+    .. change::
+        :tags: orm
+        :tickets: 2063
+
+      Reworded the exception raised when a flush
+      is attempted of a subclass that is not polymorphic
+      against the supertype.
+
+    .. change::
+        :tags: orm
+        :tickets: 2123
+
+      Some fixes to the state handling regarding
+      backrefs, typically when autoflush=False, where
+      the back-referenced collection wouldn't
+      properly handle add/removes with no net
+      change.  Thanks to Richard Murri for the
+      test case + patch.
+
+    .. change::
+        :tags: orm
+        :tickets: 2130
+
+      a "having" clause would be copied from the
+      inside to the outside query if from_self()
+      were used..
+
+    .. change::
+        :tags: sql
+        :tickets: 2028
+
+      Column.copy(), as used in table.tometadata(), copies the
+      'doc' attribute.
+
+    .. change::
+        :tags: sql
+        :tickets: 2023
+
+      Added some defs to the resultproxy.c extension so that
+      the extension compiles and runs on Python 2.4.
+
+    .. change::
+        :tags: sql
+        :tickets: 2042
+
+      The compiler extension now supports overriding the default
+      compilation of expression._BindParamClause including that
+      the auto-generated binds within the VALUES/SET clause
+      of an insert()/update() statement will also use the new
+      compilation rules.
+
+    .. change::
+        :tags: sql
+        :tickets: 2089
+
+      Added accessors to ResultProxy "returns_rows", "is_insert"
+
+    .. change::
+        :tags: sql
+        :tickets: 2116
+
+      The limit/offset keywords to select() as well
+      as the value passed to select.limit()/offset()
+      will be coerced to integer.
+
+    .. change::
+        :tags: engine
+        :tickets: 2102
+
+      Fixed bug in QueuePool, SingletonThreadPool whereby
+      connections that were discarded via overflow or periodic
+      cleanup() were not explicitly closed, leaving garbage
+      collection to the task instead.   This generally only
+      affects non-reference-counting backends like Jython
+      and Pypy.  Thanks to Jaimy Azle for spotting
+      this.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 2115
+
+      Fixed bug where reflection of foreign key
+      created as "REFERENCES <tablename>" without
+      col name would fail.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1083
+
+      When explicit sequence execution derives the name
+      of the auto-generated sequence of a SERIAL column,
+      which currently only occurs if implicit_returning=False,
+      now accommodates if the table + column name is greater
+      than 63 characters using the same logic Postgresql uses.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2044
+
+      Added an additional libpq message to the list of "disconnect"
+      exceptions, "could not receive data from server"
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2092
+
+      Added RESERVED_WORDS for postgresql dialect.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2073
+
+      Fixed the BIT type to allow a "length" parameter, "varying"
+      parameter.  Reflection also fixed.
+
+    .. change::
+        :tags: informix
+        :tickets: 2092
+
+      Added RESERVED_WORDS informix dialect.
+
+    .. change::
+        :tags: mssql
+        :tickets: 2071
+
+      Rewrote the query used to get the definition of a view,
+      typically when using the Inspector interface, to
+      use sys.sql_modules instead of the information schema,
+      thereby allowing views definitions longer than 4000
+      characters to be fully returned.
+
+    .. change::
+        :tags: mysql
+        :tickets: 2047
+
+      oursql dialect accepts the same "ssl" arguments in
+      create_engine() as that of MySQLdb.
+
+    .. change::
+        :tags: firebird
+        :tickets: 2083
+
+      The "implicit_returning" flag on create_engine() is
+      honored if set to False.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2100
+
+      Using column names that would require quotes
+      for the column itself or for a name-generated
+      bind parameter, such as names with special
+      characters, underscores, non-ascii characters,
+      now properly translate bind parameter keys when
+      talking to cx_oracle.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2116
+
+      Oracle dialect adds use_binds_for_limits=False
+      create_engine() flag, will render the LIMIT/OFFSET
+      values inline instead of as binds, reported to
+      modify the execution plan used by Oracle.
+
+    .. change::
+        :tags: ext
+        :tickets: 2090
+
+      The horizontal_shard ShardedSession class accepts the common
+      Session argument "query_cls" as a constructor argument,
+      to enable further subclassing of ShardedQuery.
+
+    .. change::
+        :tags: declarative
+        :tickets: 2050
+
+      Added an explicit check for the case that the name
+      'metadata' is used for a column attribute on a
+      declarative class.
+
+    .. change::
+        :tags: declarative
+        :tickets: 2061
+
+      Fix error message referencing old @classproperty
+      name to reference @declared_attr
+
+    .. change::
+        :tags: declarative
+        :tickets: 2091
+
+      Arguments in __mapper_args__ that aren't "hashable"
+      aren't mistaken for always-hashable, possibly-column
+      arguments.
+
+    .. change::
+        :tags: documentation
+        :tickets: 2029
+
+      Documented SQLite DATE/TIME/DATETIME types.
+
+    .. change::
+        :tags: examples
+        :tickets: 2090
+
+      The Beaker caching example allows a "query_cls" argument
+      to the query_callable() function.
+
+.. changelog::
+    :version: 0.6.6
+    :released: Sat Jan 08 2011
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug whereby a non-"mutable" attribute modified event
+      which occurred on an object that was clean except for
+      preceding mutable attribute changes would fail to strongly
+      reference itself in the identity map. This would cause the
+      object to be garbage collected, losing track of any changes
+      that weren't previously saved in the "mutable changes"
+      dictionary.
+
+    .. change::
+        :tags: orm
+        :tickets: 2013
+
+      Fixed bug whereby "passive_deletes='all'" wasn't passing
+      the correct symbols to lazy loaders during flush, thereby
+      causing an unwarranted load.
+
+    .. change::
+        :tags: orm
+        :tickets: 1997
+
+      Fixed bug which prevented composite mapped
+      attributes from being used on a mapped select statement.. Note the workings of composite are slated to
+      change significantly in 0.7.
+
+    .. change::
+        :tags: orm
+        :tickets: 1976
+
+      active_history flag also added to composite().
+      The flag has no effect in 0.6, but is instead
+      a placeholder flag for forwards compatibility,
+      as it applies in 0.7 for composites.
+
+    .. change::
+        :tags: orm
+        :tickets: 2002
+
+      Fixed uow bug whereby expired objects passed to
+      Session.delete() would not have unloaded references
+      or collections taken into account when deleting
+      objects, despite passive_deletes remaining at
+      its default of False.
+
+    .. change::
+        :tags: orm
+        :tickets: 1987
+
+      A warning is emitted when version_id_col is specified
+      on an inheriting mapper when the inherited mapper
+      already has one, if those column expressions are not
+      the same.
+
+    .. change::
+        :tags: orm
+        :tickets: 1954
+
+      "innerjoin" flag doesn't take effect along the chain
+      of joinedload() joins if a previous join in that chain
+      is an outer join, thus allowing primary rows without
+      a referenced child row to be correctly returned
+      in results.
+
+    .. change::
+        :tags: orm
+        :tickets: 1964
+
+      Fixed bug regarding "subqueryload" strategy whereby
+      strategy would fail if the entity was an aliased()
+      construct.
+
+    .. change::
+        :tags: orm
+        :tickets: 2014
+
+      Fixed bug regarding "subqueryload" strategy whereby
+      the join would fail if using a multi-level load
+      of the form from A->joined-subclass->C
+
+    .. change::
+        :tags: orm
+        :tickets: 1968
+
+      Fixed indexing of Query objects by -1. It was erroneously
+      transformed to the empty slice -1:0 that resulted in
+      IndexError.
+
+    .. change::
+        :tags: orm
+        :tickets: 1971
+
+      The mapper argument "primary_key" can be passed as a
+      single column as well as a list or tuple. 
+      The documentation examples that illustrated it as a
+      scalar value have been changed to lists.
+
+    .. change::
+        :tags: orm
+        :tickets: 1961
+
+      Added active_history flag to relationship()
+      and column_property(), forces attribute events to
+      always load the "old" value, so that it's available to
+      attributes.get_history().
+
+    .. change::
+        :tags: orm
+        :tickets: 1977
+
+      Query.get() will raise if the number of params
+      in a composite key is too large, as well as too
+      small.
+
+    .. change::
+        :tags: orm
+        :tickets: 1992
+
+      Backport of "optimized get" fix from 0.7,
+      improves the generation of joined-inheritance
+      "load expired row" behavior.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      A little more verbiage to the "primaryjoin" error,
+      in an unusual condition that the join condition
+      "works" for viewonly but doesn't work for non-viewonly,
+      and foreign_keys wasn't used - adds "foreign_keys" to
+      the suggestion.  Also add "foreign_keys" to the
+      suggestion for the generic "direction" error.
+
+    .. change::
+        :tags: sql
+        :tickets: 1984
+
+      Fixed operator precedence rules for multiple
+      chains of a single non-associative operator.
+      I.e. "x - (y - z)" will compile as "x - (y - z)"
+      and not "x - y - z".  Also works with labels,
+      i.e. "x - (y - z).label('foo')"
+
+    .. change::
+        :tags: sql
+        :tickets: 1967
+
+      The 'info' attribute of Column is copied during
+      Column.copy(), i.e. as occurs when using columns
+      in declarative mixins.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added a bind processor for booleans which coerces
+      to int, for DBAPIs such as pymssql that naively call
+      str() on values.
+
+    .. change::
+        :tags: sql
+        :tickets: 2000
+
+      CheckConstraint will copy its 'initially', 'deferrable',
+      and '_create_rule' attributes within a copy()/tometadata()
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      The "unicode warning" against non-unicode bind data
+      is now raised only when the
+      Unicode type is used explictly; not when
+      convert_unicode=True is used on the engine
+      or String type.
+
+    .. change::
+        :tags: engine
+        :tickets: 1978
+
+      Fixed memory leak in C version of Decimal result
+      processor.
+
+    .. change::
+        :tags: engine
+        :tickets: 1871
+
+      Implemented sequence check capability for the C
+      version of RowProxy, as well as 2.7 style
+      "collections.Sequence" registration for RowProxy.
+
+    .. change::
+        :tags: engine
+        :tickets: 1998
+
+      Threadlocal engine methods rollback(), commit(),
+      prepare() won't raise if no transaction is in progress;
+      this was a regression introduced in 0.6.
+
+    .. change::
+        :tags: engine
+        :tickets: 2004
+
+      Threadlocal engine returns itself upon begin(),
+      begin_nested(); engine then implements contextmanager
+      methods to allow the "with" statement.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1984
+
+      Single element tuple expressions inside an IN clause
+      parenthesize correctly, also from
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1955
+
+      Ensured every numeric, float, int code, scalar + array,
+      are recognized by psycopg2 and pg8000's "numeric"
+      base type.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1956
+
+      Added as_uuid=True flag to the UUID type, will receive
+      and return values as Python UUID() objects rather than
+      strings.  Currently, the UUID type is only known to
+      work with psycopg2.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1989
+
+      Fixed bug whereby KeyError would occur with non-ENUM
+      supported PG versions after a pool dispose+recreate
+      would occur.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1960
+
+      Fixed error handling for Jython + zxjdbc, such that
+      has_table() property works again.  Regression from
+      0.6.3 (we don't have a Jython buildbot, sorry)
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1851
+
+      The REFERENCES clause in a CREATE TABLE that includes
+      a remote schema to another table with the same schema
+      name now renders the remote name without
+      the schema clause, as required by SQLite.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      On the same theme, the REFERENCES clause in a CREATE TABLE
+      that includes a remote schema to a *different* schema
+      than that of the parent table doesn't render at all,
+      as cross-schema references do not appear to be supported.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1770
+
+      The rewrite of index reflection in was
+      unfortunately not tested correctly, and returned incorrect
+      results.   This regression is now fixed.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1953
+
+      The cx_oracle "decimal detection" logic, which takes place
+      for for result set columns with ambiguous numeric characteristics,
+      now uses the decimal point character determined by the locale/
+      NLS_LANG setting, using an on-first-connect detection of
+      this character.  cx_oracle 5.0.3 or greater is also required
+      when using a non-period-decimal-point NLS_LANG setting..
+
+    .. change::
+        :tags: firebird
+        :tickets: 2012
+
+      Firebird numeric type now checks for Decimal explicitly,
+      lets float() pass right through, thereby allowing
+      special values such as float('inf').
+
+    .. change::
+        :tags: declarative
+        :tickets: 1972
+
+      An error is raised if __table_args__ is not in tuple
+      or dict format, and is not None.
+
+    .. change::
+        :tags: sqlsoup
+        :tickets: 1975
+
+      Added "map_to()" method to SqlSoup, which is a "master"
+      method which accepts explicit arguments for each aspect of
+      the selectable and mapping, including a base class per
+      mapping.
+
+    .. change::
+        :tags: sqlsoup
+        :tickets: 
+
+      Mapped selectables used with the map(), with_labels(),
+      join() methods no longer put the given argument into the
+      internal "cache" dictionary.  Particularly since the
+      join() and select() objects are created in the method
+      itself this was pretty much a pure memory leaking behavior.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      The versioning example now supports detection of changes
+      in an associated relationship().
+
+.. changelog::
+    :version: 0.6.5
+    :released: Sun Oct 24 2010
+
+    .. change::
+        :tags: orm
+        :tickets: 1914
+
+      Added a new "lazyload" option "immediateload".
+      Issues the usual "lazy" load operation automatically
+      as the object is populated.   The use case
+      here is when loading objects to be placed in
+      an offline cache, or otherwise used after
+      the session isn't available, and straight 'select'
+      loading, not 'joined' or 'subquery', is desired.
+
+    .. change::
+        :tags: orm
+        :tickets: 1920
+
+      New Query methods: query.label(name), query.as_scalar(),
+      return the query's statement as a scalar subquery
+      with /without label;
+      query.with_entities(*ent), replaces the SELECT list of
+      the query with new entities.
+      Roughly equivalent to a generative form of query.values()
+      which accepts mapped entities as well as column
+      expressions.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed recursion bug which could occur when moving
+      an object from one reference to another, with
+      backrefs involved, where the initiating parent
+      was a subclass (with its own mapper) of the
+      previous parent.
+
+    .. change::
+        :tags: orm
+        :tickets: 1918
+
+      Fixed a regression in 0.6.4 which occurred if you
+      passed an empty list to "include_properties" on
+      mapper()
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed labeling bug in Query whereby the NamedTuple
+      would mis-apply labels if any of the column
+      expressions were un-labeled.
+
+    .. change::
+        :tags: orm
+        :tickets: 1925
+
+      Patched a case where query.join() would adapt the
+      right side to the right side of the left's join
+      inappropriately
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.select_from() has been beefed up to help
+      ensure that a subsequent call to query.join()
+      will use the select_from() entity, assuming it's
+      a mapped entity and not a plain selectable,
+      as the default "left" side, not the first entity
+      in the Query object's list of entities.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The exception raised by Session when it is used
+      subsequent to a subtransaction rollback (which is what
+      happens when a flush fails in autocommit=False mode) has
+      now been reworded (this is the "inactive due to a
+      rollback in a subtransaction" message). In particular,
+      if the rollback was due to an exception during flush(),
+      the message states this is the case, and reiterates the
+      string form of the original exception that occurred
+      during flush. If the session is closed due to explicit
+      usage of subtransactions (not very common), the message
+      just states this is the case.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The exception raised by Mapper when repeated requests to
+      its initialization are made after initialization already
+      failed no longer assumes the "hasattr" case, since
+      there's other scenarios in which this message gets
+      emitted, and the message also does not compound onto
+      itself multiple times - you get the same message for
+      each attempt at usage. The misnomer "compiles" is being
+      traded out for "initialize".
+
+    .. change::
+        :tags: orm
+        :tickets: 1935
+
+      Fixed bug in query.update() where 'evaluate' or 'fetch'
+      expiration would fail if the column expression key was
+      a class attribute with a different keyname as the
+      actual column name.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added an assertion during flush which ensures
+      that no NULL-holding identity keys were generated
+      on "newly persistent" objects.
+      This can occur when user defined code inadvertently
+      triggers flushes on not-fully-loaded objects.
+
+    .. change::
+        :tags: orm
+        :tickets: 1910
+
+      lazy loads for relationship attributes now use
+      the current state, not the "committed" state,
+      of foreign and primary key attributes
+      when issuing SQL, if a flush is not in process.
+      Previously, only the database-committed state would
+      be used.  In particular, this would cause a many-to-one
+      get()-on-lazyload operation to fail, as autoflush
+      is not triggered on these loads when the attributes are
+      determined and the "committed" state may not be
+      available.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      A new flag on relationship(), load_on_pending, allows
+      the lazy loader to fire off on pending objects without a
+      flush taking place, as well as a transient object that's
+      been manually "attached" to the session. Note that this
+      flag blocks attribute events from taking place when an
+      object is loaded, so backrefs aren't available until
+      after a flush. The flag is only intended for very
+      specific use cases.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Another new flag on relationship(), cascade_backrefs,
+      disables the "save-update" cascade when the event was
+      initiated on the "reverse" side of a bidirectional
+      relationship.   This is a cleaner behavior so that
+      many-to-ones can be set on a transient object without
+      it getting sucked into the child object's session,
+      while still allowing the forward collection to
+      cascade.   We *might* default this to False in 0.7.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Slight improvement to the behavior of
+      "passive_updates=False" when placed only on the
+      many-to-one side of a relationship; documentation has
+      been clarified that passive_updates=False should really
+      be on the one-to-many side.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Placing passive_deletes=True on a many-to-one emits
+      a warning, since you probably intended to put it on
+      the one-to-many side.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug that would prevent "subqueryload" from
+      working correctly with single table inheritance
+      for a relationship from a subclass - the "where
+      type in (x, y, z)" only gets placed on the inside,
+      instead of repeatedly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      When using from_self() with single table inheritance,
+      the "where type in (x, y, z)" is placed on the outside
+      of the query only, instead of repeatedly.   May make
+      some more adjustments to this.
+
+    .. change::
+        :tags: orm
+        :tickets: 1924
+
+      scoped_session emits a warning when configure() is
+      called if a Session is already present (checks only the
+      current thread)
+
+    .. change::
+        :tags: orm
+        :tickets: 1932
+
+      reworked the internals of mapper.cascade_iterator() to
+      cut down method calls by about 9% in some circumstances.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug in TypeDecorator whereby the dialect-specific
+      type was getting pulled in to generate the DDL for a
+      given type, which didn't always return the correct result.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      TypeDecorator can now have a fully constructed type
+      specified as its "impl", in addition to a type class.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      TypeDecorator will now place itself as the resulting
+      type for a binary expression where the type coercion
+      rules would normally return its impl type - previously,
+      a copy of the impl type would be returned which would
+      have the TypeDecorator embedded into it as the "dialect"
+      impl, this was probably an unintentional way of achieving
+      the desired effect.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      TypeDecorator.load_dialect_impl() returns "self.impl" by
+      default, i.e. not the dialect implementation type of
+      "self.impl".   This to support compilation correctly.
+      Behavior can be user-overridden in exactly the same way
+      as before to the same effect.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added type_coerce(expr, type_) expression element.
+      Treats the given expression as the given type when evaluating
+      expressions and processing result rows, but does not
+      affect the generation of SQL, other than an anonymous
+      label.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Table.tometadata() now copies Index objects associated
+      with the Table as well.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Table.tometadata() issues a warning if the given Table
+      is already present in the target MetaData - the existing
+      Table object is returned.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      An informative error message is raised if a Column
+      which has not yet been assigned a name, i.e. as in
+      declarative, is used in a context where it is
+      exported to the columns collection of an enclosing
+      select() construct, or if any construct involving
+      that column is compiled before its name is
+      assigned.
+
+    .. change::
+        :tags: sql
+        :tickets: 1862
+
+      as_scalar(), label() can be called on a selectable
+      which contains a Column that is not yet named.
+
+    .. change::
+        :tags: sql
+        :tickets: 1907
+
+      Fixed recursion overflow which could occur when operating
+      with two expressions both of type "NullType", but
+      not the singleton NULLTYPE instance.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1922
+
+      @classproperty (soon/now @declared_attr) takes effect for
+      __mapper_args__, __table_args__, __tablename__ on
+      a base class that is not a mixin, as well as mixins.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1915
+
+      @classproperty 's official name/location for usage
+      with declarative is sqlalchemy.ext.declarative.declared_attr.
+      Same thing, but moving there since it is more of a
+      "marker" that's specific to declararative,
+      not just an attribute technique.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1931, 1930
+
+      Fixed bug whereby columns on a mixin wouldn't propagate
+      correctly to a single-table, or joined-table,
+      inheritance scheme where the attribute name is
+      different than that of the column.,.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      A mixin can now specify a column that overrides
+      a column of the same name associated with a superclass.
+      Thanks to Oystein Haaland.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Fixed a regression in 0.6.4 whereby the change that
+      allowed cursor errors to be raised consistently broke
+      the result.lastrowid accessor.   Test coverage has
+      been added for result.lastrowid.   Note that lastrowid
+      is only supported by Pysqlite and some MySQL drivers,
+      so isn't super-useful in the general case.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      the logging message emitted by the engine when
+      a connection is first used is now "BEGIN (implicit)"
+      to emphasize that DBAPI has no explicit begin().
+
+    .. change::
+        :tags: engine
+        :tickets: 1936
+
+      added "views=True" option to metadata.reflect(),
+      will add the list of available views to those
+      being reflected.
+
+    .. change::
+        :tags: engine
+        :tickets: 1899
+
+      engine_from_config() now accepts 'debug' for
+      'echo', 'echo_pool', 'force' for 'convert_unicode',
+      boolean values for 'use_native_unicode'.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Added "as_tuple" flag to ARRAY type, returns results
+      as tuples instead of lists to allow hashing.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1933
+
+      Fixed bug which prevented "domain" built from a
+      custom type such as "enum" from being reflected.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1940
+
+      Fixed bug involving reflection of CURRENT_TIMESTAMP
+      default used with ON UPDATE clause, thanks to
+      Taavi Burns
+
+    .. change::
+        :tags: oracle
+        :tickets: 1878
+
+      The implicit_retunring argument to create_engine()
+      is now honored regardless of detected version of
+      Oracle.  Previously, the flag would be forced
+      to False if server version info was < 10.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1946
+
+      Fixed reflection bug which did not properly handle
+      reflection of unknown types.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1943
+
+      Fixed bug where aliasing of tables with "schema" would
+      fail to compile properly.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1770
+
+      Rewrote the reflection of indexes to use sys.
+      catalogs, so that column names of any configuration
+      (spaces, embedded commas, etc.) can be reflected.
+      Note that reflection of indexes requires SQL
+      Server 2005 or greater.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1952
+
+      mssql+pymssql dialect now honors the "port" portion
+      of the URL instead of discarding it.
+
+    .. change::
+        :tags: informix
+        :tickets: 1906
+
+      *Major* cleanup / modernization of the Informix
+      dialect for 0.6, courtesy Florian Apolloner.
+
+    .. change::
+        :tags: tests
+        :tickets: 
+
+      the NoseSQLAlchemyPlugin has been moved to a
+      new package "sqlalchemy_nose" which installs
+      along with "sqlalchemy".  This so that the "nosetests"
+      script works as always but also allows the
+      --with-coverage option to turn on coverage before
+      SQLAlchemy modules are imported, allowing coverage
+      to work correctly.
+
+    .. change::
+        :tags: misc
+        :tickets: 1890
+
+      CircularDependencyError now has .cycles and .edges
+      members, which are the set of elements involved in
+      one or more cycles, and the set of edges as 2-tuples.
+
+.. changelog::
+    :version: 0.6.4
+    :released: Tue Sep 07 2010
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The name ConcurrentModificationError has been
+      changed to StaleDataError, and descriptive
+      error messages have been revised to reflect
+      exactly what the issue is.   Both names will
+      remain available for the forseeable future
+      for schemes that may be specifying
+      ConcurrentModificationError in an "except:"
+      clause.
+
+    .. change::
+        :tags: orm
+        :tickets: 1891
+
+      Added a mutex to the identity map which mutexes
+      remove operations against iteration methods,
+      which now pre-buffer before returning an
+      iterable.   This because asyncrhonous gc
+      can remove items via the gc thread at any time.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The Session class is now present in sqlalchemy.orm.*.
+      We're moving away from the usage of create_session(),
+      which has non-standard defaults, for those situations
+      where a one-step Session constructor is desired. Most
+      users should stick with sessionmaker() for general use,
+      however.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.with_parent() now accepts transient objects
+      and will use the non-persistent values of their pk/fk
+      attributes in order to formulate the criterion.
+      Docs are also clarified as to the purpose of with_parent().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The include_properties and exclude_properties arguments
+      to mapper() now accept Column objects as members in
+      addition to strings.  This so that same-named Column
+      objects, such as those within a join(), can be
+      disambiguated.
+
+    .. change::
+        :tags: orm
+        :tickets: 1896
+
+      A warning is now emitted if a mapper is created against a
+      join or other single selectable that includes multiple
+      columns with the same name in its .c. collection,
+      and those columns aren't explictly named as part of
+      the same or separate attributes (or excluded).
+      In 0.7 this warning will be an exception.   Note that
+      this warning is not emitted when the combination occurs
+      as a result of inheritance, so that attributes
+      still allow being overridden naturally..  In 0.7 this will be improved further.
+
+    .. change::
+        :tags: orm
+        :tickets: 1896
+
+      The primary_key argument to mapper() can now specify
+      a series of columns that are only a subset of
+      the calculated "primary key" columns of the mapped
+      selectable, without an error being raised.  This
+      helps for situations where a selectable's effective
+      primary key is simpler than the number of columns
+      in the selectable that are actually marked as
+      "primary_key", such as a join against two
+      tables on their primary key columns.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      An object that's been deleted now gets a flag
+      'deleted', which prohibits the object from
+      being re-add()ed to the session, as previously
+      the object would live in the identity map
+      silently until its attributes were accessed.
+      The make_transient() function now resets this
+      flag along with the "key" flag.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      make_transient() can be safely called on an
+      already transient instance.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a warning is emitted in mapper() if the polymorphic_on
+      column is not present either in direct or derived
+      form in the mapped selectable or in the
+      with_polymorphic selectable, instead of silently
+      ignoring it.  Look for this to become an
+      exception in 0.7.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Another pass through the series of error messages
+      emitted when relationship() is configured with
+      ambiguous arguments.   The "foreign_keys"
+      setting is no longer mentioned, as it is almost
+      never needed and it is preferable users set up
+      correct ForeignKey metadata, which is now the
+      recommendation.  If 'foreign_keys'
+      is used and is incorrect, the message suggests
+      the attribute is probably unnecessary.  Docs
+      for the attribute are beefed up.  This
+      because all confused relationship() users on the
+      ML appear to be attempting to use foreign_keys
+      due to the message, which only confuses them
+      further since Table metadata is much clearer.
+
+    .. change::
+        :tags: orm
+        :tickets: 1877
+
+      If the "secondary" table has no ForeignKey metadata
+      and no foreign_keys is set, even though the
+      user is passing screwed up information, it is assumed
+      that primary/secondaryjoin expressions should
+      consider only and all cols in "secondary" to be
+      foreign.  It's not possible with "secondary" for
+      the foreign keys to be elsewhere in any case.
+      A warning is now emitted instead of an error,
+      and the mapping succeeds.
+
+    .. change::
+        :tags: orm
+        :tickets: 1856
+
+      Moving an o2m object from one collection to
+      another, or vice versa changing the referenced
+      object by an m2o, where the foreign key is also a
+      member of the primary key, will now be more
+      carefully checked during flush if the change in
+      value of the foreign key on the "many" side is the
+      result of a change in the primary key of the "one"
+      side, or if the "one" is just a different object.
+      In one case, a cascade-capable DB would have
+      cascaded the value already and we need to look at
+      the "new" PK value to do an UPDATE, in the other we
+      need to continue looking at the "old". We now look
+      at the "old", assuming passive_updates=True,
+      unless we know it was a PK switch that
+      triggered the change.
+
+    .. change::
+        :tags: orm
+        :tickets: 1857
+
+      The value of version_id_col can be changed
+      manually, and this will result in an UPDATE
+      of the row.  Versioned UPDATEs and DELETEs
+      now use the "committed" value of the
+      version_id_col in the WHERE clause and
+      not the pending changed value. The
+      version generator is also bypassed if
+      manual changes are present on the attribute.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Repaired the usage of merge() when used with
+      concrete inheriting mappers.  Such mappers frequently
+      have so-called "concrete" attributes, which are
+      subclass attributes that "disable" propagation from
+      the parent - these needed to allow a merge()
+      operation to pass through without effect.
+
+    .. change::
+        :tags: orm
+        :tickets: 1863
+
+      Specifying a non-column based argument
+      for column_mapped_collection, including string,
+      text() etc., will raise an error message that
+      specifically asks for a column element, no longer
+      misleads with incorrect information about
+      text() or literal().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Similarly, for relationship(), foreign_keys,
+      remote_side, order_by - all column-based
+      expressions are enforced - lists of strings
+      are explicitly disallowed since this is a
+      very common error
+
+    .. change::
+        :tags: orm
+        :tickets: 1864
+
+      Dynamic attributes don't support collection
+      population - added an assertion for when
+      set_committed_value() is called, as well as
+      when joinedload() or subqueryload() options
+      are applied to a dynamic attribute, instead
+      of failure / silent failure.
+
+    .. change::
+        :tags: orm
+        :tickets: 1852
+
+      Fixed bug whereby generating a Query derived
+      from one which had the same column repeated
+      with different label names, typically
+      in some UNION situations, would fail to
+      propagate the inner columns completely to
+      the outer query.
+
+    .. change::
+        :tags: orm
+        :tickets: 1881
+
+      object_session() raises the proper
+      UnmappedInstanceError when presented with an
+      unmapped instance.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Applied further memoizations to calculated Mapper
+      properties, with significant (~90%) runtime mapper.py
+      call count reduction in heavily polymorphic mapping
+      configurations.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      mapper _get_col_to_prop private method used
+      by the versioning example is deprecated;
+      now use mapper.get_property_by_column() which
+      will remain the public method for this.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the versioning example works correctly now
+      if versioning on a col that was formerly
+      NULL.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Calling execute() on an alias() construct is pending
+      deprecation for 0.7, as it is not itself an
+      "executable" construct. It currently "proxies" its
+      inner element and is conditionally "executable" but
+      this is not the kind of ambiguity we like these days.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The execute() and scalar() methods of ClauseElement
+      are now moved appropriately to the Executable
+      subclass. ClauseElement.execute()/ scalar() are still
+      present and are pending deprecation in 0.7, but note
+      these would always raise an error anyway if you were
+      not an Executable (unless you were an alias(), see
+      previous note).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added basic math expression coercion for
+      Numeric->Integer,
+      so that resulting type is Numeric regardless
+      of the direction of the expression.
+
+    .. change::
+        :tags: sql
+        :tickets: 1855
+
+      Changed the scheme used to generate truncated
+      "auto" index names when using the "index=True"
+      flag on Column.   The truncation only takes
+      place with the auto-generated name, not one
+      that is user-defined (an error would be
+      raised instead), and the truncation scheme
+      itself is now based on a fragment of an md5
+      hash of the identifier name, so that multiple
+      indexes on columns with similar names still
+      have unique names.
+
+    .. change::
+        :tags: sql
+        :tickets: 1412
+
+      The generated index name also is based on
+      a "max index name length" attribute which is
+      separate from the "max identifier length" -
+      this to appease MySQL who has a max length
+      of 64 for index names, separate from their
+      overall max length of 255.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the text() construct, if placed in a column
+      oriented situation, will at least return NULLTYPE
+      for its type instead of None, allowing it to
+      be used a little more freely for ad-hoc column
+      expressions than before.   literal_column()
+      is still the better choice, however.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added full description of parent table/column,
+      target table/column in error message raised when
+      ForeignKey can't resolve target.
+
+    .. change::
+        :tags: sql
+        :tickets: 1865
+
+      Fixed bug whereby replacing composite foreign key
+      columns in a reflected table would cause an attempt
+      to remove the reflected constraint from the table
+      a second time, raising a KeyError.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the _Label construct, i.e. the one that is produced
+      whenever you say somecol.label(), now counts itself
+      in its "proxy_set" unioned with that of it's
+      contained column's proxy set, instead of
+      directly returning that of the contained column.
+      This allows column correspondence
+      operations which depend on the identity of the
+      _Labels themselves to return the correct result
+
+    .. change::
+        :tags: sql
+        :tickets: 1852
+
+      fixes ORM bug.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Calling fetchone() or similar on a result that
+      has already been exhausted, has been closed,
+      or is not a result-returning result now
+      raises ResourceClosedError, a subclass of
+      InvalidRequestError, in all cases, regardless
+      of backend.  Previously, some DBAPIs would
+      raise ProgrammingError (i.e. pysqlite), others
+      would return None leading to downstream breakages
+      (i.e. MySQL-python).
+
+    .. change::
+        :tags: engine
+        :tickets: 1894
+
+      Fixed bug in Connection whereby if a "disconnect"
+      event occurred in the "initialize" phase of the
+      first connection pool connect, an AttributeError
+      would be raised when the Connection would attempt
+      to invalidate the DBAPI connection.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Connection, ResultProxy, as well as Session use
+      ResourceClosedError for all "this
+      connection/transaction/result is closed" types of
+      errors.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Connection.invalidate() can be called more than
+      once and subsequent calls do nothing.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      if @classproperty is used with a regular class-bound
+      mapper property attribute, it will be called to get the
+      actual attribute value during initialization. Currently,
+      there's no advantage to using @classproperty on a column
+      or relationship attribute of a declarative class that
+      isn't a mixin - evaluation is at the same time as if
+      @classproperty weren't used. But here we at least allow
+      it to function as expected.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      Fixed bug where "Can't add additional column" message
+      would display the wrong name.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Fixed the psycopg2 dialect to use its
+      set_isolation_level() method instead of relying
+      upon the base "SET SESSION ISOLATION" command,
+      as psycopg2 resets the isolation level on each new
+      transaction otherwise.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Fixed "default schema" query to work with
+      pymssql backend.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      Fixed bug whereby a column default would fail to
+      reflect if the "default" keyword were lower case.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1879
+
+      Added ROWID type to the Oracle dialect, for those
+      cases where an explicit CAST might be needed.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1867
+
+      Oracle reflection of indexes has been tuned so
+      that indexes which include some or all primary
+      key columns, but not the same set of columns
+      as that of the primary key, are reflected.
+      Indexes which contain the identical columns
+      as that of the primary key are skipped within
+      reflection, as the index in that case is assumed
+      to be the auto-generated primary key index.
+      Previously, any index with PK columns present
+      would be skipped.  Thanks to Kent Bower
+      for the patch.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1868
+
+      Oracle now reflects the names of primary key
+      constraints - also thanks to Kent Bower.
+
+    .. change::
+        :tags: informix
+        :tickets: 1904
+
+      Applied patches from to get
+      basic Informix functionality up again.  We
+      rely upon end-user testing to ensure that
+      Informix is working to some degree.
+
+    .. change::
+        :tags: documentation
+        :tickets: 
+
+      The docs have been reorganized such that the "API
+      Reference" section is gone - all the docstrings from
+      there which were public API are moved into the
+      context of the main doc section that talks about it.
+      Main docs divided into "SQLAlchemy Core" and
+      "SQLAlchemy ORM" sections, mapper/relationship docs
+      have been broken out. Lots of sections rewritten
+      and/or reorganized.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      The beaker_caching example has been reorgnized
+      such that the Session, cache manager,
+      declarative_base are part of environment, and
+      custom cache code is portable and now within
+      "caching_query.py".  This allows the example to
+      be easier to "drop in" to existing projects.
+
+    .. change::
+        :tags: examples
+        :tickets: 1887
+
+      the history_meta versioning recipe sets "unique=False"
+      when copying columns, so that the versioning
+      table handles multiple rows with repeating values.
+
+.. changelog::
+    :version: 0.6.3
+    :released: Thu Jul 15 2010
+
+    .. change::
+        :tags: orm
+        :tickets: 1845
+
+      Removed errant many-to-many load in unitofwork
+      which triggered unnecessarily on expired/unloaded
+      collections. This load now takes place only if
+      passive_updates is False and the parent primary
+      key has changed, or if passive_deletes is False
+      and a delete of the parent has occurred.
+
+    .. change::
+        :tags: orm
+        :tickets: 1853
+
+      Column-entities (i.e. query(Foo.id)) copy their
+      state more fully when queries are derived from
+      themselves + a selectable (i.e. from_self(),
+      union(), etc.), so that join() and such have the
+      correct state to work from.
+
+    .. change::
+        :tags: orm
+        :tickets: 1853
+
+      Fixed bug where Query.join() would fail if
+      querying a non-ORM column then joining without
+      an on clause when a FROM clause is already
+      present, now raises a checked exception the
+      same way it does when the clause is not
+      present.
+
+    .. change::
+        :tags: orm
+        :tickets: 1142
+
+      Improved the check for an "unmapped class",
+      including the case where the superclass is mapped
+      but the subclass is not.  Any attempts to access
+      cls._sa_class_manager.mapper now raise
+      UnmappedClassError().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added "column_descriptions" accessor to Query,
+      returns a list of dictionaries containing
+      naming/typing information about the entities
+      the Query will return.  Can be helpful for
+      building GUIs on top of ORM queries.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1848
+
+      The _extract_error_code() method now works
+      correctly with each MySQL dialect (
+      MySQL-python, OurSQL, MySQL-Connector-Python,
+      PyODBC).  Previously,
+      the reconnect logic would fail for OperationalError
+      conditions, however since MySQLdb and OurSQL
+      have their own reconnect feature, there was no
+      symptom for these drivers here unless one
+      watched the logs.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1840
+
+      More tweaks to cx_oracle Decimal handling.
+      "Ambiguous" numerics with no decimal place
+      are coerced to int at the connection handler
+      level.  The advantage here is that ints
+      come back as ints without SQLA type
+      objects being involved and without needless
+      conversion to Decimal first.
+      
+      Unfortunately, some exotic subquery cases
+      can even see different types between
+      individual result rows, so the Numeric
+      handler, when instructed to return Decimal,
+      can't take full advantage of "native decimal"
+      mode and must run isinstance() on every value
+      to check if its Decimal already. Reopen of
+
+.. changelog::
+    :version: 0.6.2
+    :released: Tue Jul 06 2010
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.join() will check for a call of the
+      form query.join(target, clause_expression),
+      i.e. missing the tuple, and raise an informative
+      error message that this is the wrong calling form.
+
+    .. change::
+        :tags: orm
+        :tickets: 1824
+
+      Fixed bug regarding flushes on self-referential
+      bi-directional many-to-many relationships, where
+      two objects made to mutually reference each other
+      in one flush would fail to insert a row for both
+      sides.  Regression from 0.5.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the post_update feature of relationship() has been
+      reworked architecturally to integrate more closely
+      with the new 0.6 unit of work.  The motivation
+      for the change is so that multiple "post update"
+      calls, each affecting different foreign key
+      columns of the same row, are executed in a single
+      UPDATE statement, rather than one UPDATE
+      statement per column per row.   Multiple row
+      updates are also batched into executemany()s as
+      possible, while maintaining consistent row ordering.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.statement, Query.subquery(), etc. now transfer
+      the values of bind parameters, i.e. those specified
+      by query.params(), into the resulting SQL expression.
+      Previously the values would not be transferred
+      and bind parameters would come out as None.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Subquery-eager-loading now works with Query objects
+      which include params(), as well as get() Queries.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Can now call make_transient() on an instance that
+      is referenced by parent objects via many-to-one,
+      without the parent's foreign key value getting
+      temporarily set to None - this was a function
+      of the "detect primary key switch" flush handler.
+      It now ignores objects that are no longer
+      in the "persistent" state, and the parent's
+      foreign key identifier is left unaffected.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.order_by() now accepts False, which cancels
+      any existing order_by() state on the Query, allowing
+      subsequent generative methods to be called which do
+      not support ORDER BY.  This is not the same as the
+      already existing feature of passing None, which
+      suppresses any existing order_by() settings, including
+      those configured on the mapper.  False will make it
+      as though order_by() was never called, while
+      None is an active setting.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      An instance which is moved to "transient", has
+      an incomplete or missing set of primary key
+      attributes, and contains expired attributes, will
+      raise an InvalidRequestError if an expired attribute
+      is accessed, instead of getting a recursion overflow.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The make_transient() function is now in the generated
+      documentation.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      make_transient() removes all "loader" callables from
+      the state being made transient, removing any
+      "expired" state - all unloaded attributes reset back
+      to undefined, None/empty on access.
+
+    .. change::
+        :tags: sql
+        :tickets: 1822
+
+      The warning emitted by the Unicode and String types
+      with convert_unicode=True no longer embeds the actual
+      value passed.   This so that the Python warning
+      registry does not continue to grow in size, the warning
+      is emitted once as per the warning filter settings,
+      and large string values don't pollute the output.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug that would prevent overridden clause
+      compilation from working for "annotated" expression
+      elements, which are often generated by the ORM.
+
+    .. change::
+        :tags: sql
+        :tickets: 1400
+
+      The argument to "ESCAPE" of a LIKE operator or similar
+      is passed through render_literal_value(), which may
+      implement escaping of backslashes.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug in Enum type which blew away native_enum
+      flag when used with TypeDecorators or other adaption
+      scenarios.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Inspector hits bind.connect() when invoked to ensure
+      initialize has been called.  the internal name ".conn"
+      is changed to ".bind", since that's what it is.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Modified the internals of "column annotation" such that
+      a custom Column subclass can safely override
+      _constructor to return Column, for the purposes of
+      making "configurational" column classes that aren't
+      involved in proxying, etc.
+
+    .. change::
+        :tags: sql
+        :tickets: 1829
+
+      Column.copy() takes along the "unique" attribute
+      among others, fixes regarding declarative
+      mixins
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1400
+
+      render_literal_value() is overridden which escapes
+      backslashes, currently applies to the ESCAPE clause
+      of LIKE and similar expressions.
+      Ultimately this will have to detect the value of
+      "standard_conforming_strings" for full behavior.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1836
+
+      Won't generate "CREATE TYPE" / "DROP TYPE" if
+      using types.Enum on a PG version prior to 8.3 -
+      the supports_native_enum flag is fully
+      honored.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1826
+
+      MySQL dialect doesn't emit CAST() for MySQL version
+      detected < 4.0.2.  This allows the unicode
+      check on connect to proceed.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      MySQL dialect now detects NO_BACKSLASH_ESCAPES sql
+      mode, in addition to ANSI_QUOTES.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1400
+
+      render_literal_value() is overridden which escapes
+      backslashes, currently applies to the ESCAPE clause
+      of LIKE and similar expressions.   This behavior
+      is derived from detecting the value of
+      NO_BACKSLASH_ESCAPES.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1819
+
+      Fixed ora-8 compatibility flags such that they
+      don't cache a stale value from before the first
+      database connection actually occurs.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1840
+
+      Oracle's "native decimal" metadata begins to return
+      ambiguous typing information about numerics
+      when columns are embedded in subqueries as well
+      as when ROWNUM is consulted with subqueries, as we
+      do for limit/offset.  We've added these ambiguous
+      conditions to the cx_oracle "convert to Decimal()"
+      handler, so that we receive numerics as Decimal
+      in more cases instead of as floats.  These are
+      then converted, if requested, into Integer
+      or Float, or otherwise kept as the lossless
+      Decimal.
+
+    .. change::
+        :tags: mssql
+        :tickets: 1825
+
+      If server_version_info is outside the usual
+      range of (8, ), (9, ), (10, ), a warning is emitted
+      which suggests checking that the FreeTDS version
+      configuration is using 7.0 or 8.0, not 4.2.
+
+    .. change::
+        :tags: firebird
+        :tickets: 1823
+
+      Fixed incorrect signature in do_execute(), error
+      introduced in 0.6.1.
+
+    .. change::
+        :tags: firebird
+        :tickets: 1813
+
+      Firebird dialect adds CHAR, VARCHAR types which
+      accept a "charset" flag, to support Firebird
+      "CHARACTER SET" clause.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1805, 1796, 1751
+
+      Added support for @classproperty to provide
+      any kind of schema/mapping construct from a
+      declarative mixin, including columns with foreign
+      keys, relationships, column_property, deferred.
+      This solves all such issues on declarative mixins.
+      An error is raised if any MapperProperty subclass
+      is specified on a mixin without using @classproperty.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1821
+
+      a mixin class can now define a column that matches
+      one which is present on a __table__ defined on a
+      subclass.  It cannot, however, define one that is
+      not present in the __table__, and the error message
+      here now works.
+
+    .. change::
+        :tags: extension, compiler
+        :tickets: 1838
+
+      The 'default' compiler is automatically copied over
+      when overriding the compilation of a built in
+      clause construct, so no KeyError is raised if the
+      user-defined compiler is specific to certain
+      backends and compilation for a different backend
+      is invoked.
+
+    .. change::
+        :tags: documentation
+        :tickets: 1820
+
+      Added documentation for the Inspector.
+
+    .. change::
+        :tags: documentation
+        :tickets: 1830
+
+      Fixed @memoized_property and @memoized_instancemethod
+      decorators so that Sphinx documentation picks up
+      these attributes and methods, such as
+      ResultProxy.inserted_primary_key.
+
+.. changelog::
+    :version: 0.6.1
+    :released: Mon May 31 2010
+
+    .. change::
+        :tags: orm
+        :tickets: 1782
+
+      Fixed regression introduced in 0.6.0 involving improper
+      history accounting on mutable attributes.
+
+    .. change::
+        :tags: orm
+        :tickets: 1807
+
+      Fixed regression introduced in 0.6.0 unit of work refactor
+      that broke updates for bi-directional relationship()
+      with post_update=True.
+
+    .. change::
+        :tags: orm
+        :tickets: 1789
+
+      session.merge() will not expire attributes on the returned
+      instance if that instance is "pending".
+
+    .. change::
+        :tags: orm
+        :tickets: 1802
+
+      fixed __setstate__ method of CollectionAdapter to not
+      fail during deserialize where parent InstanceState not
+      yet unserialized.
+
+    .. change::
+        :tags: orm
+        :tickets: 1797
+
+      Added internal warning in case an instance without a
+      full PK happened to be expired and then was asked
+      to refresh.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added more aggressive caching to the mapper's usage of
+      UPDATE, INSERT, and DELETE expressions.  Assuming the
+      statement has no per-object SQL expressions attached,
+      the expression objects are cached by the mapper after
+      the first create, and their compiled form is stored
+      persistently in a cache dictionary for the duration of
+      the related Engine.  The cache is an LRUCache for the
+      rare case that a mapper receives an extremely
+      high number of different column patterns as UPDATEs.
+
+    .. change::
+        :tags: sql
+        :tickets: 1793
+
+      expr.in_() now accepts a text() construct as the argument.
+      Grouping parenthesis are added automatically, i.e. usage
+      is like `col.in_(text("select id from table"))`.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Columns of _Binary type (i.e. LargeBinary, BLOB, etc.)
+      will coerce a "basestring" on the right side into a
+      _Binary as well so that required DBAPI processing
+      takes place.
+
+    .. change::
+        :tags: sql
+        :tickets: 1801
+
+      Added table.add_is_dependent_on(othertable), allows manual
+      placement of dependency rules between two Table objects
+      for use within create_all(), drop_all(), sorted_tables.
+
+    .. change::
+        :tags: sql
+        :tickets: 1778
+
+      Fixed bug that prevented implicit RETURNING from functioning
+      properly with composite primary key that contained zeroes.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed errant space character when generating ADD CONSTRAINT
+      for a named UNIQUE constraint.
+
+    .. change::
+        :tags: sql
+        :tickets: 1571
+
+      Fixed "table" argument on constructor of ForeginKeyConstraint
+
+    .. change::
+        :tags: sql
+        :tickets: 1786
+
+      Fixed bug in connection pool cursor wrapper whereby if a
+      cursor threw an exception on close(), the logging of the
+      message would fail.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the _make_proxy() method of ColumnClause and Column now use
+      self.__class__ to determine the class of object to be returned
+      instead of hardcoding to ColumnClause/Column, making it slightly
+      easier to produce specific subclasses of these which work in
+      alias/subquery situations.
+
+    .. change::
+        :tags: sql
+        :tickets: 1798
+
+      func.XXX() doesn't inadvertently resolve to non-Function
+      classes (e.g. fixes func.text()).
+
+    .. change::
+        :tags: engines
+        :tickets: 1781
+
+      Fixed building the C extensions on Python 2.4.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Pool classes will reuse the same "pool_logging_name" setting
+      after a dispose() occurs.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Engine gains an "execution_options" argument and
+      update_execution_options() method, which will apply to
+      all connections generated by this engine.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1794
+
+      func.sysdate() emits "SYSDATE()", i.e. with the ending
+      parenthesis, on MySQL.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1812
+
+      Fixed concatenation of constraints when "PRIMARY KEY"
+      constraint gets moved to column level due to SQLite
+      AUTOINCREMENT keyword being rendered.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1775
+
+      Added a check for cx_oracle versions lower than version 5,
+      in which case the incompatible "output type handler" won't
+      be used.   This will impact decimal accuracy and some
+      unicode handling issues.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1790
+
+      Fixed use_ansi=False mode, which was producing broken
+      WHERE clauses in pretty much all cases.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1808
+
+      Re-established support for Oracle 8 with cx_oracle,
+      including that use_ansi is set to False automatically,
+      NVARCHAR2 and NCLOB are not rendered for Unicode,
+      "native unicode" check doesn't fail, cx_oracle
+      "native unicode" mode is disabled, VARCHAR() is emitted
+      with bytes count instead of char count.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1670
+
+      oracle_xe 5 doesn't accept a Python unicode object in
+      its connect string in normal Python 2.x mode - so we coerce
+      to str() directly.  non-ascii characters aren't supported
+      in connect strings here since we don't know what encoding
+      we could use.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1815
+
+      FOR UPDATE is emitted in the syntactically correct position
+      when limit/offset is used, i.e. the ROWNUM subquery.
+      However, Oracle can't really handle FOR UPDATE with ORDER BY
+      or with subqueries, so its still not very usable, but at
+      least SQLA gets the SQL past the Oracle parser.
+
+    .. change::
+        :tags: firebird
+        :tickets: 1521
+
+      Added a label to the query used within has_table() and
+      has_sequence() to work with older versions of Firebird
+      that don't provide labels for result columns.
+
+    .. change::
+        :tags: firebird
+        :tickets: 1779
+
+      Added integer coercion to the "type_conv" attribute when
+      passed via query string, so that it is properly interpreted
+      by Kinterbasdb.
+
+    .. change::
+        :tags: firebird
+        :tickets: 1646
+
+      Added 'connection shutdown' to the list of exception strings
+      which indicate a dropped connection.
+
+    .. change::
+        :tags: sqlsoup
+        :tickets: 1783
+
+      the SqlSoup constructor accepts a `base` argument which specifies
+      the base class to use for mapped classes, the default being
+      `object`.
+
+.. changelog::
+    :version: 0.6.0
+    :released: Sun Apr 18 2010
+
+    .. change::
+        :tags: orm
+        :tickets: 1742, 1081
+
+      Unit of work internals have been rewritten.  Units of work
+      with large numbers of objects interdependent objects
+      can now be flushed without recursion overflows
+      as there is no longer reliance upon recursive calls.  The number of internal structures now stays
+      constant for a particular session state, regardless of
+      how many relationships are present on mappings.  The flow
+      of events now corresponds to a linear list of steps,
+      generated by the mappers and relationships based on actual
+      work to be done, filtered through a single topological sort
+      for correct ordering.  Flush actions are assembled using
+      far fewer steps and less memory.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Along with the UOW rewrite, this also removes an issue
+      introduced in 0.6beta3 regarding topological cycle detection
+      for units of work with long dependency cycles.  We now use
+      an algorithm written by Guido (thanks Guido!).
+
+    .. change::
+        :tags: orm
+        :tickets: 1764
+
+      one-to-many relationships now maintain a list of positive
+      parent-child associations within the flush, preventing
+      previous parents marked as deleted from cascading a
+      delete or NULL foreign key set on those child objects,
+      despite the end-user not removing the child from the old
+      association.
+
+    .. change::
+        :tags: orm
+        :tickets: 1495
+
+      A collection lazy load will switch off default
+      eagerloading on the reverse many-to-one side, since
+      that loading is by definition unnecessary.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session.refresh() now does an equivalent expire()
+      on the given instance first, so that the "refresh-expire"
+      cascade is propagated.   Previously, refresh() was
+      not affected in any way by the presence of "refresh-expire"
+      cascade.   This is a change in behavior versus that
+      of 0.6beta2, where the "lockmode" flag passed to refresh()
+      would cause a version check to occur.  Since the instance
+      is first expired, refresh() always upgrades the object
+      to the most recent version.
+
+    .. change::
+        :tags: orm
+        :tickets: 1754
+
+      The 'refresh-expire' cascade, when reaching a pending object,
+      will expunge the object if the cascade also includes
+      "delete-orphan", or will simply detach it otherwise.
+
+    .. change::
+        :tags: orm
+        :tickets: 1756
+
+      id(obj) is no longer used internally within topological.py,
+      as the sorting functions now require hashable objects
+      only.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The ORM will set the docstring of all generated descriptors
+      to None by default.  This can be overridden using 'doc'
+      (or if using Sphinx, attribute docstrings work too).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added kw argument 'doc' to all mapper property callables
+      as well as Column().  Will assemble the string 'doc' as
+      the '__doc__' attribute on the descriptor.
+
+    .. change::
+        :tags: orm
+        :tickets: 1761
+
+      Usage of version_id_col on a backend that supports
+      cursor.rowcount for execute() but not executemany() now works
+      when a delete is issued (already worked for saves, since those
+      don't use executemany()). For a backend that doesn't support
+      cursor.rowcount at all, a warning is emitted the same
+      as with saves.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The ORM now short-term caches the "compiled" form of
+      insert() and update() constructs when flushing lists of
+      objects of all the same class, thereby avoiding redundant
+      compilation per individual INSERT/UPDATE within an
+      individual flush() call.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      internal getattr(), setattr(), getcommitted() methods
+      on ColumnProperty, CompositeProperty, RelationshipProperty
+      have been underscored (i.e. are private), signature has
+      changed.
+
+    .. change::
+        :tags: engines
+        :tickets: 1757
+
+      The C extension now also works with DBAPIs which use custom
+      sequences as row (and not only tuples).
+
+    .. change::
+        :tags: sql
+        :tickets: 1755
+
+      Restored some bind-labeling logic from 0.5 which ensures
+      that tables with column names that overlap another column
+      of the form "<tablename>_<columnname>" won't produce
+      errors if column._label is used as a bind name during
+      an UPDATE.  Test coverage which wasn't present in 0.5
+      has been added.
+
+    .. change::
+        :tags: sql
+        :tickets: 1729
+
+      somejoin.select(fold_equivalents=True) is no longer
+      deprecated, and will eventually be rolled into a more
+      comprehensive version of the feature for.
+
+    .. change::
+        :tags: sql
+        :tickets: 1759
+
+      the Numeric type raises an *enormous* warning when expected
+      to convert floats to Decimal from a DBAPI that returns floats.
+      This includes SQLite, Sybase, MS-SQL.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed an error in expression typing which caused an endless
+      loop for expressions with two NULL types.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug in execution_options() feature whereby the existing
+      Transaction and other state information from the parent
+      connection would not be propagated to the sub-connection.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added new 'compiled_cache' execution option.  A dictionary
+      where Compiled objects will be cached when the Connection
+      compiles a clause expression into a dialect- and parameter-
+      specific Compiled object.  It is the user's responsibility to
+      manage the size of this dictionary, which will have keys
+      corresponding to the dialect, clause element, the column
+      names within the VALUES or SET clause of an INSERT or UPDATE,
+      as well as the "batch" mode for an INSERT or UPDATE statement.
+
+    .. change::
+        :tags: sql
+        :tickets: 1769
+
+      Added get_pk_constraint() to reflection.Inspector, similar
+      to get_primary_keys() except returns a dict that includes the
+      name of the constraint, for supported backends (PG so far).
+
+    .. change::
+        :tags: sql
+        :tickets: 1771
+
+      Table.create() and Table.drop() no longer apply metadata-
+      level create/drop events.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      the compiler extension now allows @compiles decorators
+      on base classes that extend to child classes, @compiles
+      decorators on child classes that aren't broken by a
+      @compiles decorator on the base class.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      Declarative will raise an informative error message
+      if a non-mapped class attribute is referenced in the
+      string-based relationship() arguments.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      Further reworked the "mixin" logic in declarative to
+      additionally allow __mapper_args__ as a @classproperty
+      on a mixin, such as to dynamically assign polymorphic_identity.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1071
+
+      Postgresql now reflects sequence names associated with
+      SERIAL columns correctly, after the name of of the sequence
+      has been changed.  Thanks to Kumar McMillan for the patch.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Repaired missing import in psycopg2._PGNumeric type when
+      unknown numeric is received.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      psycopg2/pg8000 dialects now aware of REAL[], FLOAT[],
+      DOUBLE_PRECISION[], NUMERIC[] return types without
+      raising an exception.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1769
+
+      Postgresql reflects the name of primary key constraints,
+      if one exists.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Now using cx_oracle output converters so that the
+      DBAPI returns natively the kinds of values we prefer:
+
+    .. change::
+        :tags: oracle
+        :tickets: 1759
+
+      NUMBER values with positive precision + scale convert
+      to cx_oracle.STRING and then to Decimal.   This
+      allows perfect precision for the Numeric type when
+      using cx_oracle.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      STRING/FIXED_CHAR now convert to unicode natively.
+      SQLAlchemy's String types then don't need to
+      apply any kind of conversions.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      The functionality of result.rowcount can be disabled on a
+      per-engine basis by setting 'enable_rowcount=False'
+      on create_engine().  Normally, cursor.rowcount is called
+      after any UPDATE or DELETE statement unconditionally,
+      because the cursor is then closed and Firebird requires
+      an open cursor in order to get a rowcount.  This
+      call is slightly expensive however so it can be disabled.
+      To re-enable on a per-execution basis, the
+      'enable_rowcount=True' execution option may be used.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      Updated attribute_shard.py example to use a more robust
+      method of searching a Query for binary expressions which
+      compare columns against literal values.
+
+.. changelog::
+    :version: 0.6beta3
+    :released: Sun Mar 28 2010
+
+    .. change::
+        :tags: orm
+        :tickets: 1675
+
+      Major feature: Added new "subquery" loading capability to
+      relationship().   This is an eager loading option which
+      generates a second SELECT for each collection represented
+      in a query, across all parents at once.  The query
+      re-issues the original end-user query wrapped in a subquery,
+      applies joins out to the target collection, and loads
+      all those collections fully in one result, similar to
+      "joined" eager loading but using all inner joins and not
+      re-fetching full parent rows repeatedly (as most DBAPIs seem
+      to do, even if columns are skipped).   Subquery loading is
+      available at mapper config level using "lazy='subquery'" and
+      at the query options level using "subqueryload(props..)",
+      "subqueryload_all(props...)".
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      To accomodate the fact that there are now two kinds of eager
+      loading available, the new names for eagerload() and
+      eagerload_all() are joinedload() and joinedload_all().  The
+      old names will remain as synonyms for the foreseeable future.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The "lazy" flag on the relationship() function now accepts
+      a string argument for all kinds of loading: "select", "joined",
+      "subquery", "noload" and "dynamic", where the default is now
+      "select".  The old values of True/
+      False/None still retain their usual meanings and will remain
+      as synonyms for the foreseeable future.
+
+    .. change::
+        :tags: orm
+        :tickets: 921
+
+      Added with_hint() method to Query() construct.  This calls
+      directly down to select().with_hint() and also accepts
+      entities as well as tables and aliases.  See with_hint() in the
+      SQL section below.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in Query whereby calling q.join(prop).from_self(...).
+      join(prop) would fail to render the second join outside the
+      subquery, when joining on the same criterion as was on the
+      inside.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in Query whereby the usage of aliased() constructs
+      would fail if the underlying table (but not the actual alias)
+      were referenced inside the subquery generated by
+      q.from_self() or q.select_from().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug which affected all eagerload() and similar options
+      such that "remote" eager loads, i.e. eagerloads off of a lazy
+      load such as query(A).options(eagerload(A.b, B.c))
+      wouldn't eagerload anything, but using eagerload("b.c") would
+      work fine.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query gains an add_columns(*columns) method which is a multi-
+      version of add_column(col).  add_column(col) is future
+      deprecated.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.join() will detect if the end result will be
+      "FROM A JOIN A", and will raise an error if so.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.join(Cls.propname, from_joinpoint=True) will check more
+      carefully that "Cls" is compatible with the current joinpoint,
+      and act the same way as Query.join("propname", from_joinpoint=True)
+      in that regard.
+
+    .. change::
+        :tags: sql
+        :tickets: 921
+
+      Added with_hint() method to select() construct.  Specify
+      a table/alias, hint text, and optional dialect name, and
+      "hints" will be rendered in the appropriate place in the
+      statement.  Works for Oracle, Sybase, MySQL.
+
+    .. change::
+        :tags: sql
+        :tickets: 1747
+
+      Fixed bug introduced in 0.6beta2 where column labels would
+      render inside of column expressions already assigned a label.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 877
+
+      The psycopg2 dialect will log NOTICE messages via the
+      "sqlalchemy.dialects.postgresql" logger name.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 997
+
+      the TIME and TIMESTAMP types are now availble from the
+      postgresql dialect directly, which add the PG-specific
+      argument 'precision' to both.   'precision' and
+      'timezone' are correctly reflected for both TIME and
+      TIMEZONE types.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1752
+
+      No longer guessing that TINYINT(1) should be BOOLEAN
+      when reflecting - TINYINT(1) is returned.  Use Boolean/
+      BOOLEAN in table definition to get boolean conversion
+      behavior.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1744
+
+      The Oracle dialect will issue VARCHAR type definitions
+      using character counts, i.e. VARCHAR2(50 CHAR), so that
+      the column is sized in terms of characters and not bytes.
+      Column reflection of character types will also use
+      ALL_TAB_COLUMNS.CHAR_LENGTH instead of
+      ALL_TAB_COLUMNS.DATA_LENGTH.  Both of these behaviors take
+      effect when the server version is 9 or higher - for
+      version 8, the old behaviors are used.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1746
+
+      Using a mixin won't break if the mixin implements an
+      unpredictable __getattribute__(), i.e. Zope interfaces.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1749
+
+      Using @classdecorator and similar on mixins to define
+      __tablename__, __table_args__, etc. now works if
+      the method references attributes on the ultimate
+      subclass.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1751
+
+      relationships and columns with foreign keys aren't
+      allowed on declarative mixins, sorry.
+
+    .. change::
+        :tags: ext
+        :tickets: 
+
+      The sqlalchemy.orm.shard module now becomes an extension,
+      sqlalchemy.ext.horizontal_shard.   The old import
+      works with a deprecation warning.
+
+.. changelog::
+    :version: 0.6beta2
+    :released: Sat Mar 20 2010
+
+    .. change::
+        :tags: py3k
+        :tickets: 
+
+      Improved the installation/test setup regarding Python 3,
+      now that Distribute runs on Py3k.   distribute_setup.py
+      is now included.  See README.py3k for Python 3 installation/
+      testing instructions.
+
+    .. change::
+        :tags: orm
+        :tickets: 1740
+
+      The official name for the relation() function is now
+      relationship(), to eliminate confusion over the relational
+      algebra term.  relation() however will remain available
+      in equal capacity for the foreseeable future.
+
+    .. change::
+        :tags: orm
+        :tickets: 1692
+
+      Added "version_id_generator" argument to Mapper, this is a
+      callable that, given the current value of the "version_id_col",
+      returns the next version number.  Can be used for alternate
+      versioning schemes such as uuid, timestamps.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "lockmode" kw argument to Session.refresh(), will
+      pass through the string value to Query the same as
+      in with_lockmode(), will also do version check for a
+      version_id_col-enabled mapping.
+
+    .. change::
+        :tags: orm
+        :tickets: 1188
+
+      Fixed bug whereby calling query(A).join(A.bs).add_entity(B)
+      in a joined inheritance scenario would double-add B as a
+      target and produce an invalid query.
+
+    .. change::
+        :tags: orm
+        :tickets: 1674
+
+      Fixed bug in session.rollback() which involved not removing
+      formerly "pending" objects from the session before
+      re-integrating "deleted" objects, typically occured with
+      natural primary keys. If there was a primary key conflict
+      between them, the attach of the deleted would fail
+      internally. The formerly "pending" objects are now expunged
+      first.
+
+    .. change::
+        :tags: orm
+        :tickets: 1719
+
+      Removed a lot of logging that nobody really cares about,
+      logging that remains will respond to live changes in the
+      log level.  No significant overhead is added.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in session.merge() which prevented dict-like
+      collections from merging.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      session.merge() works with relations that specifically
+      don't include "merge" in their cascade options - the target
+      is ignored completely.
+
+    .. change::
+        :tags: orm
+        :tickets: 1681
+
+      session.merge() will not expire existing scalar attributes
+      on an existing target if the target has a value for that
+      attribute, even if the incoming merged doesn't have
+      a value for the attribute.  This prevents unnecessary loads
+      on existing items.  Will still mark the attr as expired
+      if the destination doesn't have the attr, though, which
+      fulfills some contracts of deferred cols.
+
+    .. change::
+        :tags: orm
+        :tickets: 1680
+
+      The "allow_null_pks" flag is now called "allow_partial_pks",
+      defaults to True, acts like it did in 0.5 again.  Except,
+      it also is implemented within merge() such that a SELECT
+      won't be issued for an incoming instance with partially
+      NULL primary key if the flag is False.
+
+    .. change::
+        :tags: orm
+        :tickets: 1737
+
+      Fixed bug in 0.6-reworked "many-to-one" optimizations
+      such that a many-to-one that is against a non-primary key
+      column on the remote table (i.e. foreign key against a
+      UNIQUE column) will pull the "old" value in from the
+      database during a change, since if it's in the session
+      we will need it for proper history/backref accounting,
+      and we can't pull from the local identity map on a
+      non-primary key column.
+
+    .. change::
+        :tags: orm
+        :tickets: 1731
+
+      fixed internal error which would occur if calling has()
+      or similar complex expression on a single-table inheritance
+      relation().
+
+    .. change::
+        :tags: orm
+        :tickets: 1688
+
+      query.one() no longer applies LIMIT to the query, this to
+      ensure that it fully counts all object identities present
+      in the result, even in the case where joins may conceal
+      multiple identities for two or more rows.  As a bonus,
+      one() can now also be called with a query that issued
+      from_statement() to start with since it no longer modifies
+      the query.
+
+    .. change::
+        :tags: orm
+        :tickets: 1727
+
+      query.get() now returns None if queried for an identifier
+      that is present in the identity map with a different class
+      than the one requested, i.e. when using polymorphic loading.
+
+    .. change::
+        :tags: orm
+        :tickets: 1706
+
+      A major fix in query.join(), when the "on" clause is an
+      attribute of an aliased() construct, but there is already
+      an existing join made out to a compatible target, query properly
+      joins to the right aliased() construct instead of sticking
+      onto the right side of the existing join.
+
+    .. change::
+        :tags: orm
+        :tickets: 1362
+
+      Slight improvement to the fix for to not issue
+      needless updates of the primary key column during a so-called
+      "row switch" operation, i.e. add + delete of two objects
+      with the same PK.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Now uses sqlalchemy.orm.exc.DetachedInstanceError when an
+      attribute load or refresh action fails due to object
+      being detached from any Session.   UnboundExecutionError
+      is specific to engines bound to sessions and statements.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query called in the context of an expression will render
+      disambiguating labels in all cases.    Note that this does
+      not apply to the existing .statement and .subquery()
+      accessor/method, which still honors the .with_labels()
+      setting that defaults to False.
+
+    .. change::
+        :tags: orm
+        :tickets: 1676
+
+      Query.union() retains disambiguating labels within the
+      returned statement, thus avoiding various SQL composition
+      errors which can result from column name conflicts.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed bug in attribute history that inadvertently invoked
+      __eq__ on mapped instances.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Some internal streamlining of object loading grants a
+      small speedup for large results, estimates are around
+      10-15%.   Gave the "state" internals a good solid
+      cleanup with less complexity, datamembers,
+      method calls, blank dictionary creates.
+
+    .. change::
+        :tags: orm
+        :tickets: 1689
+
+      Documentation clarification for query.delete()
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed cascade bug in many-to-one relation() when attribute
+      was set to None, introduced in r6711 (cascade deleted
+      items into session during add()).
+
+    .. change::
+        :tags: orm
+        :tickets: 1736
+
+      Calling query.order_by() or query.distinct() before calling
+      query.select_from(), query.with_polymorphic(), or
+      query.from_statement() raises an exception now instead of
+      silently dropping those criterion.
+
+    .. change::
+        :tags: orm
+        :tickets: 1735
+
+      query.scalar() now raises an exception if more than one
+      row is returned.  All other behavior remains the same.
+
+    .. change::
+        :tags: orm
+        :tickets: 1692
+
+      Fixed bug which caused "row switch" logic, that is an
+      INSERT and DELETE replaced by an UPDATE, to fail when
+      version_id_col was in use.
+
+    .. change::
+        :tags: sql
+        :tickets: 1714
+
+      join() will now simulate a NATURAL JOIN by default.  Meaning,
+      if the left side is a join, it will attempt to join the right
+      side to the rightmost side of the left first, and not raise
+      any exceptions about ambiguous join conditions if successful
+      even if there are further join targets across the rest of
+      the left.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The most common result processors conversion function were
+      moved to the new "processors" module.  Dialect authors are
+      encouraged to use those functions whenever they correspond
+      to their needs instead of implementing custom ones.
+
+    .. change::
+        :tags: sql
+        :tickets: 1694, 1698
+
+      SchemaType and subclasses Boolean, Enum are now serializable,
+      including their ddl listener and other event callables.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Some platforms will now interpret certain literal values
+      as non-bind parameters, rendered literally into the SQL
+      statement.   This to support strict SQL-92 rules that are
+      enforced by some platforms including MS-SQL and Sybase.
+      In this model, bind parameters aren't allowed in the
+      columns clause of a SELECT, nor are certain ambiguous
+      expressions like "?=?".  When this mode is enabled, the base
+      compiler will render the binds as inline literals, but only across
+      strings and numeric values.  Other types such as dates
+      will raise an error, unless the dialect subclass defines
+      a literal rendering function for those.  The bind parameter
+      must have an embedded literal value already or an error
+      is raised (i.e. won't work with straight bindparam('x')).
+      Dialects can also expand upon the areas where binds are not
+      accepted, such as within argument lists of functions
+      (which don't work on MS-SQL when native SQL binding is used).
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added "unicode_errors" parameter to String, Unicode, etc.
+      Behaves like the 'errors' keyword argument to
+      the standard library's string.decode() functions.   This flag
+      requires that `convert_unicode` is set to `"force"` - otherwise,
+      SQLAlchemy is not guaranteed to handle the task of unicode
+      conversion.   Note that this flag adds significant performance
+      overhead to row-fetching operations for backends that already
+      return unicode objects natively (which most DBAPIs do).  This
+      flag should only be used as an absolute last resort for reading
+      strings from a column with varied or corrupted encodings,
+      which only applies to databases that accept invalid encodings
+      in the first place (i.e. MySQL. *not* PG, Sqlite, etc.)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added math negation operator support, -x.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      FunctionElement subclasses are now directly executable the
+      same way any func.foo() construct is, with automatic
+      SELECT being applied when passed to execute().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The "type" and "bind" keyword arguments of a func.foo()
+      construct are now local to "func." constructs and are
+      not part of the FunctionElement base class, allowing
+      a "type" to be handled in a custom constructor or
+      class-level variable.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Restored the keys() method to ResultProxy.
+
+    .. change::
+        :tags: sql
+        :tickets: 1647, 1683
+
+      The type/expression system now does a more complete job
+      of determining the return type from an expression
+      as well as the adaptation of the Python operator into
+      a SQL operator, based on the full left/right/operator
+      of the given expression.  In particular
+      the date/time/interval system created for Postgresql
+      EXTRACT in has now been generalized into
+      the type system.   The previous behavior which often
+      occured of an expression "column + literal" forcing
+      the type of "literal" to be the same as that of "column"
+      will now usually not occur - the type of
+      "literal" is first derived from the Python type of the
+      literal, assuming standard native Python types + date
+      types, before falling back to that of the known type
+      on the other side of the expression.  If the
+      "fallback" type is compatible (i.e. CHAR from String),
+      the literal side will use that.  TypeDecorator
+      types override this by default to coerce the "literal"
+      side unconditionally, which can be changed by implementing
+      the coerce_compared_value() method. Also part of.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Made sqlalchemy.sql.expressions.Executable part of public
+      API, used for any expression construct that can be sent to
+      execute().  FunctionElement now inherits Executable so that
+      it gains execution_options(), which are also propagated
+      to the select() that's generated within execute().
+      Executable in turn subclasses _Generative which marks
+      any ClauseElement that supports the @_generative
+      decorator - these may also become "public" for the benefit
+      of the compiler extension at some point.
+
+    .. change::
+        :tags: sql
+        :tickets: 1579
+
+      A change to the solution for - an end-user
+      defined bind parameter name that directly conflicts with
+      a column-named bind generated directly from the SET or
+      VALUES clause of an update/insert generates a compile error.
+      This reduces call counts and eliminates some cases where
+      undesirable name conflicts could still occur.
+
+    .. change::
+        :tags: sql
+        :tickets: 1705
+
+      Column() requires a type if it has no foreign keys (this is
+      not new).  An error is now raised if a Column() has no type
+      and no foreign keys.
+
+    .. change::
+        :tags: sql
+        :tickets: 1717
+
+      the "scale" argument of the Numeric() type is honored when
+      coercing a returned floating point value into a string
+      on its way to Decimal - this allows accuracy to function
+      on SQLite, MySQL.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the copy() method of Column now copies over uninitialized
+      "on table attach" events.  Helps with the new declarative
+      "mixin" capability.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Added an optional C extension to speed up the sql layer by
+      reimplementing RowProxy and the most common result processors.
+      The actual speedups will depend heavily on your DBAPI and
+      the mix of datatypes used in your tables, and can vary from
+      a 30% improvement to more than 200%.  It also provides a modest
+      (~15-20%) indirect improvement to ORM speed for large queries.
+      Note that it is *not* built/installed by default.
+      See README for installation instructions.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      the execution sequence pulls all rowcount/last inserted ID
+      info from the cursor before commit() is called on the
+      DBAPI connection in an "autocommit" scenario.  This helps
+      mxodbc with rowcount and is probably a good idea overall.
+
+    .. change::
+        :tags: engines
+        :tickets: 1719
+
+      Opened up logging a bit such that isEnabledFor() is called
+      more often, so that changes to the log level for engine/pool
+      will be reflected on next connect.   This adds a small
+      amount of method call overhead.  It's negligible and will make
+      life a lot easier for all those situations when logging
+      just happens to be configured after create_engine() is called.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      The assert_unicode flag is deprecated.  SQLAlchemy will raise
+      a warning in all cases where it is asked to encode a non-unicode
+      Python string, as well as when a Unicode or UnicodeType type
+      is explicitly passed a bytestring.  The String type will do nothing
+      for DBAPIs that already accept Python unicode objects.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Bind parameters are sent as a tuple instead of a list. Some
+      backend drivers will not accept bind parameters as a list.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      threadlocal engine wasn't properly closing the connection
+      upon close() - fixed that.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Transaction object doesn't rollback or commit if it isn't
+      "active", allows more accurate nesting of begin/rollback/commit.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Python unicode objects as binds result in the Unicode type,
+      not string, thus eliminating a certain class of unicode errors
+      on drivers that don't support unicode binds.
+
+    .. change::
+        :tags: engines
+        :tickets: 1555
+
+      Added "logging_name" argument to create_engine(), Pool() constructor
+      as well as "pool_logging_name" argument to create_engine() which
+      filters down to that of Pool.   Issues the given string name
+      within the "name" field of logging messages instead of the default
+      hex identifier string.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      The visit_pool() method of Dialect is removed, and replaced with
+      on_connect().  This method returns a callable which receives
+      the raw DBAPI connection after each one is created.   The callable
+      is assembled into a first_connect/connect pool listener by the
+      connection strategy if non-None.   Provides a simpler interface
+      for dialects.
+
+    .. change::
+        :tags: engines
+        :tickets: 1728
+
+      StaticPool now initializes, disposes and recreates without
+      opening a new connection - the connection is only opened when
+      first requested. dispose() also works on AssertionPool now.
+
+    .. change::
+        :tags: ticket: 1673, metadata
+        :tickets: 
+
+      Added the ability to strip schema information when using
+      "tometadata" by passing "schema=None" as an argument. If schema
+      is not specified then the table's schema is retained.
+
+    .. change::
+        :tags: declarative
+        :tickets: 
+
+      DeclarativeMeta exclusively uses cls.__dict__ (not dict_)
+      as the source of class information; _as_declarative exclusively
+      uses the  dict_ passed to it as the source of class information
+      (which when using DeclarativeMeta is cls.__dict__).  This should
+      in theory make it easier for custom metaclasses to modify
+      the state passed into _as_declarative.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1707
+
+      declarative now accepts mixin classes directly, as a means
+      to provide common functional and column-based elements on
+      all subclasses, as well as a means to propagate a fixed
+      set of __table_args__ or __mapper_args__ to subclasses.
+      For custom combinations of __table_args__/__mapper_args__ from
+      an inherited mixin to local, descriptors can now be used.
+      New details are all up in the Declarative documentation.
+      Thanks to Chris Withers for putting up with my strife
+      on this.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1393
+
+      the __mapper_args__ dict is copied when propagating to a subclass,
+      and is taken straight off the class __dict__ to avoid any
+      propagation from the parent.  mapper inheritance already
+      propagates the things you want from the parent mapper.
+
+    .. change::
+        :tags: declarative
+        :tickets: 1732
+
+      An exception is raised when a single-table subclass specifies
+      a column that is already present on the base class.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1655
+
+      Fixed reflection bug whereby when COLLATE was present,
+      nullable flag and server defaults would not be reflected.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Fixed reflection of TINYINT(1) "boolean" columns defined with
+      integer flags like UNSIGNED.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1668
+
+      Further fixes for the mysql-connector dialect.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1496
+
+      Composite PK table on InnoDB where the "autoincrement" column
+      isn't first will emit an explicit "KEY" phrase within
+      CREATE TABLE thereby avoiding errors.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1634
+
+      Added reflection/create table support for a wide range
+      of MySQL keywords.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1580
+
+      Fixed import error which could occur reflecting tables on
+      a Windows host
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Re-established support for the pymssql dialect.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Various fixes for implicit returning, reflection,
+      etc. - the MS-SQL dialects aren't quite complete
+      in 0.6 yet (but are close)
+
+    .. change::
+        :tags: mssql
+        :tickets: 1710
+
+      Added basic support for mxODBC.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Removed the text_as_varchar option.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      "out" parameters require a type that is supported by
+      cx_oracle.  An error will be raised if no cx_oracle
+      type can be found.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Oracle 'DATE' now does not perform any result processing,
+      as the DATE type in Oracle stores full date+time objects,
+      that's what you'll get.  Note that the generic types.Date
+      type *will* still call value.date() on incoming values,
+      however.  When reflecting a table, the reflected type
+      will be 'DATE'.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1670
+
+      Added preliminary support for Oracle's WITH_UNICODE
+      mode.  At the very least this establishes initial
+      support for cx_Oracle with Python 3.  When WITH_UNICODE
+      mode is used in Python 2.xx, a large and scary warning
+      is emitted asking that the user seriously consider
+      the usage of this difficult mode of operation.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1712
+
+      The except_() method now renders as MINUS on Oracle,
+      which is more or less equivalent on that platform.
+
+    .. change::
+        :tags: oracle
+        :tickets: 651
+
+      Added support for rendering and reflecting
+      TIMESTAMP WITH TIME ZONE, i.e. TIMESTAMP(timezone=True).
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Oracle INTERVAL type can now be reflected.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1685
+
+      Added "native_datetime=True" flag to create_engine().
+      This will cause the DATE and TIMESTAMP types to skip
+      all bind parameter and result row processing, under
+      the assumption that PARSE_DECLTYPES has been enabled
+      on the connection.  Note that this is not entirely
+      compatible with the "func.current_date()", which
+      will be returned as a string.
+
+    .. change::
+        :tags: sybase
+        :tickets: 
+
+      Implemented a preliminary working dialect for Sybase,
+      with sub-implementations for Python-Sybase as well
+      as Pyodbc.  Handles table
+      creates/drops and basic round trip functionality.
+      Does not yet include reflection or comprehensive
+      support of unicode/special expressions/etc.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      Changed the beaker cache example a bit to have a separate
+      RelationCache option for lazyload caching.  This object
+      does a lookup among any number of potential attributes
+      more efficiently by grouping several into a common structure.
+      Both FromCache and RelationCache are simpler individually.
+
+    .. change::
+        :tags: documentation
+        :tickets: 1700
+
+      Major cleanup work in the docs to link class, function, and
+      method names into the API docs.
+
+.. changelog::
+    :version: 0.6beta1
+    :released: Wed Feb 03 2010
+
+    .. change::
+        :tags: release, major
+        :tickets: 
+
+      For the full set of feature descriptions, see
+      http://www.sqlalchemy.org/trac/wiki/06Migration .
+      This document is a work in progress.
+
+    .. change::
+        :tags: release, major
+        :tickets: 
+
+      All bug fixes and feature enhancements from the most
+      recent 0.5 version and below are also included within 0.6.
+
+    .. change::
+        :tags: release, major
+        :tickets: 
+
+      Platforms targeted now include Python 2.4/2.5/2.6, Python
+      3.1, Jython2.5.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Changes to query.update() and query.delete():
+        - the 'expire' option on query.update() has been renamed to
+          'fetch', thus matching that of query.delete().
+          'expire' is deprecated and issues a warning.
+      
+        - query.update() and query.delete() both default to
+          'evaluate' for the synchronize strategy.
+      
+        - the 'synchronize' strategy for update() and delete()
+          raises an error on failure. There is no implicit fallback
+          onto "fetch". Failure of evaluation is based on the
+          structure of criteria, so success/failure is deterministic
+          based on code structure.
+
+    .. change::
+        :tags: orm
+        :tickets: 1186, 1492, 1544
+
+      Enhancements on many-to-one relations:
+        - many-to-one relations now fire off a lazyload in fewer
+          cases, including in most cases will not fetch the "old"
+          value when a new one is replaced.
+      
+        - many-to-one relation to a joined-table subclass now uses
+          get() for a simple load (known as the "use_get"
+          condition), i.e. Related->Sub(Base), without the need to
+          redefine the primaryjoin condition in terms of the base
+          table.
+      
+        - specifying a foreign key with a declarative column, i.e.
+          ForeignKey(MyRelatedClass.id) doesn't break the "use_get"
+          condition from taking place
+      
+        - relation(), eagerload(), and eagerload_all() now feature
+          an option called "innerjoin". Specify `True` or `False` to
+          control whether an eager join is constructed as an INNER
+          or OUTER join. Default is `False` as always. The mapper
+          options will override whichever setting is specified on
+          relation(). Should generally be set for many-to-one, not
+          nullable foreign key relations to allow improved join
+          performance.
+      
+        - the behavior of eagerloading such that the main query is
+          wrapped in a subquery when LIMIT/OFFSET are present now
+          makes an exception for the case when all eager loads are
+          many-to-one joins. In those cases, the eager joins are
+          against the parent table directly along with the
+          limit/offset without the extra overhead of a subquery,
+          since a many-to-one join does not add rows to the result.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Enhancements / Changes on Session.merge():
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "dont_load=True" flag on Session.merge() is deprecated
+      and is now "load=False".
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Session.merge() is performance optimized, using half the
+      call counts for "load=False" mode compared to 0.5 and
+      significantly fewer SQL queries in the case of collections
+      for "load=True" mode.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      merge() will not issue a needless merge of attributes if the
+      given instance is the same instance which is already present.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      merge() now also merges the "options" associated with a given
+      state, i.e. those passed through query.options() which follow
+      along with an instance, such as options to eagerly- or
+      lazyily- load various attributes.   This is essential for
+      the construction of highly integrated caching schemes.  This
+      is a subtle behavioral change vs. 0.5.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      A bug was fixed regarding the serialization of the "loader
+      path" present on an instance's state, which is also necessary
+      when combining the usage of merge() with serialized state
+      and associated options that should be preserved.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The all new merge() is showcased in a new comprehensive
+      example of how to integrate Beaker with SQLAlchemy.  See
+      the notes in the "examples" note below.
+
+    .. change::
+        :tags: orm
+        :tickets: 1362
+
+      Primary key values can now be changed on a joined-table inheritance
+      object, and ON UPDATE CASCADE will be taken into account when
+      the flush happens.  Set the new "passive_updates" flag to False
+      on mapper() when using SQLite or MySQL/MyISAM.
+
+    .. change::
+        :tags: orm
+        :tickets: 1671
+
+      flush() now detects when a primary key column was updated by
+      an ON UPDATE CASCADE operation from another primary key, and
+      can then locate the row for a subsequent UPDATE on the new PK
+      value.  This occurs when a relation() is there to establish
+      the relationship as well as passive_updates=True.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "save-update" cascade will now cascade the pending *removed*
+      values from a scalar or collection attribute into the new session
+      during an add() operation.  This so that the flush() operation
+      will also delete or modify rows of those disconnected items.
+
+    .. change::
+        :tags: orm
+        :tickets: 1531
+
+      Using a "dynamic" loader with a "secondary" table now produces
+      a query where the "secondary" table is *not* aliased.  This
+      allows the secondary Table object to be used in the "order_by"
+      attribute of the relation(), and also allows it to be used
+      in filter criterion against the dynamic relation.
+
+    .. change::
+        :tags: orm
+        :tickets: 1643
+
+      relation() with uselist=False will emit a warning when
+      an eager or lazy load locates more than one valid value for
+      the row.  This may be due to primaryjoin/secondaryjoin
+      conditions which aren't appropriate for an eager LEFT OUTER
+      JOIN or for other conditions.
+
+    .. change::
+        :tags: orm
+        :tickets: 1633
+
+      an explicit check occurs when a synonym() is used with
+      map_column=True, when a ColumnProperty (deferred or otherwise)
+      exists separately in the properties dictionary sent to mapper
+      with the same keyname.   Instead of silently replacing
+      the existing property (and possible options on that property),
+      an error is raised.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      a "dynamic" loader sets up its query criterion at construction
+      time so that the actual query is returned from non-cloning
+      accessors like "statement".
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the "named tuple" objects returned when iterating a
+      Query() are now pickleable.
+
+    .. change::
+        :tags: orm
+        :tickets: 1542
+
+      mapping to a select() construct now requires that you
+      make an alias() out of it distinctly.   This to eliminate
+      confusion over such issues as
+
+    .. change::
+        :tags: orm
+        :tickets: 1537
+
+      query.join() has been reworked to provide more consistent
+      behavior and more flexibility (includes)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.select_from() accepts multiple clauses to produce
+      multiple comma separated entries within the FROM clause.
+      Useful when selecting from multiple-homed join() clauses.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      query.select_from() also accepts mapped classes, aliased()
+      constructs, and mappers as arguments.  In particular this
+      helps when querying from multiple joined-table classes to ensure
+      the full join gets rendered.
+
+    .. change::
+        :tags: orm
+        :tickets: 1135
+
+      query.get() can be used with a mapping to an outer join
+      where one or more of the primary key values are None.
+
+    .. change::
+        :tags: orm
+        :tickets: 1568
+
+      query.from_self(), query.union(), others which do a
+      "SELECT * from (SELECT...)" type of nesting will do
+      a better job translating column expressions within the subquery
+      to the columns clause of the outer query.  This is
+      potentially backwards incompatible with 0.5, in that this
+      may break queries with literal expressions that do not have labels
+      applied (i.e. literal('foo'), etc.)
+
+    .. change::
+        :tags: orm
+        :tickets: 1622
+
+      relation primaryjoin and secondaryjoin now check that they
+      are column-expressions, not just clause elements.  this prohibits
+      things like FROM expressions being placed there directly.
+
+    .. change::
+        :tags: orm
+        :tickets: 1415
+
+      `expression.null()` is fully understood the same way
+      None is when comparing an object/collection-referencing
+      attribute within query.filter(), filter_by(), etc.
+
+    .. change::
+        :tags: orm
+        :tickets: 1052
+
+      added "make_transient()" helper function which transforms a
+      persistent/ detached instance into a transient one (i.e.
+      deletes the instance_key and removes from any session.)
+
+    .. change::
+        :tags: orm
+        :tickets: 1339
+
+      the allow_null_pks flag on mapper() is deprecated, and
+      the feature is turned "on" by default.  This means that
+      a row which has a non-null value for any of its primary key
+      columns will be considered an identity.  The need for this
+      scenario typically only occurs when mapping to an outer join.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the mechanics of "backref" have been fully merged into the
+      finer grained "back_populates" system, and take place entirely
+      within the _generate_backref() method of RelationProperty.  This
+      makes the initialization procedure of RelationProperty
+      simpler and allows easier propagation of settings (such as from
+      subclasses of RelationProperty) into the reverse reference.
+      The internal BackRef() is gone and backref() returns a plain
+      tuple that is understood by RelationProperty.
+
+    .. change::
+        :tags: orm
+        :tickets: 1569
+
+      The version_id_col feature on mapper() will raise a warning when
+      used with dialects that don't support "rowcount" adequately.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "execution_options()" to Query, to so options can be
+      passed to the resulting statement. Currently only
+      Select-statements have these options, and the only option
+      used is "stream_results", and the only dialect which knows
+      "stream_results" is psycopg2.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.yield_per() will set the "stream_results" statement
+      option automatically.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Deprecated or removed:
+       * 'allow_null_pks' flag on mapper() is deprecated.  It does
+         nothing now and the setting is "on" in all cases.
+       * 'transactional' flag on sessionmaker() and others is
+         removed. Use 'autocommit=True' to indicate 'transactional=False'.
+       * 'polymorphic_fetch' argument on mapper() is removed.
+         Loading can be controlled using the 'with_polymorphic'
+         option.
+       * 'select_table' argument on mapper() is removed.  Use
+         'with_polymorphic=("*", <some selectable>)' for this
+         functionality.
+       * 'proxy' argument on synonym() is removed.  This flag
+         did nothing throughout 0.5, as the "proxy generation"
+         behavior is now automatic.
+       * Passing a single list of elements to eagerload(),
+         eagerload_all(), contains_eager(), lazyload(),
+         defer(), and undefer() instead of multiple positional
+         *args is deprecated.
+       * Passing a single list of elements to query.order_by(),
+         query.group_by(), query.join(), or query.outerjoin()
+         instead of multiple positional *args is deprecated.
+       * query.iterate_instances() is removed.  Use query.instances().
+       * Query.query_from_parent() is removed.  Use the
+         sqlalchemy.orm.with_parent() function to produce a
+         "parent" clause, or alternatively query.with_parent().
+       * query._from_self() is removed, use query.from_self()
+         instead.
+       * the "comparator" argument to composite() is removed.
+         Use "comparator_factory".
+       * RelationProperty._get_join() is removed.
+       * the 'echo_uow' flag on Session is removed.  Use
+         logging on the "sqlalchemy.orm.unitofwork" name.
+       * session.clear() is removed.  use session.expunge_all().
+       * session.save(), session.update(), session.save_or_update()
+         are removed.  Use session.add() and session.add_all().
+       * the "objects" flag on session.flush() remains deprecated.
+       * the "dont_load=True" flag on session.merge() is deprecated
+         in favor of "load=False".
+       * ScopedSession.mapper remains deprecated.  See the
+         usage recipe at
+         http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
+       * passing an InstanceState (internal SQLAlchemy state object) to
+         attributes.init_collection() or attributes.get_history() is
+         deprecated.  These functions are public API and normally
+         expect a regular mapped object instance.
+       * the 'engine' parameter to declarative_base() is removed.
+         Use the 'bind' keyword argument.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the "autocommit" flag on select() and text() as well
+      as select().autocommit() are deprecated - now call
+      .execution_options(autocommit=True) on either of those
+      constructs, also available directly on Connection and orm.Query.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      the autoincrement flag on column now indicates the column
+      which should be linked to cursor.lastrowid, if that method
+      is used.  See the API docs for details.
+
+    .. change::
+        :tags: sql
+        :tickets: 1566
+
+      an executemany() now requires that all bound parameter
+      sets require that all keys are present which are
+      present in the first bound parameter set.  The structure
+      and behavior of an insert/update statement is very much
+      determined by the first parameter set, including which
+      defaults are going to fire off, and a minimum of
+      guesswork is performed with all the rest so that performance
+      is not impacted.  For this reason defaults would otherwise
+      silently "fail" for missing parameters, so this is now guarded
+      against.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      returning() support is native to insert(), update(),
+      delete(). Implementations of varying levels of
+      functionality exist for Postgresql, Firebird, MSSQL and
+      Oracle. returning() can be called explicitly with column
+      expressions which are then returned in the resultset,
+      usually via fetchone() or first().
+      
+      insert() constructs will also use RETURNING implicitly to
+      get newly generated primary key values, if the database
+      version in use supports it (a version number check is
+      performed). This occurs if no end-user returning() was
+      specified.
+
+    .. change::
+        :tags: sql
+        :tickets: 1665
+
+      union(), intersect(), except() and other "compound" types
+      of statements have more consistent behavior w.r.t.
+      parenthesizing.   Each compound element embedded within
+      another will now be grouped with parenthesis - previously,
+      the first compound element in the list would not be grouped,
+      as SQLite doesn't like a statement to start with
+      parenthesis.   However, Postgresql in particular has
+      precedence rules regarding INTERSECT, and it is
+      more consistent for parenthesis to be applied equally
+      to all sub-elements.   So now, the workaround for SQLite
+      is also what the workaround for PG was previously -
+      when nesting compound elements, the first one usually needs
+      ".alias().select()" called on it to wrap it inside
+      of a subquery.
+
+    .. change::
+        :tags: sql
+        :tickets: 1579
+
+      insert() and update() constructs can now embed bindparam()
+      objects using names that match the keys of columns.  These
+      bind parameters will circumvent the usual route to those
+      keys showing up in the VALUES or SET clause of the generated
+      SQL.
+
+    .. change::
+        :tags: sql
+        :tickets: 1524
+
+      the Binary type now returns data as a Python string
+      (or a "bytes" type in Python 3), instead of the built-
+      in "buffer" type.  This allows symmetric round trips
+      of binary data.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added a tuple_() construct, allows sets of expressions
+      to be compared to another set, typically with IN against
+      composite primary keys or similar.  Also accepts an
+      IN with multiple columns.   The "scalar select can
+      have only one column" error message is removed - will
+      rely upon the database to report problems with
+      col mismatch.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      User-defined "default" and "onupdate" callables which
+      accept a context should now call upon
+      "context.current_parameters" to get at the dictionary
+      of bind parameters currently being processed.  This
+      dict is available in the same way regardless of
+      single-execute or executemany-style statement execution.
+
+    .. change::
+        :tags: sql
+        :tickets: 1428
+
+      multi-part schema names, i.e. with dots such as
+      "dbo.master", are now rendered in select() labels
+      with underscores for dots, i.e. "dbo_master_table_column".
+      This is a "friendly" label that behaves better
+      in result sets.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      removed needless "counter" behavior with select()
+      labelnames that match a column name in the table,
+      i.e. generates "tablename_id" for "id", instead of
+      "tablename_id_1" in an attempt to avoid naming
+      conflicts, when the table has a column actually
+      named "tablename_id" - this is because
+      the labeling logic is always applied to all columns
+      so a naming conflict will never occur.
+
+    .. change::
+        :tags: sql
+        :tickets: 1628
+
+      calling expr.in_([]), i.e. with an empty list, emits a warning
+      before issuing the usual "expr != expr" clause.  The
+      "expr != expr" can be very expensive, and it's preferred
+      that the user not issue in_() if the list is empty,
+      instead simply not querying, or modifying the criterion
+       as appropriate for more complex situations.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added "execution_options()" to select()/text(), which set the
+      default options for the Connection.  See the note in "engines".
+
+    .. change::
+        :tags: sql
+        :tickets: 1131
+
+      Deprecated or removed:
+        * "scalar" flag on select() is removed, use
+          select.as_scalar().
+        * "shortname" attribute on bindparam() is removed.
+        * postgres_returning, firebird_returning flags on
+          insert(), update(), delete() are deprecated, use
+          the new returning() method.
+        * fold_equivalents flag on join is deprecated (will remain
+          until is implemented)
+
+    .. change::
+        :tags: engines
+        :tickets: 443
+
+      transaction isolation level may be specified with
+      create_engine(... isolation_level="..."); available on
+      postgresql and sqlite.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Connection has execution_options(), generative method
+      which accepts keywords that affect how the statement
+      is executed w.r.t. the DBAPI.   Currently supports
+      "stream_results", causes psycopg2 to use a server
+      side cursor for that statement, as well as
+      "autocommit", which is the new location for the "autocommit"
+      option from select() and text().   select() and
+      text() also have .execution_options() as well as
+      ORM Query().
+
+    .. change::
+        :tags: engines
+        :tickets: 1630
+
+      fixed the import for entrypoint-driven dialects to
+      not rely upon silly tb_info trick to determine import
+      error status.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      added first() method to ResultProxy, returns first row and
+      closes result set immediately.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      RowProxy objects are now pickleable, i.e. the object returned
+      by result.fetchone(), result.fetchall() etc.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      RowProxy no longer has a close() method, as the row no longer
+      maintains a reference to the parent.  Call close() on
+      the parent ResultProxy instead, or use autoclose.
+
+    .. change::
+        :tags: engines
+        :tickets: 1586
+
+      ResultProxy internals have been overhauled to greatly reduce
+      method call counts when fetching columns.  Can provide a large
+      speed improvement (up to more than 100%) when fetching large
+      result sets.  The improvement is larger when fetching columns
+      that have no type-level processing applied and when using
+      results as tuples (instead of as dictionaries).  Many
+      thanks to Elixir's Gaëtan de Menten for this dramatic
+      improvement !
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Databases which rely upon postfetch of "last inserted id"
+      to get at a generated sequence value (i.e. MySQL, MS-SQL)
+      now work correctly when there is a composite primary key
+      where the "autoincrement" column is not the first primary
+      key column in the table.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      the last_inserted_ids() method has been renamed to the
+      descriptor "inserted_primary_key".
+
+    .. change::
+        :tags: engines
+        :tickets: 1554
+
+      setting echo=False on create_engine() now sets the loglevel
+      to WARN instead of NOTSET.  This so that logging can be
+      disabled for a particular engine even if logging
+      for "sqlalchemy.engine" is enabled overall.  Note that the
+      default setting of "echo" is `None`.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      ConnectionProxy now has wrapper methods for all transaction
+      lifecycle events, including begin(), rollback(), commit()
+      begin_nested(), begin_prepared(), prepare(), release_savepoint(),
+      etc.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      Connection pool logging now uses both INFO and DEBUG
+      log levels for logging.  INFO is for major events such
+      as invalidated connections, DEBUG for all the acquire/return
+      logging.  `echo_pool` can be False, None, True or "debug"
+      the same way as `echo` works.
+
+    .. change::
+        :tags: engines
+        :tickets: 1621
+
+      All pyodbc-dialects now support extra pyodbc-specific
+      kw arguments 'ansi', 'unicode_results', 'autocommit'.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      the "threadlocal" engine has been rewritten and simplified
+      and now supports SAVEPOINT operations.
+
+    .. change::
+        :tags: engines
+        :tickets: 
+
+      deprecated or removed
+        * result.last_inserted_ids() is deprecated.  Use
+          result.inserted_primary_key
+        * dialect.get_default_schema_name(connection) is now
+          public via dialect.default_schema_name.
+        * the "connection" argument from engine.transaction() and
+          engine.run_callable() is removed - Connection itself
+          now has those methods.   All four methods accept
+          *args and **kwargs which are passed to the given callable,
+          as well as the operating connection.
+
+    .. change::
+        :tags: schema
+        :tickets: 1541
+
+      the `__contains__()` method of `MetaData` now accepts
+      strings or `Table` objects as arguments.  If given
+      a `Table`, the argument is converted to `table.key` first,
+      i.e. "[schemaname.]<tablename>"
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      deprecated MetaData.connect() and
+      ThreadLocalMetaData.connect() have been removed - send
+      the "bind" attribute to bind a metadata.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      deprecated metadata.table_iterator() method removed (use
+      sorted_tables)
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      deprecated PassiveDefault - use DefaultClause.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      the "metadata" argument is removed from DefaultGenerator
+      and subclasses, but remains locally present on Sequence,
+      which is a standalone construct in DDL.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Removed public mutability from Index and Constraint
+      objects:
+        - ForeignKeyConstraint.append_element()
+        - Index.append_column()
+        - UniqueConstraint.append_column()
+        - PrimaryKeyConstraint.add()
+        - PrimaryKeyConstraint.remove()
+      These should be constructed declaratively (i.e. in one
+      construction).
+
+    .. change::
+        :tags: schema
+        :tickets: 1545
+
+      The "start" and "increment" attributes on Sequence now
+      generate "START WITH" and "INCREMENT BY" by default,
+      on Oracle and Postgresql.  Firebird doesn't support
+      these keywords right now.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      UniqueConstraint, Index, PrimaryKeyConstraint all accept
+      lists of column names or column objects as arguments.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Other removed things:
+        - Table.key (no idea what this was for)
+        - Table.primary_key is not assignable - use
+          table.append_constraint(PrimaryKeyConstraint(...))
+        - Column.bind       (get via column.table.bind)
+        - Column.metadata   (get via column.table.metadata)
+        - Column.sequence   (use column.default)
+        - ForeignKey(constraint=some_parent) (is now private _constraint)
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      The use_alter flag on ForeignKey is now a shortcut option
+      for operations that can be hand-constructed using the
+      DDL() event system. A side effect of this refactor is
+      that ForeignKeyConstraint objects with use_alter=True
+      will *not* be emitted on SQLite, which does not support
+      ALTER for foreign keys.
+
+    .. change::
+        :tags: schema
+        :tickets: 1605
+
+      ForeignKey and ForeignKeyConstraint objects now correctly
+      copy() all their public keyword arguments.
+
+    .. change::
+        :tags: reflection/inspection
+        :tickets: 
+
+      Table reflection has been expanded and generalized into
+      a new API called "sqlalchemy.engine.reflection.Inspector".
+      The Inspector object provides fine-grained information about
+      a wide variety of schema information, with room for expansion,
+      including table names, column names, view definitions, sequences,
+      indexes, etc.
+
+    .. change::
+        :tags: reflection/inspection
+        :tickets: 
+
+      Views are now reflectable as ordinary Table objects.  The same
+      Table constructor is used, with the caveat that "effective"
+      primary and foreign key constraints aren't part of the reflection
+      results; these have to be specified explicitly if desired.
+
+    .. change::
+        :tags: reflection/inspection
+        :tickets: 
+
+      The existing autoload=True system now uses Inspector underneath
+      so that each dialect need only return "raw" data about tables
+      and other objects - Inspector is the single place that information
+      is compiled into Table objects so that consistency is at a maximum.
+
+    .. change::
+        :tags: ddl
+        :tickets: 
+
+      the DDL system has been greatly expanded.  the DDL() class
+      now extends the more generic DDLElement(), which forms the basis
+      of many new constructs:
+      
+        - CreateTable()
+        - DropTable()
+        - AddConstraint()
+        - DropConstraint()
+        - CreateIndex()
+        - DropIndex()
+        - CreateSequence()
+        - DropSequence()
+      
+       These support "on" and "execute-at()" just like plain DDL()
+       does.  User-defined DDLElement subclasses can be created and
+       linked to a compiler using the sqlalchemy.ext.compiler extension.
+
+    .. change::
+        :tags: ddl
+        :tickets: 
+
+      The signature of the "on" callable passed to DDL() and
+      DDLElement() is revised as follows:
+      
+        "ddl" - the DDLElement object itself.
+        "event" - the string event name.
+        "target" - previously "schema_item", the Table or
+        MetaData object triggering the event.
+        "connection" - the Connection object in use for the operation.
+        **kw - keyword arguments.  In the case of MetaData before/after
+          create/drop, the list of Table objects for which
+          CREATE/DROP DDL is to be issued is passed as the kw
+          argument "tables". This is necessary for metadata-level
+          DDL that is dependent on the presence of specific tables.
+      
+      - the "schema_item" attribute of DDL has been renamed to
+        "target".
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      Dialect modules are now broken into database dialects
+      plus DBAPI implementations. Connect URLs are now
+      preferred to be specified using dialect+driver://...,
+      i.e. "mysql+mysqldb://scott:tiger@localhost/test". See
+      the 0.6 documentation for examples.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      the setuptools entrypoint for external dialects is now
+      called "sqlalchemy.dialects".
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      the "owner" keyword argument is removed from Table. Use
+      "schema" to represent any namespaces to be prepended to
+      the table name.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      server_version_info becomes a static attribute.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      dialects receive an initialize() event on initial
+      connection to determine connection properties.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      dialects receive a visit_pool event have an opportunity
+      to establish pool listeners.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      cached TypeEngine classes are cached per-dialect class
+      instead of per-dialect.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      new UserDefinedType should be used as a base class for
+      new types, which preserves the 0.5 behavior of
+      get_col_spec().
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      The result_processor() method of all type classes now
+      accepts a second argument "coltype", which is the DBAPI
+      type argument from cursor.description.  This argument
+      can help some types decide on the most efficient processing
+      of result values.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      Deprecated Dialect.get_params() removed.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      Dialect.get_rowcount() has been renamed to a descriptor
+      "rowcount", and calls cursor.rowcount directly. Dialects
+      which need to hardwire a rowcount in for certain calls
+      should override the method to provide different behavior.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 1566
+
+      DefaultRunner and subclasses have been removed.  The job
+      of this object has been simplified and moved into
+      ExecutionContext.  Dialects which support sequences should
+      add a `fire_sequence()` method to their execution context
+      implementation.
+
+    .. change::
+        :tags: dialect, refactor
+        :tickets: 
+
+      Functions and operators generated by the compiler now use
+      (almost) regular dispatch functions of the form
+      "visit_<opname>" and "visit_<funcname>_fn" to provide
+      customed processing. This replaces the need to copy the
+      "functions" and "operators" dictionaries in compiler
+      subclasses with straightforward visitor methods, and also
+      allows compiler subclasses complete control over
+      rendering, as the full _Function or _BinaryExpression
+      object is passed in.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      New dialects: pg8000, zxjdbc, and pypostgresql
+      on py3k.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      The "postgres" dialect is now named "postgresql" !
+      Connection strings look like:
+      
+           postgresql://scott:tiger@localhost/test
+           postgresql+pg8000://scott:tiger@localhost/test
+      
+       The "postgres" name remains for backwards compatiblity
+       in the following ways:
+      
+           - There is a "postgres.py" dummy dialect which
+             allows old URLs to work, i.e.
+             postgres://scott:tiger@localhost/test
+      
+           - The "postgres" name can be imported from the old
+             "databases" module, i.e. "from
+             sqlalchemy.databases import postgres" as well as
+             "dialects", "from sqlalchemy.dialects.postgres
+             import base as pg", will send a deprecation
+             warning.
+      
+           - Special expression arguments are now named
+             "postgresql_returning" and "postgresql_where", but
+             the older "postgres_returning" and
+             "postgres_where" names still work with a
+             deprecation warning.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      "postgresql_where" now accepts SQL expressions which
+      can also include literals, which will be quoted as needed.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      The psycopg2 dialect now uses psycopg2's "unicode extension"
+      on all new connections, which allows all String/Text/etc.
+      types to skip the need to post-process bytestrings into
+      unicode (an expensive step due to its volume).  Other
+      dialects which return unicode natively (pg8000, zxjdbc)
+      also skip unicode post-processing.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1511
+
+      Added new ENUM type, which exists as a schema-level
+      construct and extends the generic Enum type.  Automatically
+      associates itself with tables and their parent metadata
+      to issue the appropriate CREATE TYPE/DROP TYPE
+      commands as needed, supports unicode labels, supports
+      reflection.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      INTERVAL supports an optional "precision" argument
+      corresponding to the argument that PG accepts.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      using new dialect.initialize() feature to set up
+      version-dependent behavior.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1279
+
+      somewhat better support for % signs in table/column names;
+      psycopg2 can't handle a bind parameter name of
+      %(foobar)s however and SQLA doesn't want to add overhead
+      just to treat that one non-existent use case.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1516
+
+      Inserting NULL into a primary key + foreign key column
+      will allow the "not null constraint" error to raise,
+      not an attempt to execute a nonexistent "col_id_seq"
+      sequence.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      autoincrement SELECT statements, i.e. those which
+      select from a procedure that modifies rows, now work
+      with server-side cursor mode (the named cursor isn't
+      used for such statements.)
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1636
+
+      postgresql dialect can properly detect pg "devel" version
+      strings, i.e. "8.5devel"
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1619
+
+      The psycopg2 now respects the statement option
+      "stream_results". This option overrides the connection setting
+      "server_side_cursors". If true, server side cursors will be
+      used for the statement. If false, they will not be used, even
+      if "server_side_cursors" is true on the
+      connection.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      New dialects: oursql, a new native dialect,
+      MySQL Connector/Python, a native Python port of MySQLdb,
+      and of course zxjdbc on Jython.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      VARCHAR/NVARCHAR will not render without a length, raises
+      an error before passing to MySQL.   Doesn't impact
+      CAST since VARCHAR is not allowed in MySQL CAST anyway,
+      the dialect renders CHAR/NCHAR in those cases.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      all the _detect_XXX() functions now run once underneath
+      dialect.initialize()
+
+    .. change::
+        :tags: mysql
+        :tickets: 1279
+
+      somewhat better support for % signs in table/column names;
+      MySQLdb can't handle % signs in SQL when executemany() is used,
+      and SQLA doesn't want to add overhead just to treat that one
+      non-existent use case.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      the BINARY and MSBinary types now generate "BINARY" in all
+      cases.  Omitting the "length" parameter will generate
+      "BINARY" with no length.  Use BLOB to generate an unlengthed
+      binary column.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      the "quoting='quoted'" argument to MSEnum/ENUM is deprecated.
+      It's best to rely upon the automatic quoting.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      ENUM now subclasses the new generic Enum type, and also handles
+      unicode values implicitly, if the given labelnames are unicode
+      objects.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1539
+
+      a column of type TIMESTAMP now defaults to NULL if
+      "nullable=False" is not passed to Column(), and no default
+      is present. This is now consistent with all other types,
+      and in the case of TIMESTAMP explictly renders "NULL"
+      due to MySQL's "switching" of default nullability
+      for TIMESTAMP columns.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      unit tests pass 100% with cx_oracle !
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      support for cx_Oracle's "native unicode" mode which does
+      not require NLS_LANG to be set. Use the latest 5.0.2 or
+      later of cx_oracle.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      an NCLOB type is added to the base types.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      use_ansi=False won't leak into the FROM/WHERE clause of
+      a statement that's selecting from a subquery that also
+      uses JOIN/OUTERJOIN.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1467
+
+      added native INTERVAL type to the dialect.  This supports
+      only the DAY TO SECOND interval type so far due to lack
+      of support in cx_oracle for YEAR TO MONTH.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      usage of the CHAR type results in cx_oracle's
+      FIXED_CHAR dbapi type being bound to statements.
+
+    .. change::
+        :tags: oracle
+        :tickets: 885
+
+      the Oracle dialect now features NUMBER which intends
+      to act justlike Oracle's NUMBER type.  It is the primary
+      numeric type returned by table reflection and attempts
+      to return Decimal()/float/int based on the precision/scale
+      parameters.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      func.char_length is a generic function for LENGTH
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      ForeignKey() which includes onupdate=<value> will emit a
+      warning, not emit ON UPDATE CASCADE which is unsupported
+      by oracle
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      the keys() method of RowProxy() now returns the result
+      column names *normalized* to be SQLAlchemy case
+      insensitive names. This means they will be lower case for
+      case insensitive names, whereas the DBAPI would normally
+      return them as UPPERCASE names. This allows row keys() to
+      be compatible with further SQLAlchemy operations.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      using new dialect.initialize() feature to set up
+      version-dependent behavior.
+
+    .. change::
+        :tags: oracle
+        :tickets: 1125
+
+      using types.BigInteger with Oracle will generate
+      NUMBER(19)
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      "case sensitivity" feature will detect an all-lowercase
+      case-sensitive column name during reflect and add
+      "quote=True" to the generated Column, so that proper
+      quoting is maintained.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      the keys() method of RowProxy() now returns the result
+      column names *normalized* to be SQLAlchemy case
+      insensitive names. This means they will be lower case for
+      case insensitive names, whereas the DBAPI would normally
+      return them as UPPERCASE names. This allows row keys() to
+      be compatible with further SQLAlchemy operations.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      using new dialect.initialize() feature to set up
+      version-dependent behavior.
+
+    .. change::
+        :tags: firebird
+        :tickets: 
+
+      "case sensitivity" feature will detect an all-lowercase
+      case-sensitive column name during reflect and add
+      "quote=True" to the generated Column, so that proper
+      quoting is maintained.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      MSSQL + Pyodbc + FreeTDS now works for the most part,
+      with possible exceptions regarding binary data as well as
+      unicode schema identifiers.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      the "has_window_funcs" flag is removed. LIMIT/OFFSET
+      usage will use ROW NUMBER as always, and if on an older
+      version of SQL Server, the operation fails. The behavior
+      is exactly the same except the error is raised by SQL
+      server instead of the dialect, and no flag setting is
+      required to enable it.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      the "auto_identity_insert" flag is removed. This feature
+      always takes effect when an INSERT statement overrides a
+      column that is known to have a sequence on it. As with
+      "has_window_funcs", if the underlying driver doesn't
+      support this, then you can't do this operation in any
+      case, so there's no point in having a flag.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      using new dialect.initialize() feature to set up
+      version-dependent behavior.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      removed references to sequence which is no longer used.
+      implicit identities in mssql work the same as implicit
+      sequences on any other dialects. Explicit sequences are
+      enabled through the use of "default=Sequence()". See
+      the MSSQL dialect documentation for more information.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      DATE, TIME and DATETIME types can now take optional storage_format
+      and regexp argument. storage_format can be used to store those types
+      using a custom string format. regexp allows to use a custom regular
+      expression to match string values from the database.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      Time and DateTime types now use by a default a stricter regular
+      expression to match strings from the database. Use the regexp
+      argument if you are using data stored in a legacy format.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      __legacy_microseconds__ on SQLite Time and DateTime types is not
+      supported anymore. You should use the storage_format argument
+      instead.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      Date, Time and DateTime types are now stricter in what they accept as
+      bind parameters: Date type only accepts date objects (and datetime
+      ones, because they inherit from date), Time only accepts time
+      objects, and DateTime only accepts date and datetime objects.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 1016
+
+      Table() supports a keyword argument "sqlite_autoincrement", which
+      applies the SQLite keyword "AUTOINCREMENT" to the single integer
+      primary key column when generating DDL. Will prevent generation of
+      a separate PRIMARY KEY constraint.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      The construction of types within dialects has been totally
+      overhauled.  Dialects now define publically available types
+      as UPPERCASE names exclusively, and internal implementation
+      types using underscore identifiers (i.e. are private).
+      The system by which types are expressed in SQL and DDL
+      has been moved to the compiler system.  This has the
+      effect that there are much fewer type objects within
+      most dialects. A detailed document on this architecture
+      for dialect authors is in
+      lib/sqlalchemy/dialects/type_migration_guidelines.txt .
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      Types no longer make any guesses as to default
+      parameters. In particular, Numeric, Float, NUMERIC,
+      FLOAT, DECIMAL don't generate any length or scale unless
+      specified.
+
+    .. change::
+        :tags: types
+        :tickets: 1664
+
+      types.Binary is renamed to types.LargeBinary, it only
+      produces BLOB, BYTEA, or a similar "long binary" type.
+      New base BINARY and VARBINARY
+      types have been added to access these MySQL/MS-SQL specific
+      types in an agnostic way.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      String/Text/Unicode types now skip the unicode() check
+      on each result column value if the dialect has
+      detected the DBAPI as returning Python unicode objects
+      natively.  This check is issued on first connect
+      using "SELECT CAST 'some text' AS VARCHAR(10)" or
+      equivalent, then checking if the returned object
+      is a Python unicode.   This allows vast performance
+      increases for native-unicode DBAPIs, including
+      pysqlite/sqlite3, psycopg2, and pg8000.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      Most types result processors have been checked for possible speed
+      improvements. Specifically, the following generic types have been
+      optimized, resulting in varying speed improvements:
+      Unicode, PickleType, Interval, TypeDecorator, Binary.
+      Also the following dbapi-specific implementations have been improved:
+      Time, Date and DateTime on Sqlite, ARRAY on Postgresql,
+      Time on MySQL, Numeric(as_decimal=False) on MySQL, oursql and
+      pypostgresql, DateTime on cx_oracle and LOB-based types on cx_oracle.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      Reflection of types now returns the exact UPPERCASE
+      type within types.py, or the UPPERCASE type within
+      the dialect itself if the type is not a standard SQL
+      type.  This means reflection now returns more accurate
+      information about reflected types.
+
+    .. change::
+        :tags: types
+        :tickets: 1511, 1109
+
+      Added a new Enum generic type. Enum is a schema-aware object
+      to support databases which require specific DDL in order to
+      use enum or equivalent; in the case of PG it handles the
+      details of `CREATE TYPE`, and on other databases without
+      native enum support will by generate VARCHAR + an inline CHECK
+      constraint to enforce the enum.
+
+    .. change::
+        :tags: types
+        :tickets: 1467
+
+      The Interval type includes a "native" flag which controls
+      if native INTERVAL types (postgresql + oracle) are selected
+      if available, or not.  "day_precision" and "second_precision"
+      arguments are also added which propagate as appropriately
+      to these native types. Related to.
+
+    .. change::
+        :tags: types
+        :tickets: 1589
+
+      The Boolean type, when used on a backend that doesn't
+      have native boolean support, will generate a CHECK
+      constraint "col IN (0, 1)" along with the int/smallint-
+      based column type.  This can be switched off if
+      desired with create_constraint=False.
+      Note that MySQL has no native boolean *or* CHECK constraint
+      support so this feature isn't available on that platform.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      PickleType now uses == for comparison of values when
+      mutable=True, unless the "comparator" argument with a
+      comparsion function is specified to the type. Objects
+      being pickled will be compared based on identity (which
+      defeats the purpose of mutable=True) if __eq__() is not
+      overridden or a comparison function is not provided.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      The default "precision" and "scale" arguments of Numeric
+      and Float have been removed and now default to None.
+      NUMERIC and FLOAT will be rendered with no numeric
+      arguments by default unless these values are provided.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      AbstractType.get_search_list() is removed - the games
+      that was used for are no longer necessary.
+
+    .. change::
+        :tags: types
+        :tickets: 1125
+
+      Added a generic BigInteger type, compiles to
+      BIGINT or NUMBER(19).
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      sqlsoup has been overhauled to explicitly support an 0.5 style
+      session, using autocommit=False, autoflush=True. Default
+      behavior of SQLSoup now requires the usual usage of commit()
+      and rollback(), which have been added to its interface. An
+      explcit Session or scoped_session can be passed to the
+      constructor, allowing these arguments to be overridden.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      sqlsoup db.<sometable>.update() and delete() now call
+      query(cls).update() and delete(), respectively.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      sqlsoup now has execute() and connection(), which call upon
+      the Session methods of those names, ensuring that the bind is
+      in terms of the SqlSoup object's bind.
+
+    .. change::
+        :tags: types
+        :tickets: 
+
+      sqlsoup objects no longer have the 'query' attribute - it's
+      not needed for sqlsoup's usage paradigm and it gets in the
+      way of a column that is actually named 'query'.
+
+    .. change::
+        :tags: types
+        :tickets: 1259
+
+      The signature of the proxy_factory callable passed to
+      association_proxy is now (lazy_collection, creator,
+      value_attr, association_proxy), adding a fourth argument
+      that is the parent AssociationProxy argument.  Allows
+      serializability and subclassing of the built in collections.
+
+    .. change::
+        :tags: types
+        :tickets: 1372
+
+      association_proxy now has basic comparator methods .any(),
+      .has(), .contains(), ==, !=, thanks to Scott Torborg.
diff --git a/doc/build/changelog/changelog_07.rst b/doc/build/changelog/changelog_07.rst
new file mode 100644 (file)
index 0000000..7b28f5f
--- /dev/null
@@ -0,0 +1,4436 @@
+
+==============
+0.7 Changelog
+==============
+
+                
+.. changelog::
+    :version: 0.7.10
+    :released: 
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2583
+
+      Fixed Session accounting bug whereby replacing
+      a deleted object in the identity map with another
+      object of the same primary key would raise a
+      "conflicting state" error on rollback(),
+      if the replaced primary key were established either
+      via non-unitofwork-established INSERT statement
+      or by primary key switch of another instance.
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2561
+
+      changed the list of cx_oracle types that are
+      excluded from the setinputsizes() step to only include
+      STRING and UNICODE; CLOB and NCLOB are removed.  This
+      is to work around cx_oracle behavior which is broken
+      for the executemany() call.  In 0.8, this same change
+      is applied however it is also configurable via the
+      exclude_setinputsizes argument.
+
+    .. change::
+        :tags: feature, mysql
+        :tickets: 2523
+
+      Added "raise_on_warnings" flag to OurSQL
+      dialect.
+
+    .. change::
+        :tags: feature, mysql
+        :tickets: 2554
+
+      Added "read_timeout" flag to MySQLdb
+      dialect.
+
+.. changelog::
+    :version: 0.7.9
+    :released: Mon Oct 01 2012
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 
+
+      Fixed bug mostly local to new
+      AbstractConcreteBase helper where the "type"
+      attribute from the superclass would not
+      be overridden on the subclass to produce the
+      "reserved for base" error message, instead placing
+      a do-nothing attribute there.  This was inconsistent
+      vs. using ConcreteBase as well as all the behavior
+      of classical concrete mappings, where the "type"
+      column from the polymorphic base would be explicitly
+      disabled on subclasses, unless overridden
+      explicitly.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 
+
+      A warning is emitted when lazy='dynamic'
+      is combined with uselist=False.  This is an
+      exception raise in 0.8.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 
+
+      Fixed bug whereby user error in related-object
+      assignment could cause recursion overflow if the
+      assignment triggered a backref of the same name
+      as a bi-directional attribute on the incorrect
+      class to the same target.  An informative
+      error is raised now.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2539
+
+      Fixed bug where incorrect type information
+      would be passed when the ORM would bind the
+      "version" column, when using the "version" feature.
+      Tests courtesy Daniel Miller.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2566
+
+      Extra logic has been added to the "flush"
+      that occurs within Session.commit(), such that the
+      extra state added by an after_flush() or
+      after_flush_postexec() hook is also flushed in a
+      subsequent flush, before the "commit" completes.
+      Subsequent calls to flush() will continue until
+      the after_flush hooks stop adding new state.
+      An "overflow" counter of 100 is also in place,
+      in the event of a broken after_flush() hook
+      adding new content each time.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2571
+
+      Fixed the DropIndex construct to support
+      an Index associated with a Table in a remote
+      schema.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2574
+
+      Fixed bug in over() construct whereby
+      passing an empty list for either partition_by
+      or order_by, as opposed to None, would fail
+      to generate correctly.
+      Courtesy Gunnlaugur ÃžÃ³r Briem.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2521
+
+      Fixed CTE bug whereby positional
+      bound parameters present in the CTEs themselves
+      would corrupt the overall ordering of
+      bound parameters.  This primarily
+      affected SQL Server as the platform with
+      positional binds + CTE support.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 
+
+      Fixed more un-intuitivenesses in CTEs
+      which prevented referring to a CTE in a union
+      of itself without it being aliased.
+      CTEs now render uniquely
+      on name, rendering the outermost CTE of a given
+      name only - all other references are rendered
+      just as the name.   This even includes other
+      CTE/SELECTs that refer to different versions
+      of the same CTE object, such as a SELECT
+      or a UNION ALL of that SELECT. We are
+      somewhat loosening the usual link between object
+      identity and lexical identity in this case.
+      A true name conflict between two unrelated
+      CTEs now raises an error.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2512
+
+      quoting is applied to the column names
+      inside the WITH RECURSIVE clause of a
+      common table expression according to the
+      quoting rules for the originating Column.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2518
+
+      Fixed regression introduced in 0.7.6
+      whereby the FROM list of a SELECT statement
+      could be incorrect in certain "clone+replace"
+      scenarios.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2552
+
+      Fixed bug whereby usage of a UNION
+      or similar inside of an embedded subquery
+      would interfere with result-column targeting,
+      in the case that a result-column had the same
+      ultimate name as a name inside the embedded
+      UNION.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2558
+
+      Fixed a regression since 0.6 regarding
+      result-row targeting.   It should be possible
+      to use a select() statement with string
+      based columns in it, that is
+      select(['id', 'name']).select_from('mytable'),
+      and have this statement be targetable by
+      Column objects with those names; this is the
+      mechanism by which
+      query(MyClass).from_statement(some_statement)
+      works.  At some point the specific case of
+      using select(['id']), which is equivalent to
+      select([literal_column('id')]), stopped working
+      here, so this has been re-instated and of
+      course tested.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2544
+
+      Added missing operators is_(), isnot()
+      to the ColumnOperators base, so that these long-available
+      operators are present as methods like all
+      the other operators.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2522
+
+      Fixed bug whereby
+      a disconnect detect + dispose that occurs
+      when the QueuePool has threads waiting
+      for connections would leave those
+      threads waiting for the duration of
+      the timeout on the old pool (or indefinitely
+      if timeout was disabled).  The fix
+      now notifies those waiters with a special
+      exception case and has them move onto
+      the new pool.
+
+    .. change::
+        :tags: engine, feature
+        :tickets: 2516
+
+      Dramatic improvement in memory
+      usage of the event system; instance-level
+      collections are no longer created for a
+      particular type of event until
+      instance-level listeners are established
+      for that event.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2529
+
+      Added gaerdbms import to mysql/__init__.py,
+      the absense of which was preventing the new
+      GAE dialect from being loaded.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2553
+
+      Fixed cextension bug whereby the
+      "ambiguous column error" would fail to
+      function properly if the given index were
+      a Column object and not a string.
+      Note there are still some column-targeting
+      issues here which are fixed in 0.8.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 
+
+      Fixed the repr() of Enum to include
+      the "name" and "native_enum" flags.  Helps
+      Alembic autogenerate.
+
+    .. change::
+        :tags: sqlite, bug
+        :tickets: 2568
+
+      Adjusted a very old bugfix which attempted
+      to work around a SQLite issue that itself was
+      "fixed" as of sqlite 3.6.14, regarding quotes
+      surrounding a table name when using
+      the "foreign_key_list" pragma.  The fix has been
+      adjusted to not interfere with quotes that
+      are *actually in the name* of a column or table,
+      to as much a degree as possible; sqlite still
+      doesn't return the correct result for foreign_key_list()
+      if the target table actually has quotes surrounding
+      its name, as *part* of its name (i.e. """mytable""").
+
+    .. change::
+        :tags: sqlite, bug
+        :tickets: 2265
+
+      Adjusted column default reflection code to
+      convert non-string values to string, to accommodate
+      old SQLite versions that don't deliver
+      default info as a string.
+
+    .. change::
+        :tags: sqlite, feature
+        :tickets: 
+
+      Added support for the localtimestamp()
+      SQL function implemented in SQLite, courtesy
+      Richard Mitchell.
+
+    .. change::
+        :tags: postgresql, bug
+        :tickets: 2531
+
+      Columns in reflected primary key constraint
+      are now returned in the order in which the constraint
+      itself defines them, rather than how the table
+      orders them.  Courtesy Gunnlaugur ÃžÃ³r Briem..
+
+    .. change::
+        :tags: postgresql, bug
+        :tickets: 2570
+
+      Added 'terminating connection' to the list
+      of messages we use to detect a disconnect with PG, which
+      appears to be present in some versions when the server
+      is restarted.
+
+    .. change::
+        :tags: bug, mysql
+        :tickets: 
+
+      Updated mysqlconnector interface to use
+      updated "client flag" and "charset" APIs,
+      courtesy David McNelis.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2538
+
+      Fixed compiler bug whereby using a correlated
+      subquery within an ORDER BY would fail to render correctly
+      if the stament also used LIMIT/OFFSET, due to mis-rendering
+      within the ROW_NUMBER() OVER clause.  Fix courtesy
+      sayap
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2545
+
+      Fixed compiler bug whereby a given
+      select() would be modified if it had an "offset"
+      attribute, causing the construct to not compile
+      correctly a second time.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 
+
+      Fixed bug where reflection of primary key constraint
+      would double up columns if the same constraint/table
+      existed in multiple schemas.
+
+.. changelog::
+    :version: 0.7.8
+    :released: Sat Jun 16 2012
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2480
+
+      Fixed bug whereby subqueryload() from
+      a polymorphic mapping to a target would incur
+      a new invocation of the query for each
+      distinct class encountered in the polymorphic
+      result.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2491, 1892
+
+      Fixed bug in declarative
+      whereby the precedence of columns
+      in a joined-table, composite
+      column (typically for id) would fail to
+      be correct if the columns contained
+      names distinct from their attribute
+      names.  This would cause things like
+      primaryjoin conditions made against the
+      entity attributes to be incorrect.  Related
+      to as this was supposed
+      to be part of that, this is.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 
+
+      The 'objects' argument to
+      flush() is no longer deprecated, as some
+      valid use cases have been identified.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2508
+
+      Fixed identity_key() function which
+      was not accepting a scalar argument
+      for the identity. .
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2497
+
+      Fixed bug whereby populate_existing
+      option would not propagate to subquery
+      eager loaders. .
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2499
+
+      added BIGINT to types.__all__,
+      BIGINT, BINARY, VARBINARY to sqlalchemy
+      module namespace, plus test to ensure
+      this breakage doesn't occur again.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2490
+
+      Repaired common table expression
+      rendering to function correctly when the
+      SELECT statement contains UNION or other
+      compound expressions, courtesy btbuilder.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2482
+
+      Fixed bug whereby append_column()
+      wouldn't function correctly on a cloned
+      select() construct, courtesy
+      Gunnlaugur ÃžÃ³r Briem.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2489
+
+      Fixed memory leak in C version of
+      result proxy whereby DBAPIs which don't deliver
+      pure Python tuples for result rows would
+      fail to decrement refcounts correctly.
+      The most prominently affected DBAPI
+      is pyodbc.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2503
+
+      Fixed bug affecting Py3K whereby
+      string positional parameters passed to
+      engine/connection execute() would fail to be
+      interpreted correctly, due to __iter__
+      being present on Py3K string..
+
+    .. change::
+        :tags: postgresql, bug
+        :tickets: 2510
+
+      removed unnecessary table clause when
+      reflecting enums,.  Courtesy
+      Gunnlaugur ÃžÃ³r Briem.
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2483
+
+      Added ROWID to oracle.*.
+
+    .. change::
+        :tags: feature, mysql
+        :tickets: 2484
+
+      Added a new dialect for Google App
+      Engine.  Courtesy Richie Foreman.
+
+.. changelog::
+    :version: 0.7.7
+    :released: Sat May 05 2012
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2477
+
+      Fixed issue in unit of work
+      whereby setting a non-None self-referential
+      many-to-one relationship to None
+      would fail to persist the change if the
+      former value was not already loaded..
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 2443
+
+      Added prefix_with() method
+      to Query, calls upon select().prefix_with()
+      to allow placement of MySQL SELECT
+      directives in statements.  Courtesy
+      Diana Clarke
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2409
+
+      Fixed bug in 0.7.6 introduced by whereby column_mapped_collection
+      used against columns that were mapped as
+      joins or other indirect selectables
+      would fail to function.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 
+
+      Added new flag to @validates
+      include_removes.  When True, collection
+      remove and attribute del events
+      will also be sent to the validation function,
+      which accepts an additional argument
+      "is_remove" when this flag is used.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2449
+
+      Fixed bug whereby polymorphic_on
+      column that's not otherwise mapped on the
+      class would be incorrectly included
+      in a merge() operation, raising an error.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2453
+
+      Fixed bug in expression annotation
+      mechanics which could lead to incorrect
+      rendering of SELECT statements with aliases
+      and joins, particularly when using
+      column_property().
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2454
+
+      Fixed bug which would prevent
+      OrderingList from being pickleable.  Courtesy Jeff Dairiki
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 
+
+      Fixed bug in relationship comparisons
+      whereby calling unimplemented methods like
+      SomeClass.somerelationship.like() would
+      produce a recursion overflow, instead
+      of NotImplementedError.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 
+
+      Removed warning when Index is created
+      with no columns; while this might not be what
+      the user intended, it is a valid use case
+      as an Index could be a placeholder for just an
+      index of a certain name.
+
+    .. change::
+        :tags: feature, sql
+        :tickets: 
+
+      Added new connection event
+      dbapi_error(). Is called for all DBAPI-level
+      errors passing the original DBAPI exception
+      before SQLAlchemy modifies the state
+      of the cursor.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 
+
+      If conn.begin() fails when calling
+      "with engine.begin()", the newly acquired
+      Connection is closed explicitly before
+      propagating the exception onward normally.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2474
+
+      Add BINARY, VARBINARY to types.__all__.
+
+    .. change::
+        :tags: mssql, feature
+        :tickets: 
+
+      Added interim create_engine flag
+      supports_unicode_binds to PyODBC dialect,
+      to force whether or not the dialect
+      passes Python unicode literals to PyODBC
+      or not.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 
+
+      Repaired the use_scope_identity
+      create_engine() flag when using the pyodbc
+      dialect.  Previously this flag would be
+      ignored if set to False.  When set to False,
+      you'll get "SELECT @@identity" after each
+      INSERT to get at the last inserted ID,
+      for those tables which have "implicit_returning"
+      set to False.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2468
+
+      UPDATE..FROM syntax with SQL Server
+      requires that the updated table be present
+      in the FROM clause when an alias of that
+      table is also present in the FROM clause.
+      The updated table is now always present
+      in the FROM, when FROM is present
+      in the first place.  Courtesy sayap.
+
+    .. change::
+        :tags: postgresql, feature
+        :tickets: 2445
+
+      Added new for_update/with_lockmode()
+      options for Postgresql: for_update="read"/
+      with_lockmode("read"),
+      for_update="read_nowait"/
+      with_lockmode("read_nowait").
+      These emit "FOR SHARE" and "FOR SHARE NOWAIT",
+      respectively.  Courtesy Diana Clarke
+
+    .. change::
+        :tags: postgresql, bug
+        :tickets: 2473
+
+      removed unnecessary table clause
+      when reflecting domains.
+
+    .. change::
+        :tags: bug, mysql
+        :tickets: 2460
+
+      Fixed bug whereby column name inside
+      of "KEY" clause for autoincrement composite
+      column with InnoDB would double quote a
+      name that's a reserved word.  Courtesy Jeff
+      Dairiki.
+
+    .. change::
+        :tags: bug, mysql
+        :tickets: 
+
+      Fixed bug whereby get_view_names() for
+      "information_schema" schema would fail
+      to retrieve views marked as "SYSTEM VIEW".
+      courtesy Matthew Turland.
+
+    .. change::
+        :tags: bug, mysql
+        :tickets: 2467
+
+      Fixed bug whereby if cast() is used
+      on a SQL expression whose type is not supported
+      by cast() and therefore CAST isn't rendered by
+      the dialect, the order of evaluation could change
+      if the casted expression required that it be
+      grouped; grouping is now applied to those
+      expressions.
+
+    .. change::
+        :tags: sqlite, feature
+        :tickets: 2475
+
+      Added SQLite execution option
+      "sqlite_raw_colnames=True", will bypass
+      attempts to remove "." from column names
+      returned by SQLite cursor.description.
+
+    .. change::
+        :tags: sqlite, bug
+        :tickets: 2525
+
+      When the primary key column of a Table
+      is replaced, such as via extend_existing,
+      the "auto increment" column used by insert()
+      constructs is reset.  Previously it would
+      remain referring to the previous primary
+      key column.
+
+.. changelog::
+    :version: 0.7.6
+    :released: Wed Mar 14 2012
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2424
+
+      Fixed event registration bug
+      which would primarily show up as
+      events not being registered with
+      sessionmaker() instances created
+      after the event was associated
+      with the Session class.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2425
+
+      Fixed bug whereby a primaryjoin
+      condition with a "literal" in it would
+      raise an error on compile with certain
+      kinds of deeply nested expressions
+      which also needed to render the same
+      bound parameter name more than once.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 
+
+      Added "no_autoflush" context
+      manager to Session, used with with:
+      will temporarily disable autoflush.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 1859
+
+      Added cte() method to Query,
+      invokes common table expression support
+      from the Core (see below).
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2403
+
+      Removed the check for number of
+      rows affected when doing a multi-delete
+      against mapped objects.   If an ON DELETE
+      CASCADE exists between two rows, we can't
+      get an accurate rowcount from the DBAPI;
+      this particular count is not supported
+      on most DBAPIs in any case, MySQLdb
+      is the notable case where it is.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2409
+
+      Fixed bug whereby objects using
+      attribute_mapped_collection or
+      column_mapped_collection could not be
+      pickled.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2406
+
+      Fixed bug whereby MappedCollection
+      would not get the appropriate collection
+      instrumentation if it were only used
+      in a custom subclass that used
+      @collection.internally_instrumented.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2419
+
+      Fixed bug whereby SQL adaption mechanics
+      would fail in a very nested scenario involving
+      joined-inheritance, joinedload(), limit(), and a
+      derived function in the columns clause.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2417
+
+      Fixed the repr() for CascadeOptions to
+      include refresh-expire.  Also reworked
+      CascadeOptions to be a <frozenset>.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 2400
+
+      Added the ability to query for
+      Table-bound column names when using
+      query(sometable).filter_by(colname=value).
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 
+
+      Improved the "declarative reflection"
+      example to support single-table inheritance,
+      multiple calls to prepare(), tables that
+      are present in alternate schemas,
+      establishing only a subset of classes
+      as reflected.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2390
+
+      Scaled back the test applied within
+      flush() to check for UPDATE against partially
+      NULL PK within one table to only actually
+      happen if there's really an UPDATE to occur.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2352
+
+      Fixed bug whereby if a method name
+      conflicted with a column name, a
+      TypeError would be raised when the mapper
+      tried to inspect the __get__() method
+      on the method object.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2427
+
+      Fixed memory leak in core which would
+      occur when C extensions were used with
+      particular types of result fetches,
+      in particular when orm query.count()
+      were called.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2398
+
+      Fixed issue whereby attribute-based
+      column access on a row would raise
+      AttributeError with non-C version,
+      NoSuchColumnError with C version.  Now
+      raises AttributeError in both cases.
+
+    .. change::
+        :tags: feature, sql
+        :tickets: 1859
+
+      Added support for SQL standard
+      common table expressions (CTE), allowing
+      SELECT objects as the CTE source (DML
+      not yet supported).  This is invoked via
+      the cte() method on any select() construct.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2392
+
+      Added support for using the .key
+      of a Column as a string identifier in a
+      result set row.   The .key is currently
+      listed as an "alternate" name for a column,
+      and is superseded by the name of a column
+      which has that key value as its regular name.
+      For the next major release
+      of SQLAlchemy we may reverse this precedence
+      so that .key takes precedence, but this
+      is not decided on yet.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2413
+
+      A warning is emitted when a not-present
+      column is stated in the values() clause
+      of an insert() or update() construct.
+      Will move to an exception in 0.8.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2396
+
+      A significant change to how labeling
+      is applied to columns in SELECT statements
+      allows "truncated" labels, that is label names
+      that are generated in Python which exceed
+      the maximum identifier length (note this is
+      configurable via label_length on create_engine()),
+      to be properly referenced when rendered inside
+      of a subquery, as well as to be present
+      in a result set row using their original
+      in-Python names.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2402
+
+      Fixed bug in new "autoload_replace" flag
+      which would fail to preserve the primary
+      key constraint of the reflected table.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2380
+
+      Index will raise when arguments passed
+      cannot be interpreted as columns or expressions.
+      Will warn when Index is created
+      with no columns at all.
+
+    .. change::
+        :tags: engine, feature
+        :tickets: 2407
+
+      Added "no_parameters=True" execution
+      option for connections.   If no parameters
+      are present, will pass the statement
+      as cursor.execute(statement), thereby invoking
+      the DBAPIs behavior when no parameter collection
+      is present; for psycopg2 and mysql-python, this
+      means not interpreting % signs in the string.
+      This only occurs with this option, and not
+      just if the param list is blank, as otherwise
+      this would produce inconsistent behavior
+      of SQL expressions that normally escape percent
+      signs (and while compiling, can't know ahead of
+      time if parameters will be present in
+      some cases).
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 
+
+      Added execution_options() call to
+      MockConnection (i.e., that used with
+      strategy="mock") which acts as a pass through
+      for arguments.
+
+    .. change::
+        :tags: engine, feature
+        :tickets: 2378
+
+      Added pool_reset_on_return argument
+      to create_engine, allows control over
+      "connection return" behavior.  Also added
+      new arguments 'rollback', 'commit', None
+      to pool.reset_on_return to allow more control
+      over connection return activity.
+
+    .. change::
+        :tags: engine, feature
+        :tickets: 
+
+      Added some decent context managers
+      to Engine, Connection:
+      
+          with engine.begin() as conn:
+              <work with conn in a transaction>
+      
+      and:
+      
+          with engine.connect() as conn:
+              <work with conn>
+      
+      Both close out the connection when done,
+      commit or rollback transaction with errors
+      on engine.begin().
+
+    .. change::
+        :tags: sqlite, bug
+        :tickets: 2432
+
+      Fixed bug in C extensions whereby
+      string format would not be applied to a
+      Numeric value returned as integer; this
+      affected primarily SQLite which does
+      not maintain numeric scale settings.
+
+    .. change::
+        :tags: mssql, feature
+        :tickets: 2430
+
+      Added support for MSSQL INSERT,
+      UPDATE, and DELETE table hints, using
+      new with_hint() method on UpdateBase.
+
+    .. change::
+        :tags: feature, mysql
+        :tickets: 2386
+
+      Added support for MySQL index and
+      primary key constraint types
+      (i.e. USING) via new mysql_using parameter
+      to Index and PrimaryKeyConstraint,
+      courtesy Diana Clarke.
+
+    .. change::
+        :tags: feature, mysql
+        :tickets: 2394
+
+      Added support for the "isolation_level"
+      parameter to all MySQL dialects.  Thanks
+      to mu_mind for the patch here.
+
+    .. change::
+        :tags: oracle, feature
+        :tickets: 2399
+
+      Added a new create_engine() flag
+      coerce_to_decimal=False, disables the precision
+      numeric handling which can add lots of overhead
+      by converting all numeric values to
+      Decimal.
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2401
+
+      Added missing compilation support for
+      LONG
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2435
+
+      Added 'LEVEL' to the list of reserved
+      words for Oracle.
+
+    .. change::
+        :tags: examples, bug
+        :tickets: 
+
+      Altered _params_from_query() function
+      in Beaker example to pull bindparams from the
+      fully compiled statement, as a quick means
+      to get everything including subqueries in the
+      columns clause, etc.
+
+.. changelog::
+    :version: 0.7.5
+    :released: Sat Jan 28 2012
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2389
+
+      Fixed issue where modified session state
+      established after a failed flush would be committed
+      as part of the subsequent transaction that
+      begins automatically after manual call
+      to rollback().   The state of the session is
+      checked within rollback(), and if new state
+      is present, a warning is emitted and
+      restore_snapshot() is called a second time,
+      discarding those changes.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2345
+
+      Fixed regression from 0.7.4 whereby
+      using an already instrumented column from a
+      superclass as "polymorphic_on" failed to resolve
+      the underlying Column.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2370
+
+      Raise an exception if xyzload_all() is
+      used inappropriately with two non-connected
+      relationships.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 
+
+      Added "class_registry" argument to
+      declarative_base().  Allows two or more declarative
+      bases to share the same registry of class names.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 
+
+      query.filter() accepts multiple
+      criteria which will join via AND, i.e.
+      query.filter(x==y, z>q, ...)
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 2351
+
+      Added new capability to relationship
+      loader options to allow "default" loader strategies.
+      Pass '*' to any of joinedload(), lazyload(),
+      subqueryload(), or noload() and that becomes the
+      loader strategy used for all relationships,
+      except for those explicitly stated in the
+      Query.  Thanks to up-and-coming contributor
+      Kent Bower for an exhaustive and well
+      written test suite !
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2367
+
+      Fixed bug whereby event.listen(SomeClass)
+      forced an entirely unnecessary compile of the
+      mapper, making events very hard to set up
+      at module import time (nobody noticed this ??)
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 
+
+      Fixed bug whereby hybrid_property didn't
+      work as a kw arg in any(), has().
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed regression from 0.6 whereby if
+      "load_on_pending" relationship() flag were used
+      where a non-"get()" lazy clause needed to be
+      emitted on a pending object, it would fail
+      to load.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2371
+
+      ensure pickleability of all ORM exceptions
+      for multiprocessing compatibility.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2353
+
+      implemented standard "can't set attribute" /
+      "can't delete attribute" AttributeError when
+      setattr/delattr used on a hybrid that doesn't
+      define fset or fdel.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2362
+
+      Fixed bug where unpickled object didn't
+      have enough of its state set up to work
+      correctly within the unpickle() event established
+      by the mutable object extension, if the object
+      needed ORM attribute access within
+      __eq__() or similar.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2374
+
+      Fixed bug where "merge" cascade could
+      mis-interpret an unloaded attribute, if the
+      load_on_pending flag were used with
+      relationship().  Thanks to Kent Bower
+      for tests.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 2356
+
+      New declarative reflection example
+      added, illustrates how best to mix table reflection
+      with declarative as well as uses some new features
+      from.
+
+    .. change::
+        :tags: feature, sql
+        :tickets: 2356
+
+      New reflection feature "autoload_replace";
+      when set to False on Table, the Table can be autoloaded
+      without existing columns being replaced.  Allows
+      more flexible chains of Table construction/reflection
+      to be constructed, including that it helps with
+      combining Declarative with table reflection.
+      See the new example on the wiki.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2356
+
+      Improved the API for add_column() such that
+      if the same column is added to its own table,
+      an error is not raised and the constraints
+      don't get doubled up.  Also helps with some
+      reflection/declarative patterns.
+
+    .. change::
+        :tags: feature, sql
+        :tickets: 
+
+      Added "false()" and "true()" expression
+      constructs to sqlalchemy.sql namespace, though
+      not part of __all__ as of yet.
+
+    .. change::
+        :tags: feature, sql
+        :tickets: 2361
+
+      Dialect-specific compilers now raise
+      CompileException for all type/statement compilation
+      issues, instead of InvalidRequestError or ArgumentError.
+      The DDL for CREATE TABLE will re-raise
+      CompileExceptions to include table/column information
+      for the problematic column.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2381
+
+      Fixed issue where the "required" exception
+      would not be raised for bindparam() with required=True,
+      if the statement were given no parameters at all.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2371
+
+      Added __reduce__ to StatementError,
+      DBAPIError, column errors so that exceptions
+      are pickleable, as when using multiprocessing.
+      However, not
+      all DBAPIs support this yet, such as
+      psycopg2.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2382
+
+      Improved error messages when a non-string
+      or invalid string is passed to any of the
+      date/time processors used by SQLite, including
+      C and Python versions.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2377
+
+      Fixed bug whereby a table-bound Column
+      object named "<a>_<b>" which matched a column
+      labeled as "<tablename>_<colname>" could match
+      inappropriately when targeting in a result
+      set row.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2384
+
+      Fixed bug in "mock" strategy whereby
+      correct DDL visit method wasn't called, resulting
+      in "CREATE/DROP SEQUENCE" statements being
+      duplicated
+
+    .. change::
+        :tags: sqlite, bug
+        :tickets: 2364
+
+      the "name" of an FK constraint in SQLite
+      is reflected as "None", not "0" or other
+      integer value.
+      SQLite does not appear to support constraint
+      naming in any case.
+
+    .. change::
+        :tags: sqlite, bug
+        :tickets: 2368
+
+      sql.false() and sql.true() compile to
+      0 and 1, respectively in sqlite
+
+    .. change::
+        :tags: sqlite, bug
+        :tickets: 
+
+      removed an erroneous "raise" in the
+      SQLite dialect when getting table names
+      and view names, where logic is in place
+      to fall back to an older version of
+      SQLite that doesn't have the
+      "sqlite_temp_master" table.
+
+    .. change::
+        :tags: bug, mysql
+        :tickets: 2376
+
+      fixed regexp that filters out warnings
+      for non-reflected "PARTITION" directives,
+      thanks to George Reilly
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2340
+
+      Adjusted the regexp used in the
+      mssql.TIME type to ensure only six digits
+      are received for the "microseconds" portion
+      of the value, which is expected by
+      Python's datetime.time().  Note that
+      support for sending microseconds doesn't
+      seem to be possible yet with pyodbc
+      at least.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2347
+
+      Dropped the "30 char" limit on pymssql,
+      based on reports that it's doing things
+      better these days.  pymssql hasn't been
+      well tested and as the DBAPI is in flux
+      it's still not clear what the status
+      is on this driver and how SQLAlchemy's
+      implementation should adapt.
+
+    .. change::
+        :tags: oracle, bug
+        :tickets: 2388
+
+      Added ORA-03135 to the never ending
+      list of oracle "connection lost" errors
+
+    .. change::
+        :tags: core, bug
+        :tickets: 2379
+
+      Changed LRUCache, used by the mapper
+      to cache INSERT/UPDATE/DELETE statements,
+      to use an incrementing counter instead
+      of a timestamp to track entries, for greater
+      reliability versus using time.time(), which
+      can cause test failures on some platforms.
+
+    .. change::
+        :tags: core, bug
+        :tickets: 2383
+
+      Added a boolean check for the "finalize"
+      function within the pool connection proxy's
+      weakref callback before calling it, so that a
+      warning isn't emitted that this function is None
+      when the application is exiting and gc has
+      removed the function from the module before the
+      weakref callback was invoked.
+
+    .. change::
+        :tags: bug, py3k
+        :tickets: 2348
+
+      Fixed inappropriate usage of util.py3k
+      flag and renamed it to util.py3k_warning, since
+      this flag is intended to detect the -3 flag
+      series of import restrictions only.
+
+    .. change::
+        :tags: examples, feature
+        :tickets: 2313
+
+      Simplified the versioning example
+      a bit to use a declarative mixin as well
+      as an event listener, instead of a metaclass +
+      SessionExtension.
+
+    .. change::
+        :tags: examples, bug
+        :tickets: 2346
+
+      Fixed large_collection.py to close the
+      session before dropping tables.
+
+.. changelog::
+    :version: 0.7.4
+    :released: Fri Dec 09 2011
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2315
+
+      Fixed backref behavior when "popping" the
+      value off of a many-to-one in response to
+      a removal from a stale one-to-many - the operation
+      is skipped, since the many-to-one has since
+      been updated.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2264
+
+      After some years of not doing this, added
+      more granularity to the "is X a parent of Y"
+      functionality, which is used when determining
+      if the FK on "Y" needs to be "nulled out" as well
+      as if "Y" should be deleted with delete-orphan
+      cascade.   The test now takes into account the
+      Python identity of the parent as well its identity
+      key, to see if the last known parent of Y is
+      definitely X.   If a decision
+      can't be made, a StaleDataError is raised.  The
+      conditions where this error is raised are fairly
+      rare, requiring that the previous parent was
+      garbage collected, and previously
+      could very well inappropriately update/delete
+      a record that's since moved onto a new parent,
+      though there may be some cases where
+      "silent success" occurred previously that will now
+      raise in the face of ambiguity.
+      Expiring "Y" resets the "parent" tracker, meaning
+      X.remove(Y) could then end up deleting Y even
+      if X is stale, but this is the same behavior
+      as before; it's advised to expire X also in that
+      case.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2310
+
+      fixed inappropriate evaluation of user-mapped
+      object in a boolean context within query.get().  Also in 0.6.9.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2304
+
+      Added missing comma to PASSIVE_RETURN_NEVER_SET
+      symbol
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 1776
+
+      Cls.column.collate("some collation") now
+      works.   Also in 0.6.9
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2309
+
+      the value of a composite attribute is now
+      expired after an insert or update operation, instead
+      of regenerated in place.  This ensures that a
+      column value which is expired within a flush
+      will be loaded first, before the composite
+      is regenerated using that value.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2309, 2308
+
+      The fix in also emits the
+      "refresh" event when the composite value is
+      loaded on access, even if all column
+      values were already present, as is appropriate.
+      This fixes the "mutable" extension which relies
+      upon the "load" event to ensure the _parents
+      dictionary is up to date, fixes.
+      Thanks to Scott Torborg for the test case here.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2312
+
+      Fixed bug whereby a subclass of a subclass
+      using concrete inheritance in conjunction with
+      the new ConcreteBase or AbstractConcreteBase
+      would fail to apply the subclasses deeper than
+      one level to the "polymorphic loader" of each
+      base
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2312
+
+      Fixed bug whereby a subclass of a subclass
+      using the new AbstractConcreteBase would fail
+      to acquire the correct "base_mapper" attribute
+      when the "base" mapper was generated, thereby
+      causing failures later on.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2316
+
+      Fixed bug whereby column_property() created
+      against ORM-level column could be treated as
+      a distinct entity when producing certain
+      kinds of joined-inh joins.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2297
+
+      Fixed the error formatting raised when
+      a tuple is inadvertently passed to session.query().  Also in 0.6.9.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2328
+
+      Calls to query.join() to a single-table
+      inheritance subclass are now tracked, and
+      are used to eliminate the additional WHERE..
+      IN criterion normally tacked on with single
+      table inheritance, since the join should
+      accommodate it.  This allows OUTER JOIN
+      to a single table subclass to produce
+      the correct results, and overall will produce
+      fewer WHERE criterion when dealing with
+      single table inheritance joins.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2339
+
+      __table_args__ can now be passed as
+      an empty tuple as well as an empty dict..  Thanks to Fayaz Yusuf Khan
+      for the patch.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 2325
+
+      Updated warning message when setting
+      delete-orphan without delete to no longer
+      refer to 0.6, as we never got around to
+      upgrading this to an exception.  Ideally
+      this might be better as an exception but
+      it's not critical either way.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 2345, 2238
+
+      polymorphic_on now accepts many
+      new kinds of values:
+      
+        - standalone expressions that aren't
+          otherwise mapped
+        - column_property() objects
+        - string names of any column_property()
+          or attribute name of a mapped Column
+      
+      The docs include an example using
+      the case() construct, which is likely to be
+      a common constructed used here. and part of
+      
+      Standalone expressions in polymorphic_on
+      propagate to single-table inheritance
+      subclasses so that they are used in the
+      WHERE /JOIN clause to limit rows to that
+      subclass as is the usual behavior.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 2301
+
+      IdentitySet supports the - operator
+      as the same as difference(), handy when dealing
+      with Session.dirty etc.
+
+    .. change::
+        :tags: orm, feature
+        :tickets: 
+
+      Added new value for Column autoincrement
+      called "ignore_fk", can be used to force autoincrement
+      on a column that's still part of a ForeignKeyConstraint.
+      New example in the relationship docs illustrates
+      its use.
+
+    .. change::
+        :tags: orm, bug
+        :tickets: 
+
+      Fixed bug in get_history() when referring
+      to a composite attribute that has no value;
+      added coverage for get_history() regarding
+      composites which is otherwise just a userland
+      function.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2316, 2261
+
+      related to, made some
+      adjustments to the change from
+      regarding the "from" list on a select(). The
+      _froms collection is no longer memoized, as this
+      simplifies various use cases and removes the
+      need for a "warning" if a column is attached
+      to a table after it was already used in an
+      expression - the select() construct will now
+      always produce the correct expression.
+      There's probably no real-world
+      performance hit here; select() objects are
+      almost always made ad-hoc, and systems that
+      wish to optimize the re-use of a select()
+      would be using the "compiled_cache" feature.
+      A hit which would occur when calling select.bind
+      has been reduced, but the vast majority
+      of users shouldn't be using "bound metadata"
+      anyway :).
+
+    .. change::
+        :tags: feature, sql
+        :tickets: 2166, 1944
+
+      The update() construct can now accommodate
+      multiple tables in the WHERE clause, which will
+      render an "UPDATE..FROM" construct, recognized by
+      Postgresql and MSSQL.  When compiled on MySQL,
+      will instead generate "UPDATE t1, t2, ..".  MySQL
+      additionally can render against multiple tables in the
+      SET clause, if Column objects are used as keys
+      in the "values" parameter or generative method.
+
+    .. change::
+        :tags: feature, sql
+        :tickets: 77
+
+      Added accessor to types called "python_type",
+      returns the rudimentary Python type object
+      for a particular TypeEngine instance, if known,
+      else raises NotImplementedError.
+
+    .. change::
+        :tags: bug, sql
+        :tickets: 2261, 2319
+
+      further tweak to the fix from,
+      so that generative methods work a bit better
+      off of cloned (this is almost a non-use case though).
+      In particular this allows with_only_columns()
+      to behave more consistently.   Added additional
+      documentation to with_only_columns() to clarify
+      expected behavior, which changed as a result
+      of.
+
+    .. change::
+        :tags: engine, bug
+        :tickets: 2317
+
+      Fixed bug whereby transaction.rollback()
+      would throw an error on an invalidated
+      connection if the transaction were a
+      two-phase or savepoint transaction.
+      For plain transactions, rollback() is a no-op
+      if the connection is invalidated, so while
+      it wasn't 100% clear if it should be a no-op,
+      at least now the interface is consistent.
+
+    .. change::
+        :tags: feature, schema
+        :tickets: 
+
+      Added new support for remote "schemas":
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      MetaData() accepts "schema" and "quote_schema"
+      arguments, which will be applied to the same-named
+      arguments of a Table
+      or Sequence which leaves these at their default
+      of ``None``.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Sequence accepts "quote_schema" argument
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      tometadata() for Table will use the "schema"
+      of the incoming MetaData for the new Table
+      if the schema argument is explicitly "None"
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Added CreateSchema and DropSchema DDL
+      constructs - these accept just the string
+      name of a schema and a "quote" flag.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      When using default "schema" with MetaData,
+      ForeignKey will also assume the "default" schema
+      when locating remote table.  This allows the "schema"
+      argument on MetaData to be applied to any
+      set of Table objects that otherwise don't have
+      a "schema".
+
+    .. change::
+        :tags: schema
+        :tickets: 1679
+
+      a "has_schema" method has been implemented
+        on dialect, but only works on Postgresql so far.
+      Courtesy Manlio Perillo.
+
+    .. change::
+        :tags: feature, schema
+        :tickets: 1410
+
+      The "extend_existing" flag on Table
+      now allows for the reflection process to take
+      effect for a Table object that's already been
+      defined; when autoload=True and extend_existing=True
+      are both set, the full set of columns will be
+      reflected from the Table which will then
+      *overwrite* those columns already present,
+      rather than no activity occurring.  Columns that
+      are present directly in the autoload run
+      will be used as always, however.
+
+    .. change::
+        :tags: bug, schema
+        :tickets: 
+
+      Fixed bug whereby TypeDecorator would
+      return a stale value for _type_affinity, when
+      using a TypeDecorator that "switches" types,
+      like the CHAR/UUID type.
+
+    .. change::
+        :tags: bug, schema
+        :tickets: 
+
+      Fixed bug whereby "order_by='foreign_key'"
+      option to Inspector.get_table_names
+      wasn't implementing the sort properly, replaced
+      with the existing sort algorithm
+
+    .. change::
+        :tags: bug, schema
+        :tickets: 2305
+
+      the "name" of a column-level CHECK constraint,
+      if present, is now rendered in the CREATE TABLE
+      statement using "CONSTRAINT <name> CHECK <expression>".
+
+    .. change::
+        :tags: pyodbc, bug
+        :tickets: 2318
+
+      pyodbc-based dialects now parse the
+      pyodbc accurately as far as observed
+      pyodbc strings, including such gems
+      as "py3-3.0.1-beta4"
+
+    .. change::
+        :tags: postgresql, bug
+        :tickets: 2311
+
+      Postgresql dialect memoizes that an ENUM of a
+      particular name was processed
+      during a create/drop sequence.  This allows
+      a create/drop sequence to work without any
+      calls to "checkfirst", and also means with
+      "checkfirst" turned on it only needs to
+      check for the ENUM once.
+
+    .. change::
+        :tags: postgresql, feature
+        :tickets: 
+
+      Added create_type constructor argument
+      to pg.ENUM.  When False, no CREATE/DROP or
+      checking for the type will be performed as part
+      of a table create/drop event; only the
+      create()/drop)() methods called directly
+      will do this.  Helps with Alembic "offline"
+      scripts.
+
+    .. change::
+        :tags: mssql, feature
+        :tickets: 822
+
+      lifted the restriction on SAVEPOINT
+      for SQL Server.  All tests pass using it,
+      it's not known if there are deeper issues
+      however.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2336
+
+      repaired the with_hint() feature which
+      wasn't implemented correctly on MSSQL -
+      usually used for the "WITH (NOLOCK)" hint
+      (which you shouldn't be using anyway !
+      use snapshot isolation instead :) )
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2318
+
+      use new pyodbc version detection for
+      _need_decimal_fix option.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2343
+
+      don't cast "table name" as NVARCHAR
+      on SQL Server 2000.  Still mostly in the dark
+      what incantations are needed to make PyODBC
+      work fully with FreeTDS 0.91 here, however.
+
+    .. change::
+        :tags: mssql, bug
+        :tickets: 2269
+
+      Decode incoming values when retrieving
+      list of index names and the names of columns
+      within those indexes.
+
+    .. change::
+        :tags: bug, mysql
+        :tickets: 
+
+      Unicode adjustments allow latest pymysql
+      (post 0.4) to pass 100% on Python 2.
+
+    .. change::
+        :tags: ext, feature
+        :tickets: 
+
+      Added an example to the hybrid docs
+      of a "transformer" - a hybrid that returns a
+      query-transforming callable in combination
+      with a custom comparator.   Uses a new method
+      on Query called with_transformation().  The use
+      case here is fairly experimental, but only
+      adds one line of code to Query.
+
+    .. change::
+        :tags: ext, bug
+        :tickets: 
+
+      the @compiles decorator raises an
+      informative error message when no "default"
+      compilation handler is present, rather
+      than KeyError.
+
+    .. change::
+        :tags: examples, bug
+        :tickets: 
+
+      Fixed bug in history_meta.py example where
+      the "unique" flag was not removed from a
+      single-table-inheritance subclass which
+      generates columns to put up onto the base.
+
+.. changelog::
+    :version: 0.7.3
+    :released: Sun Oct 16 2011
+
+    .. change::
+        :tags: general
+        :tickets: 2279
+
+      Adjusted the "importlater" mechanism, which is
+      used internally to resolve import cycles,
+      such that the usage of __import__ is completed
+      when the import of sqlalchemy or sqlalchemy.orm
+      is done, thereby avoiding any usage of __import__
+      after the application starts new threads,
+      fixes.  Also in 0.6.9.
+
+    .. change::
+        :tags: orm
+        :tickets: 2298
+
+      Improved query.join() such that the "left" side
+      can more flexibly be a non-ORM selectable,
+      such as a subquery.   A selectable placed
+      in select_from() will now be used as the left
+      side, favored over implicit usage
+      of a mapped entity.
+      If the join still fails based on lack of
+      foreign keys, the error message includes
+      this detail.  Thanks to brianrhude
+      on IRC for the test case.
+
+    .. change::
+        :tags: orm
+        :tickets: 2241
+
+      Added after_soft_rollback() Session event.  This
+      event fires unconditionally whenever rollback()
+      is called, regardless of if an actual DBAPI
+      level rollback occurred.  This event
+      is specifically designed to allow operations
+      with the Session to proceed after a rollback
+      when the Session.is_active is True.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added "adapt_on_names" boolean flag to orm.aliased()
+      construct.  Allows an aliased() construct
+      to link the ORM entity to a selectable that contains
+      aggregates or other derived forms of a particular
+      attribute, provided the name is the same as that
+      of the entity mapped column.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added new flag expire_on_flush=False to column_property(),
+      marks those properties that would otherwise be considered
+      to be "readonly", i.e. derived from SQL expressions,
+      to retain their value after a flush has occurred, including
+      if the parent object itself was involved in an update.
+
+    .. change::
+        :tags: orm
+        :tickets: 2237
+
+      Enhanced the instrumentation in the ORM to support
+      Py3K's new argument style of "required kw arguments",
+      i.e. fn(a, b, *, c, d), fn(a, b, *args, c, d).
+      Argument signatures of mapped object's __init__
+      method will be preserved, including required kw rules.
+
+    .. change::
+        :tags: orm
+        :tickets: 2282
+
+      Fixed bug in unit of work whereby detection of
+      "cycles" among classes in highly interlinked patterns
+      would not produce a deterministic
+      result; thereby sometimes missing some nodes that
+      should be considered cycles and causing further
+      issues down the road.  Note this bug is in 0.6
+      also; not backported at the moment.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Fixed a variety of synonym()-related regressions
+      from 0.6:
+          - making a synonym against a synonym now works.
+          - synonyms made against a relationship() can
+            be passed to query.join(), options sent
+            to query.options(), passed by name
+            to query.with_parent().
+
+    .. change::
+        :tags: orm
+        :tickets: 2287
+
+      Fixed bug whereby mapper.order_by attribute would
+      be ignored in the "inner" query within a
+      subquery eager load. .
+      Also in 0.6.9.
+
+    .. change::
+        :tags: orm
+        :tickets: 2267
+
+      Identity map .discard() uses dict.pop(,None)
+      internally instead of "del" to avoid KeyError/warning
+      during a non-determinate gc teardown
+
+    .. change::
+        :tags: orm
+        :tickets: 2253
+
+      Fixed regression in new composite rewrite where
+      deferred=True option failed due to missing
+      import
+
+    .. change::
+        :tags: orm
+        :tickets: 2248
+
+      Reinstated "comparator_factory" argument to
+      composite(), removed when 0.7 was released.
+
+    .. change::
+        :tags: orm
+        :tickets: 2247
+
+      Fixed bug in query.join() which would occur
+      in a complex multiple-overlapping path scenario,
+      where the same table could be joined to
+      twice.  Thanks *much* to Dave Vitek
+      for the excellent fix here.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query will convert an OFFSET of zero when
+      slicing into None, so that needless OFFSET
+      clauses are not invoked.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Repaired edge case where mapper would fail
+      to fully update internal state when a relationship
+      on a new mapper would establish a backref on the
+      first mapper.
+
+    .. change::
+        :tags: orm
+        :tickets: 2260
+
+      Fixed bug whereby if __eq__() was
+      redefined, a relationship many-to-one lazyload
+      would hit the __eq__() and fail. 
+      Does not apply to 0.6.9.
+
+    .. change::
+        :tags: orm
+        :tickets: 2196
+
+      Calling class_mapper() and passing in an object
+      that is not a "type" (i.e. a class that could
+      potentially be mapped) now raises an informative
+      ArgumentError, rather than UnmappedClassError.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      New event hook, MapperEvents.after_configured().
+      Called after a configure() step has completed and
+      mappers were in fact affected.   Theoretically this
+      event is called once per application, unless new mappings
+      are constructed after existing ones have been used
+      already.
+
+    .. change::
+        :tags: orm
+        :tickets: 2281
+
+      When an open Session is garbage collected, the objects
+      within it which remain are considered detached again
+      when they are add()-ed to a new Session.
+      This is accomplished by an extra check that the previous
+      "session_key" doesn't actually exist among the pool
+      of Sessions.
+
+    .. change::
+        :tags: orm
+        :tickets: 2239
+
+      New declarative features:
+          - __declare_last__() method, establishes an event
+          listener for the class method that will be called
+          when mappers are completed with the final "configure"
+          step.
+          - __abstract__ flag.   The class will not be mapped
+          at all when this flag is present on the class.
+          - New helper classes ConcreteBase, AbstractConcreteBase.
+          Allow concrete mappings using declarative which automatically
+          set up the "polymorphic_union" when the "configure"
+          mapper step is invoked.
+          - The mapper itself has semi-private methods that allow
+          the "with_polymorphic" selectable to be assigned
+          to the mapper after it has already been configured.
+
+    .. change::
+        :tags: orm
+        :tickets: 2283
+
+      Declarative will warn when a subclass' base uses
+      @declared_attr for a regular column - this attribute
+      does not propagate to subclasses.
+
+    .. change::
+        :tags: orm
+        :tickets: 2280
+
+      The integer "id" used to link a mapped instance with
+      its owning Session is now generated by a sequence
+      generation function rather than id(Session), to
+      eliminate the possibility of recycled id() values
+      causing an incorrect result, no need to check that
+      object actually in the session.
+
+    .. change::
+        :tags: orm
+        :tickets: 2257
+
+      Behavioral improvement: empty
+      conjunctions such as and_() and or_() will be
+      flattened in the context of an enclosing conjunction,
+      i.e. and_(x, or_()) will produce 'X' and not 'X AND
+      ()'..
+
+    .. change::
+        :tags: orm
+        :tickets: 2261
+
+      Fixed bug regarding calculation of "from" list
+      for a select() element.  The "from" calc is now
+      delayed, so that if the construct uses a Column
+      object that is not yet attached to a Table,
+      but is later associated with a Table, it generates
+      SQL using the table as a FROM.   This change
+      impacted fairly deeply the mechanics of how
+      the FROM list as well as the "correlates" collection
+      is calculated, as some "clause adaption" schemes
+      (these are used very heavily in the ORM)
+      were relying upon the fact that the "froms"
+      collection would typically be cached before the
+      adaption completed.   The rework allows it
+      such that the "froms" collection can be cleared
+      and re-generated at any time.
+
+    .. change::
+        :tags: orm
+        :tickets: 2270
+
+      Fixed bug whereby with_only_columns() method of
+      Select would fail if a selectable were passed..  Also in 0.6.9.
+
+    .. change::
+        :tags: schema
+        :tickets: 2284
+
+      Modified Column.copy() to use _constructor(),
+      which defaults to self.__class__, in order to
+      create the new object.  This allows easier support
+      of subclassing Column.
+
+    .. change::
+        :tags: schema
+        :tickets: 2223
+
+      Added a slightly nicer __repr__() to SchemaItem
+      classes.  Note the repr here can't fully support
+      the "repr is the constructor" idea since schema
+      items can be very deeply nested/cyclical, have
+      late initialization of some things, etc.
+
+    .. change::
+        :tags: engine
+        :tickets: 2254
+
+      The recreate() method in all pool classes uses
+      self.__class__ to get at the type of pool
+      to produce, in the case of subclassing.  Note
+      there's no usual need to subclass pools.
+
+    .. change::
+        :tags: engine
+        :tickets: 2243
+
+      Improvement to multi-param statement logging,
+      long lists of bound parameter sets will be
+      compressed with an informative indicator
+      of the compression taking place.  Exception
+      messages use the same improved formatting.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Added optional "sa_pool_key" argument to
+      pool.manage(dbapi).connect() so that serialization
+      of args is not necessary.
+
+    .. change::
+        :tags: engine
+        :tickets: 2286
+
+      The entry point resolution supported by
+      create_engine() now supports resolution of
+      individual DBAPI drivers on top of a built-in
+      or entry point-resolved dialect, using the
+      standard '+' notation - it's converted to
+      a '.' before being resolved as an entry
+      point.
+
+    .. change::
+        :tags: engine
+        :tickets: 2299
+
+      Added an exception catch + warning for the
+      "return unicode detection" step within connect,
+      allows databases that crash on NVARCHAR to
+      continue initializing, assuming no NVARCHAR
+      type implemented.
+
+    .. change::
+        :tags: types
+        :tickets: 2258
+
+      Extra keyword arguments to the base Float
+      type beyond "precision" and "asdecimal" are ignored;
+      added a deprecation warning here and additional
+      docs, related to
+
+    .. change::
+        :tags: sqlite
+        :tickets: 
+
+      Ensured that the same ValueError is raised for
+      illegal date/time/datetime string parsed from
+      the database regardless of whether C
+      extensions are in use or not.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2290
+
+      Added "postgresql_using" argument to Index(), produces
+      USING clause to specify index implementation for
+      PG. .  Thanks to Ryan P. Kelly for
+      the patch.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1839
+
+      Added client_encoding parameter to create_engine()
+      when the postgresql+psycopg2 dialect is used;
+      calls the psycopg2 set_client_encoding() method
+      with the value upon connect.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2291, 2141
+
+      Fixed bug related to whereby the
+      same modified index behavior in PG 9 affected
+      primary key reflection on a renamed column..  Also in 0.6.9.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2256
+
+      Reflection functions for Table, Sequence no longer
+      case insensitive.  Names can be differ only in case
+      and will be correctly distinguished.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Use an atomic counter as the "random number"
+      source for server side cursor names;
+      conflicts have been reported in rare cases.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2249
+
+      Narrowed the assumption made when reflecting
+      a foreign-key referenced table with schema in
+      the current search path; an explicit schema will
+      be applied to the referenced table only if
+      it actually matches that of the referencing table,
+      which also has an explicit schema.   Previously
+      it was assumed that "current" schema was synonymous
+      with the full search_path.
+
+    .. change::
+        :tags: mysql
+        :tickets: 2225
+
+      a CREATE TABLE will put the COLLATE option
+      after CHARSET, which appears to be part of
+      MySQL's arbitrary rules regarding if it will actually
+      work or not.   Also in 0.6.9.
+
+    .. change::
+        :tags: mysql
+        :tickets: 2293
+
+      Added mysql_length parameter to Index construct,
+      specifies "length" for indexes.
+
+    .. change::
+        :tags: mssql
+        :tickets: 2273
+
+      Changes to attempt support of FreeTDS 0.91 with
+      Pyodbc.  This includes that string binds are sent as
+      Python unicode objects when FreeTDS 0.91 is detected,
+      and a CAST(? AS NVARCHAR) is used when we detect
+      for a table.   However, I'd continue
+      to characterize Pyodbc + FreeTDS 0.91 behavior as
+      pretty crappy, there are still many queries such
+      as used in reflection which cause a core dump on
+      Linux, and it is not really usable at all
+      on OSX, MemoryErrors abound and just plain broken
+      unicode support.
+
+    .. change::
+        :tags: mssql
+        :tickets: 2277
+
+      The behavior of =/!= when comparing a scalar select
+      to a value will no longer produce IN/NOT IN as of 0.8;
+      this behavior is a little too heavy handed (use in_() if
+      you want to emit IN) and now emits a deprecation warning.
+      To get the 0.8 behavior immediately and remove the warning,
+      a compiler recipe is given at
+      http://www.sqlalchemy.org/docs/07/dialects/mssql.html#scalar-select-comparisons
+      to override the behavior of visit_binary().
+
+    .. change::
+        :tags: mssql
+        :tickets: 2222
+
+      "0" is accepted as an argument for limit() which
+      will produce "TOP 0".
+
+    .. change::
+        :tags: oracle
+        :tickets: 2272
+
+      Fixed ReturningResultProxy for zxjdbc dialect..  Regression from 0.6.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2252
+
+      The String type now generates VARCHAR2 on Oracle
+      which is recommended as the default VARCHAR.
+      Added an explicit VARCHAR2 and NVARCHAR2 to the Oracle
+      dialect as well.   Using NVARCHAR still generates
+      "NVARCHAR2" - there is no "NVARCHAR" on Oracle -
+      this remains a slight breakage of the "uppercase types
+      always give exactly that" policy.  VARCHAR still
+      generates "VARCHAR", keeping with the policy.   If
+      Oracle were to ever define "VARCHAR" as something
+      different as they claim (IMHO this will never happen),
+      the type would be available.
+
+    .. change::
+        :tags: ext
+        :tickets: 2262
+
+      SQLSoup will not be included in version 0.8
+      of SQLAlchemy; while useful, we would like to
+      keep SQLAlchemy itself focused on one ORM
+      usage paradigm.  SQLSoup will hopefully
+      soon be superseded by a third party
+      project.
+
+    .. change::
+        :tags: ext
+        :tickets: 2236
+
+      Added local_attr, remote_attr, attr accessors
+      to AssociationProxy, providing quick access
+      to the proxied attributes at the class
+      level.
+
+    .. change::
+        :tags: ext
+        :tickets: 2275
+
+      Changed the update() method on association proxy
+      dictionary to use a duck typing approach, i.e.
+      checks for "keys", to discern between update({})
+      and update((a, b)).   Previously, passing a
+      dictionary that had tuples as keys would be misinterpreted
+      as a sequence.
+
+    .. change::
+        :tags: examples
+        :tickets: 2266
+
+      Adjusted dictlike-polymorphic.py example
+      to apply the CAST such that it works on
+      PG, other databases. 
+      Also in 0.6.9.
+
+.. changelog::
+    :version: 0.7.2
+    :released: Sun Jul 31 2011
+
+    .. change::
+        :tags: orm
+        :tickets: 2213
+
+      Feature enhancement: joined and subquery
+      loading will now traverse already-present related
+      objects and collections in search of unpopulated
+      attributes throughout the scope of the eager load
+      being defined, so that the eager loading that is
+      specified via mappings or query options
+      unconditionally takes place for the full depth,
+      populating whatever is not already populated.
+      Previously, this traversal would stop if a related
+      object or collection were already present leading
+      to inconsistent behavior (though would save on
+      loads/cycles for an already-loaded graph). For a
+      subqueryload, this means that the additional
+      SELECT statements emitted by subqueryload will
+      invoke unconditionally, no matter how much of the
+      existing graph is already present (hence the
+      controversy). The previous behavior of "stopping"
+      is still in effect when a query is the result of
+      an attribute-initiated lazyload, as otherwise an
+      "N+1" style of collection iteration can become
+      needlessly expensive when the same related object
+      is encountered repeatedly. There's also an
+      as-yet-not-public generative Query method
+      _with_invoke_all_eagers()
+      which selects old/new behavior
+
+    .. change::
+        :tags: orm
+        :tickets: 2195
+
+      A rework of "replacement traversal" within
+      the ORM as it alters selectables to be against
+      aliases of things (i.e. clause adaption) includes
+      a fix for multiply-nested any()/has() constructs
+      against a joined table structure.
+
+    .. change::
+        :tags: orm
+        :tickets: 2234
+
+      Fixed bug where query.join() + aliased=True
+      from a joined-inh structure to itself on
+      relationship() with join condition on the child
+      table would convert the lead entity into the
+      joined one inappropriately. 
+      Also in 0.6.9.
+
+    .. change::
+        :tags: orm
+        :tickets: 2205
+
+      Fixed regression from 0.6 where Session.add()
+      against an object which contained None in a
+      collection would raise an internal exception.
+      Reverted this to 0.6's behavior which is to
+      accept the None but obviously nothing is
+      persisted.  Ideally, collections with None
+      present or on append() should at least emit a
+      warning, which is being considered for 0.8.
+
+    .. change::
+        :tags: orm
+        :tickets: 2191
+
+      Load of a deferred() attribute on an object
+      where row can't be located raises
+      ObjectDeletedError instead of failing later
+      on; improved the message in ObjectDeletedError
+      to include other conditions besides a simple
+      "delete".
+
+    .. change::
+        :tags: orm
+        :tickets: 2224
+
+      Fixed regression from 0.6 where a get history
+      operation on some relationship() based attributes
+      would fail when a lazyload would emit; this could
+      trigger within a flush() under certain conditions.  Thanks to the user who submitted
+      the great test for this.
+
+    .. change::
+        :tags: orm
+        :tickets: 2228
+
+      Fixed bug apparent only in Python 3 whereby
+      sorting of persistent + pending objects during
+      flush would produce an illegal comparison,
+      if the persistent object primary key
+      is not a single integer. 
+      Also in 0.6.9
+
+    .. change::
+        :tags: orm
+        :tickets: 2197
+
+      Fixed bug whereby the source clause
+      used by query.join() would be inconsistent
+      if against a column expression that combined
+      multiple entities together. 
+      Also in 0.6.9
+
+    .. change::
+        :tags: orm
+        :tickets: 2215
+
+      Fixed bug whereby if a mapped class
+      redefined __hash__() or __eq__() to something
+      non-standard, which is a supported use case
+      as SQLA should never consult these,
+      the methods would be consulted if the class
+      was part of a "composite" (i.e. non-single-entity)
+      result set. 
+      Also in 0.6.9.
+
+    .. change::
+        :tags: orm
+        :tickets: 2240
+
+      Added public attribute ".validators" to
+      Mapper, an immutable dictionary view of
+      all attributes that have been decorated
+      with the @validates decorator. courtesy Stefano Fontanelli
+
+    .. change::
+        :tags: orm
+        :tickets: 2188
+
+      Fixed subtle bug that caused SQL to blow
+      up if: column_property() against subquery +
+      joinedload + LIMIT + order by the column
+      property() occurred. .
+      Also in 0.6.9
+
+    .. change::
+        :tags: orm
+        :tickets: 2207
+
+      The join condition produced by with_parent
+      as well as when using a "dynamic" relationship
+      against a parent will generate unique
+      bindparams, rather than incorrectly repeating
+      the same bindparam. .
+      Also in 0.6.9.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Added the same "columns-only" check to
+      mapper.polymorphic_on as used when
+      receiving user arguments to
+      relationship.order_by, foreign_keys,
+      remote_side, etc.
+
+    .. change::
+        :tags: orm
+        :tickets: 2190
+
+      Fixed bug whereby comparison of column
+      expression to a Query() would not call
+      as_scalar() on the underlying SELECT
+      statement to produce a scalar subquery,
+      in the way that occurs if you called
+      it on Query().subquery().
+
+    .. change::
+        :tags: orm
+        :tickets: 2194
+
+      Fixed declarative bug where a class inheriting
+      from a superclass of the same name would fail
+      due to an unnecessary lookup of the name
+      in the _decl_class_registry.
+
+    .. change::
+        :tags: orm
+        :tickets: 2199
+
+      Repaired the "no statement condition"
+      assertion in Query which would attempt
+      to raise if a generative method were called
+      after from_statement() were called..  Also in 0.6.9.
+
+    .. change::
+        :tags: sql
+        :tickets: 2188
+
+      Fixed two subtle bugs involving column
+      correspondence in a selectable,
+      one with the same labeled subquery repeated, the other
+      when the label has been "grouped" and
+      loses itself.  Affects.
+
+    .. change::
+        :tags: schema
+        :tickets: 2187
+
+      New feature: with_variant() method on
+      all types.  Produces an instance of Variant(),
+      a special TypeDecorator which will select
+      the usage of a different type based on the
+      dialect in use.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Added an informative error message when
+      ForeignKeyConstraint refers to a column name in
+      the parent that is not found.  Also in 0.6.9.
+
+    .. change::
+        :tags: schema
+        :tickets: 2206
+
+      Fixed bug whereby adaptation of old append_ddl_listener()
+      function was passing unexpected **kw through
+      to the Table event.   Table gets no kws, the MetaData
+      event in 0.6 would get "tables=somecollection",
+      this behavior is preserved.
+
+    .. change::
+        :tags: schema
+        :tickets: 
+
+      Fixed bug where "autoincrement" detection on
+      Table would fail if the type had no "affinity"
+      value, in particular this would occur when using
+      the UUID example on the site that uses TypeEngine
+      as the "impl".
+
+    .. change::
+        :tags: schema
+        :tickets: 2209
+
+      Added an improved repr() to TypeEngine objects
+      that will only display constructor args which
+      are positional or kwargs that deviate
+      from the default.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Context manager provided by Connection.begin()
+      will issue rollback() if the commit() fails,
+      not just if an exception occurs.
+
+    .. change::
+        :tags: engine
+        :tickets: 1682
+
+      Use urllib.parse_qsl() in Python 2.6 and above,
+      no deprecation warning about cgi.parse_qsl()
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Added mixin class sqlalchemy.ext.DontWrapMixin.
+      User-defined exceptions of this type are never
+      wrapped in StatementException when they
+      occur in the context of a statement
+      execution.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      StatementException wrapping will display the
+      original exception class in the message.
+
+    .. change::
+        :tags: engine
+        :tickets: 2201
+
+      Failures on connect which raise dbapi.Error
+      will forward the error to dialect.is_disconnect()
+      and set the "connection_invalidated" flag if
+      the dialect knows this to be a potentially
+      "retryable" condition.  Only Oracle ORA-01033
+      implemented for now.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 2189
+
+      SQLite dialect no longer strips quotes
+      off of reflected default value, allowing
+      a round trip CREATE TABLE to work.
+      This is consistent with other dialects
+      that also maintain the exact form of
+      the default.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2198
+
+      Added new "postgresql_ops" argument to
+      Index, allows specification of PostgreSQL
+      operator classes for indexed columns.  Courtesy Filip Zyzniewski.
+
+    .. change::
+        :tags: mysql
+        :tickets: 2186
+
+      Fixed OurSQL dialect to use ansi-neutral
+      quote symbol "'" for XA commands instead
+      of '"'. .  Also in 0.6.9.
+
+    .. change::
+        :tags: mssql
+        :tickets: 
+
+      Adjusted the pyodbc dialect such that bound
+      values are passed as bytes and not unicode
+      if the "Easysoft" unix drivers are detected.
+      This is the same behavior as occurs with
+      FreeTDS.  Easysoft appears to segfault
+      if Python unicodes are passed under
+      certain circumstances.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2200
+
+      Added ORA-00028 to disconnect codes, use
+      cx_oracle _Error.code to get at the code,.  Also in 0.6.9.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2201
+
+      Added ORA-01033 to disconnect codes, which
+      can be caught during a connection
+      event.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2220
+
+      repaired the oracle.RAW type which did not
+      generate the correct DDL. 
+      Also in 0.6.9.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2212
+
+      added CURRENT to reserved word list. Also in 0.6.9.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Fixed bug in the mutable extension whereby
+      if the same type were used twice in one
+      mapping, the attributes beyond the first
+      would not get instrumented.
+
+    .. change::
+        :tags: oracle
+        :tickets: 
+
+      Fixed bug in the mutable extension whereby
+      if None or a non-corresponding type were set,
+      an error would be raised.  None is now accepted
+      which assigns None to all attributes,
+      illegal values raise ValueError.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      Repaired the examples/versioning test runner
+      to not rely upon SQLAlchemy test libs,
+      nosetests must be run from within
+      examples/versioning to get around setup.cfg
+      breaking it.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      Tweak to examples/versioning to pick the
+      correct foreign key in a multi-level
+      inheritance situation.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      Fixed the attribute shard example to check
+      for bind param callable correctly in 0.7
+      style.
+
+.. changelog::
+    :version: 0.7.1
+    :released: Sun Jun 05 2011
+
+    .. change::
+        :tags: general
+        :tickets: 2184
+
+      Added a workaround for Python bug 7511 where
+      failure of C extension build does not
+      raise an appropriate exception on Windows 64
+      bit + VC express
+
+    .. change::
+        :tags: orm
+        :tickets: 1912
+
+      "delete-orphan" cascade is now allowed on
+      self-referential relationships - this since
+      SQLA 0.7 no longer enforces "parent with no
+      child" at the ORM level; this check is left
+      up to foreign key nullability.
+      Related to
+
+    .. change::
+        :tags: orm
+        :tickets: 2180
+
+      Repaired new "mutable" extension to propagate
+      events to subclasses correctly; don't
+      create multiple event listeners for
+      subclasses either.
+
+    .. change::
+        :tags: orm
+        :tickets: 2170
+
+      Modify the text of the message which occurs
+      when the "identity" key isn't detected on
+      flush, to include the common cause that
+      the Column isn't set up to detect
+      auto-increment correctly;.
+      Also in 0.6.8.
+
+    .. change::
+        :tags: orm
+        :tickets: 2182
+
+      Fixed bug where transaction-level "deleted"
+      collection wouldn't be cleared of expunged
+      states, raising an error if they later
+      became transient.
+      Also in 0.6.8.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Fixed bug whereby metadata.reflect(bind)
+      would close a Connection passed as a
+      bind argument.  Regression from 0.6.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Streamlined the process by which a Select
+      determines what's in it's '.c' collection.
+      Behaves identically, except that a
+      raw ClauseList() passed to select([])
+      (which is not a documented case anyway) will
+      now be expanded into its individual column
+      elements instead of being ignored.
+
+    .. change::
+        :tags: engine
+        :tickets: 
+
+      Deprecate schema/SQL-oriented methods on
+      Connection/Engine that were never well known
+      and are redundant:  reflecttable(), create(),
+      drop(), text(), engine.func
+
+    .. change::
+        :tags: engine
+        :tickets: 2178
+
+      Adjusted the __contains__() method of
+      a RowProxy result row such that no exception
+      throw is generated internally;
+      NoSuchColumnError() also will generate its
+      message regardless of whether or not the column
+      construct can be coerced to a string..  Also in 0.6.8.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 2173
+
+      Accept None from cursor.fetchone() when
+      "PRAGMA read_uncommitted" is called to determine
+      current isolation mode at connect time and
+      default to SERIALIZABLE; this to support SQLite
+      versions pre-3.3.0 that did not have this
+      feature.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2175
+
+      Some unit test fixes regarding numeric arrays,
+      MATCH operator.   A potential floating-point
+      inaccuracy issue was fixed, and certain tests
+      of the MATCH operator only execute within an
+      EN-oriented locale for now. .
+      Also in 0.6.8.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      Unit tests pass 100% on MySQL installed
+      on windows.
+
+    .. change::
+        :tags: mysql
+        :tickets: 2181
+
+      Removed the "adjust casing" step that would
+      fail when reflecting a table on MySQL
+      on windows with a mixed case name.  After some
+      experimenting with a windows MySQL server, it's
+      been determined that this step wasn't really
+      helping the situation much; MySQL does not return
+      FK names with proper casing on non-windows
+      platforms either, and removing the step at
+      least allows the reflection to act more like
+      it does on other OSes.   A warning here
+      has been considered but its difficult to
+      determine under what conditions such a warning
+      can be raised, so punted on that for now -
+      added some docs instead.
+
+    .. change::
+        :tags: mysql
+        :tickets: 
+
+      supports_sane_rowcount will be set to False
+      if using MySQLdb and the DBAPI doesn't provide
+      the constants.CLIENT module.
+
+.. changelog::
+    :version: 0.7.0
+    :released: Fri May 20 2011
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      This section documents those changes from 0.7b4
+      to 0.7.0.  For an overview of what's new in
+      SQLAlchemy 0.7, see
+      http://www.sqlalchemy.org/trac/wiki/07Migration
+
+    .. change::
+        :tags: orm
+        :tickets: 2069
+
+      Fixed regression introduced in 0.7b4 (!) whereby
+      query.options(someoption("nonexistent name")) would
+      fail to raise an error.  Also added additional
+      error catching for cases where the option would
+      try to build off a column-based element, further
+      fixed up some of the error messages tailored
+      in
+
+    .. change::
+        :tags: orm
+        :tickets: 2162
+
+      query.count() emits "count(*)" instead of
+      "count(1)".
+
+    .. change::
+        :tags: orm
+        :tickets: 2155
+
+      Fine tuning of Query clause adaptation when
+      from_self(), union(), or other "select from
+      myself" operation, such that plain SQL expression
+      elements added to filter(), order_by() etc.
+      which are present in the nested "from myself"
+      query *will* be adapted in the same way an ORM
+      expression element will, since these
+      elements are otherwise not easily accessible.
+
+    .. change::
+        :tags: orm
+        :tickets: 2149
+
+      Fixed bug where determination of "self referential"
+      relationship would fail with no workaround
+      for joined-inh subclass related to itself,
+      or joined-inh subclass related to a subclass
+      of that with no cols in the sub-sub class
+      in the join condition. 
+      Also in 0.6.8.
+
+    .. change::
+        :tags: orm
+        :tickets: 2153
+
+      mapper() will ignore non-configured foreign keys
+      to unrelated tables when determining inherit
+      condition between parent and child class,
+      but will raise as usual for unresolved
+      columns and table names regarding the inherited
+      table.  This is an enhanced generalization of
+      behavior that was already applied to declarative
+      previously.    0.6.8 has a more
+      conservative version of this which doesn't
+      fundamentally alter how join conditions
+      are determined.
+
+    .. change::
+        :tags: orm
+        :tickets: 2144
+
+      It is an error to call query.get() when the
+      given entity is not a single, full class
+      entity or mapper (i.e. a column).  This is
+      a deprecation warning in 0.6.8.
+
+    .. change::
+        :tags: orm
+        :tickets: 2148
+
+      Fixed a potential KeyError which under some
+      circumstances could occur with the identity
+      map, part of
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      added Query.with_session() method, switches
+      Query to use a different session.
+
+    .. change::
+        :tags: orm
+        :tickets: 2131
+
+      horizontal shard query should use execution
+      options per connection as per
+
+    .. change::
+        :tags: orm
+        :tickets: 2151
+
+      a non_primary mapper will inherit the _identity_class
+      of the primary mapper.  This so that a non_primary
+      established against a class that's normally in an
+      inheritance mapping will produce results that are
+      identity-map compatible with that of the primary
+      mapper (also in 0.6.8)
+
+    .. change::
+        :tags: orm
+        :tickets: 2163
+
+      Fixed the error message emitted for "can't
+      execute syncrule for destination column 'q';
+      mapper 'X' does not map this column" to
+      reference the correct mapper. .
+      Also in 0.6.8.
+
+    .. change::
+        :tags: orm
+        :tickets: 1502
+
+      polymorphic_union() gets a "cast_nulls" option,
+      disables the usage of CAST when it renders
+      the labeled NULL columns.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      polymorphic_union() renders the columns in their
+      original table order, as according to the first
+      table/selectable in the list of polymorphic
+      unions in which they appear.  (which is itself
+      an unordered mapping unless you pass an OrderedDict).
+
+    .. change::
+        :tags: orm
+        :tickets: 2171
+
+      Fixed bug whereby mapper mapped to an anonymous
+      alias would fail if logging were used, due to
+      unescaped % sign in the alias name. 
+      Also in 0.6.8.
+
+    .. change::
+        :tags: sql
+        :tickets: 2167
+
+      Fixed bug whereby nesting a label of a select()
+      with another label in it would produce incorrect
+      exported columns.   Among other things this would
+      break an ORM column_property() mapping against
+      another column_property(). .
+      Also in 0.6.8
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Changed the handling in determination of join
+      conditions such that foreign key errors are
+      only considered between the two given tables.
+      That is, t1.join(t2) will report FK errors
+      that involve 't1' or 't2', but anything
+      involving 't3' will be skipped.   This affects
+      join(), as well as ORM relationship and
+      inherit condition logic.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Some improvements to error handling inside
+      of the execute procedure to ensure auto-close
+      connections are really closed when very
+      unusual DBAPI errors occur.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      metadata.reflect() and reflection.Inspector()
+      had some reliance on GC to close connections
+      which were internally procured, fixed this.
+
+    .. change::
+        :tags: sql
+        :tickets: 2140
+
+      Added explicit check for when Column .name
+      is assigned as blank string
+
+    .. change::
+        :tags: sql
+        :tickets: 2147
+
+      Fixed bug whereby if FetchedValue was passed
+      to column server_onupdate, it would not
+      have its parent "column" assigned, added
+      test coverage for all column default assignment
+      patterns.   also in 0.6.8
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Fixed the psycopg2_version parsing in the
+      psycopg2 dialect.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2141
+
+      Fixed bug affecting PG 9 whereby index reflection
+      would fail if against a column whose name
+      had changed. .  Also in 0.6.8.
+
+    .. change::
+        :tags: mssql
+        :tickets: 2169
+
+      Fixed bug in MSSQL dialect whereby the aliasing
+      applied to a schema-qualified table would leak
+      into enclosing select statements.
+      Also in 0.6.8.
+
+    .. change::
+        :tags: documentation
+        :tickets: 2152
+
+      Removed the usage of the "collections.MutableMapping"
+      abc from the ext.mutable docs as it was being used
+      incorrectly and makes the example more difficult
+      to understand in any case.
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      removed the ancient "polymorphic association"
+      examples and replaced with an updated set of
+      examples that use declarative mixins,
+      "generic_associations".   Each presents an alternative
+      table layout.
+
+    .. change::
+        :tags: ext
+        :tickets: 2143
+
+      Fixed bugs in sqlalchemy.ext.mutable extension where
+      `None` was not appropriately handled, replacement
+      events were not appropriately handled.
+
+.. changelog::
+    :version: 0.7.0b4
+    :released: Sun Apr 17 2011
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      Changes to the format of CHANGES, this file.
+      The format changes have been applied to
+      the 0.7 releases.
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      The "-declarative" changes will now be listed
+      directly under the "-orm" section, as these
+      are closely related.
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      The 0.5 series changes have been moved to
+      the file CHANGES_PRE_06 which replaces
+      CHANGES_PRE_05.
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      The changelog for 0.6.7 and subsequent within
+      the 0.6 series is now listed only in the
+      CHANGES file within the 0.6 branch.
+      In the 0.7 CHANGES file (i.e. this file), all the
+      0.6 changes are listed inline within the 0.7
+      section in which they were also applied
+      (since all 0.6 changes are in 0.7 as well).
+      Changes that apply to an 0.6 version here
+      are noted as are if any differences in
+      implementation/behavior are present.
+
+    .. change::
+        :tags: orm
+        :tickets: 2122
+
+      Some fixes to "evaulate" and "fetch" evaluation
+      when query.update(), query.delete() are called.
+      The retrieval of records is done after autoflush
+      in all cases, and before update/delete is
+      emitted, guarding against unflushed data present
+      as well as expired objects failing during
+      the evaluation.
+
+    .. change::
+        :tags: orm
+        :tickets: 2063
+
+      Reworded the exception raised when a flush
+      is attempted of a subclass that is not polymorphic
+      against the supertype.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Still more wording adjustments when a query option
+      can't find the target entity.  Explain that the
+      path must be from one of the root entities.
+
+    .. change::
+        :tags: orm
+        :tickets: 2123
+
+      Some fixes to the state handling regarding
+      backrefs, typically when autoflush=False, where
+      the back-referenced collection wouldn't
+      properly handle add/removes with no net
+      change.  Thanks to Richard Murri for the
+      test case + patch. 
+      (also in 0.6.7).
+
+    .. change::
+        :tags: orm
+        :tickets: 2127
+
+      Added checks inside the UOW to detect the unusual
+      condition of being asked to UPDATE or DELETE
+      on a primary key value that contains NULL
+      in it.
+
+    .. change::
+        :tags: orm
+        :tickets: 2127
+
+      Some refinements to attribute history.  More
+      changes are pending possibly in 0.8, but
+      for now history has been modified such that
+      scalar history doesn't have a "side effect"
+      of populating None for a non-present value.
+      This allows a slightly better ability to
+      distinguish between a None set and no actual
+      change, affects as well.
+
+    .. change::
+        :tags: orm
+        :tickets: 2130
+
+      a "having" clause would be copied from the
+      inside to the outside query if from_self()
+      were used; in particular this would break
+      an 0.7 style count() query.
+      (also in 0.6.7)
+
+    .. change::
+        :tags: orm
+        :tickets: 2131
+
+      the Query.execution_options() method now passes
+      those options to the Connection rather than
+      the SELECT statement, so that all available
+      options including isolation level and
+      compiled cache may be used.
+
+    .. change::
+        :tags: sql
+        :tickets: 2131
+
+      The "compiled_cache" execution option now raises
+      an error when passed to a SELECT statement
+      rather than a Connection.  Previously it was
+      being ignored entirely.   We may look into
+      having this option work on a per-statement
+      level at some point.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Restored the "catchall" constructor on the base
+      TypeEngine class, with a deprecation warning.
+      This so that code which does something like
+      Integer(11) still succeeds.
+
+    .. change::
+        :tags: sql
+        :tickets: 2104
+
+      Fixed regression whereby MetaData() coming
+      back from unpickling did not keep track of
+      new things it keeps track of now, i.e.
+      collection of Sequence objects, list
+      of schema names.
+
+    .. change::
+        :tags: sql
+        :tickets: 2116
+
+      The limit/offset keywords to select() as well
+      as the value passed to select.limit()/offset()
+      will be coerced to integer. 
+      (also in 0.6.7)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      fixed bug where "from" clause gathering from an
+      over() clause would be an itertools.chain() and
+      not a list, causing "can only concatenate list"
+      TypeError when combined with other clauses.
+
+    .. change::
+        :tags: sql
+        :tickets: 2134
+
+      Fixed incorrect usage of "," in over() clause
+      being placed between the "partition" and "order by"
+      clauses.
+
+    .. change::
+        :tags: sql
+        :tickets: 2105
+
+      Before/after attach events for PrimaryKeyConstraint
+      now function, tests added for before/after events
+      on all constraint types.
+
+    .. change::
+        :tags: sql
+        :tickets: 2117
+
+      Added explicit true()/false() constructs to expression
+      lib - coercion rules will intercept "False"/"True"
+      into these constructs.  In 0.6, the constructs were
+      typically converted straight to string, which was
+      no longer accepted in 0.7.
+
+    .. change::
+        :tags: engine
+        :tickets: 2129
+
+      The C extension is now enabled by default on CPython
+      2.x with a fallback to pure python if it fails to
+      compile.
+
+    .. change::
+        :tags: schema
+        :tickets: 2109
+
+      The 'useexisting' flag on Table has been superceded
+      by a new pair of flags 'keep_existing' and
+      'extend_existing'.   'extend_existing' is equivalent
+      to 'useexisting' - the existing Table is returned,
+      and additional constructor elements are added.
+      With 'keep_existing', the existing Table is returned,
+      but additional constructor elements are not added -
+      these elements are only applied when the Table
+      is newly created.
+
+    .. change::
+        :tags: types
+        :tickets: 2081
+
+      REAL has been added to the core types.  Supported
+      by Postgresql, SQL Server, MySQL, SQLite.  Note
+      that the SQL Server and MySQL versions, which
+      add extra arguments, are also still available
+      from those dialects.
+
+    .. change::
+        :tags: types
+        :tickets: 2106
+
+      Added @event.listens_for() decorator, given
+      target + event name, applies the decorated
+      function as a listener.
+
+    .. change::
+        :tags: pool
+        :tickets: 2103
+
+      AssertionPool now stores the traceback indicating
+      where the currently checked out connection was
+      acquired; this traceback is reported within
+      the assertion raised upon a second concurrent
+      checkout; courtesy Gunnlaugur Briem
+
+    .. change::
+        :tags: pool
+        :tickets: 
+
+      The "pool.manage" feature doesn't use pickle
+      anymore to hash the arguments for each pool.
+
+    .. change::
+        :tags: sqlite
+        :tickets: 2115
+
+      Fixed bug where reflection of foreign key
+      created as "REFERENCES <tablename>" without
+      col name would fail. 
+      (also in 0.6.7)
+
+    .. change::
+        :tags: postgresql
+        :tickets: 
+
+      Psycopg2 for Python 3 is now supported.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2132
+
+      Fixed support for precision numerics when using
+      pg8000.
+
+    .. change::
+        :tags: oracle
+        :tickets: 2100
+
+      Using column names that would require quotes
+      for the column itself or for a name-generated
+      bind parameter, such as names with special
+      characters, underscores, non-ascii characters,
+      now properly translate bind parameter keys when
+      talking to cx_oracle.   (Also
+      in 0.6.7)
+
+    .. change::
+        :tags: oracle
+        :tickets: 2116
+
+      Oracle dialect adds use_binds_for_limits=False
+      create_engine() flag, will render the LIMIT/OFFSET
+      values inline instead of as binds, reported to
+      modify the execution plan used by Oracle. (Also in 0.6.7)
+
+    .. change::
+        :tags: documentation
+        :tickets: 2029
+
+      Documented SQLite DATE/TIME/DATETIME types. (also in 0.6.7)
+
+    .. change::
+        :tags: documentation
+        :tickets: 2118
+
+      Fixed mutable extension docs to show the
+      correct type-association methods.
+
+.. changelog::
+    :version: 0.7.0b3
+    :released: Sun Mar 20 2011
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      Lots of fixes to unit tests when run under Pypy
+      (courtesy Alex Gaynor).
+
+    .. change::
+        :tags: orm
+        :tickets: 2093
+
+      Changed the underlying approach to query.count().
+      query.count() is now in all cases exactly:
+      
+          query.
+              from_self(func.count(literal_column('1'))).
+              scalar()
+      
+      That is, "select count(1) from (<full query>)".
+      This produces a subquery in all cases, but
+      vastly simplifies all the guessing count()
+      tried to do previously, which would still
+      fail in many scenarios particularly when
+      joined table inheritance and other joins
+      were involved.  If the subquery produced
+      for an otherwise very simple count is really
+      an issue, use query(func.count()) as an
+      optimization.
+
+    .. change::
+        :tags: orm
+        :tickets: 2087
+
+      some changes to the identity map regarding
+      rare weakref callbacks during iterations.
+      The mutex has been removed as it apparently
+      can cause a reentrant (i.e. in one thread) deadlock,
+      perhaps when gc collects objects at the point of
+      iteration in order to gain more memory.  It is hoped
+      that "dictionary changed during iteration" will
+      be exceedingly rare as iteration methods internally
+      acquire the full list of objects in a single values()
+      call. Note 0.6.7 has a more conservative fix here
+      which still keeps the mutex in place.
+
+    .. change::
+        :tags: orm
+        :tickets: 2082
+
+      A tweak to the unit of work causes it to order
+      the flush along relationship() dependencies even if
+      the given objects don't have any inter-attribute
+      references in memory, which was the behavior in
+      0.5 and earlier, so a flush of Parent/Child with
+      only foreign key/primary key set will succeed.
+      This while still maintaining 0.6 and above's not
+      generating a ton of useless internal dependency
+      structures within the flush that don't correspond
+      to state actually within the current flush.
+
+    .. change::
+        :tags: orm
+        :tickets: 2069
+
+      Improvements to the error messages emitted when
+      querying against column-only entities in conjunction
+      with (typically incorrectly) using loader options,
+      where the parent entity is not fully present.
+
+    .. change::
+        :tags: orm
+        :tickets: 2098
+
+      Fixed bug in query.options() whereby a path
+      applied to a lazyload using string keys could
+      overlap a same named attribute on the wrong
+      entity.  Note 0.6.7 has a more conservative fix
+      to this.
+
+    .. change::
+        :tags: declarative
+        :tickets: 2091
+
+      Arguments in __mapper_args__ that aren't "hashable"
+      aren't mistaken for always-hashable, possibly-column
+      arguments.  (also in 0.6.7)
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Added a fully descriptive error message for the
+      case where Column is subclassed and _make_proxy()
+      fails to make a copy due to TypeError on the
+      constructor.   The method _constructor should
+      be implemented in this case.
+
+    .. change::
+        :tags: sql
+        :tickets: 2095
+
+      Added new event "column_reflect" for Table objects.
+      Receives the info dictionary about a Column before
+      the object is generated within reflection, and allows
+      modification to the dictionary for control over
+      most aspects of the resulting Column including
+      key, name, type, info dictionary.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      To help with the "column_reflect" event being used
+      with specific Table objects instead of all instances
+      of Table, listeners can be added to a Table object
+      inline with its construction using a new argument
+      "listeners", a list of tuples of the form
+      (<eventname>, <fn>), which are applied to the Table
+      before the reflection process begins.
+
+    .. change::
+        :tags: sql
+        :tickets: 2085
+
+      Added new generic function "next_value()", accepts
+      a Sequence object as its argument and renders the
+      appropriate "next value" generation string on the
+      target platform, if supported.  Also provides
+      ".next_value()" method on Sequence itself.
+
+    .. change::
+        :tags: sql
+        :tickets: 2084
+
+      func.next_value() or other SQL expression can
+      be embedded directly into an insert() construct,
+      and if implicit or explicit "returning" is used
+      in conjunction with a primary key column,
+      the newly generated value will be present in
+      result.inserted_primary_key.
+
+    .. change::
+        :tags: sql
+        :tickets: 2089
+
+      Added accessors to ResultProxy "returns_rows",
+      "is_insert" (also in 0.6.7)
+
+    .. change::
+        :tags: engine
+        :tickets: 2097
+
+      Fixed AssertionPool regression bug.
+
+    .. change::
+        :tags: engine
+        :tickets: 2060
+
+      Changed exception raised to ArgumentError when an
+      invalid dialect is specified.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2092
+
+      Added RESERVED_WORDS for postgresql dialect.
+      (also in 0.6.7)
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2073
+
+      Fixed the BIT type to allow a "length" parameter, "varying"
+      parameter.  Reflection also fixed. 
+      (also in 0.6.7)
+
+    .. change::
+        :tags: mssql
+        :tickets: 2071
+
+      Rewrote the query used to get the definition of a view,
+      typically when using the Inspector interface, to
+      use sys.sql_modules instead of the information schema,
+      thereby allowing views definitions longer than 4000
+      characters to be fully returned. 
+      (also in 0.6.7)
+
+    .. change::
+        :tags: firebird
+        :tickets: 2083
+
+      The "implicit_returning" flag on create_engine() is
+      honored if set to False.  (also in 0.6.7)
+
+    .. change::
+        :tags: informix
+        :tickets: 2092
+
+      Added RESERVED_WORDS informix dialect.
+      (also in 0.6.7)
+
+    .. change::
+        :tags: ext
+        :tickets: 2090
+
+      The horizontal_shard ShardedSession class accepts the common
+      Session argument "query_cls" as a constructor argument,
+      to enable further subclassing of ShardedQuery. (also in 0.6.7)
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      Updated the association, association proxy examples
+      to use declarative, added a new example
+      dict_of_sets_with_default.py, a "pushing the envelope"
+      example of association proxy.
+
+    .. change::
+        :tags: examples
+        :tickets: 2090
+
+      The Beaker caching example allows a "query_cls" argument
+      to the query_callable() function. 
+      (also in 0.6.7)
+
+.. changelog::
+    :version: 0.7.0b2
+    :released: Sat Feb 19 2011
+
+    .. change::
+        :tags: orm
+        :tickets: 2053
+
+      Fixed bug whereby Session.merge() would call the
+      load() event with one too few arguments.
+
+    .. change::
+        :tags: orm
+        :tickets: 2052
+
+      Added logic which prevents the generation of
+      events from a MapperExtension or SessionExtension
+      from generating do-nothing events for all the methods
+      not overridden.
+
+    .. change::
+        :tags: declarative
+        :tickets: 2058
+
+      Fixed regression whereby composite() with
+      Column objects placed inline would fail
+      to initialize.  The Column objects can now
+      be inline with the composite() or external
+      and pulled in via name or object ref.
+
+    .. change::
+        :tags: declarative
+        :tickets: 2061
+
+      Fix error message referencing old @classproperty
+      name to reference @declared_attr
+      (also in 0.6.7)
+
+    .. change::
+        :tags: declarative
+        :tickets: 1468
+
+      the dictionary at the end of the __table_args__
+      tuple is now optional.
+
+    .. change::
+        :tags: sql
+        :tickets: 2059
+
+      Renamed the EngineEvents event class to
+      ConnectionEvents.  As these classes are never
+      accessed directly by end-user code, this strictly
+      is a documentation change for end users.  Also
+      simplified how events get linked to engines
+      and connections internally.
+
+    .. change::
+        :tags: sql
+        :tickets: 2055
+
+      The Sequence() construct, when passed a MetaData()
+      object via its 'metadata' argument, will be
+      included in CREATE/DROP statements within
+      metadata.create_all() and metadata.drop_all(),
+      including "checkfirst" logic.
+
+    .. change::
+        :tags: sql
+        :tickets: 2064
+
+      The Column.references() method now returns True
+      if it has a foreign key referencing the
+      given column exactly, not just it's parent
+      table.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2065
+
+      Fixed regression from 0.6 where SMALLINT and
+      BIGINT types would both generate SERIAL
+      on an integer PK column, instead of
+      SMALLINT and BIGSERIAL
+
+    .. change::
+        :tags: ext
+        :tickets: 2054
+
+      Association proxy now has correct behavior for
+      any(), has(), and contains() when proxying
+      a many-to-one scalar attribute to a one-to-many
+      collection (i.e. the reverse of the 'typical'
+      association proxy use case)
+
+    .. change::
+        :tags: examples
+        :tickets: 
+
+      Beaker example now takes into account 'limit'
+      and 'offset', bind params within embedded
+      FROM clauses (like when you use union() or
+      from_self()) when generating a cache key.
+
+.. changelog::
+    :version: 0.7.0b1
+    :released: Sat Feb 12 2011
+
+    .. change::
+        :tags: 
+        :tickets: 
+
+      Detailed descriptions of each change below are
+      described at:
+      http://www.sqlalchemy.org/trac/wiki/07Migration
+
+    .. change::
+        :tags: general
+        :tickets: 1902
+
+      New event system, supercedes all extensions, listeners,
+      etc.
+
+    .. change::
+        :tags: general
+        :tickets: 1926
+
+      Logging enhancements
+
+    .. change::
+        :tags: general
+        :tickets: 1949
+
+      Setup no longer installs a Nose plugin
+
+    .. change::
+        :tags: general
+        :tickets: 
+
+      The "sqlalchemy.exceptions" alias in sys.modules
+      has been removed.   Base SQLA exceptions are
+      available via "from sqlalchemy import exc".
+      The "exceptions" alias for "exc" remains in
+      "sqlalchemy" for now, it's just not patched into
+      sys.modules.
+
+    .. change::
+        :tags: orm
+        :tickets: 1923
+
+      More succinct form of query.join(target, onclause)
+
+    .. change::
+        :tags: orm
+        :tickets: 1903
+
+      Hybrid Attributes, implements/supercedes synonym()
+
+    .. change::
+        :tags: orm
+        :tickets: 2008
+
+      Rewrite of composites
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Mutation Event Extension, supercedes "mutable=True"
+
+    .. change::
+        :tags: orm
+        :tickets: 1980
+
+      PickleType and ARRAY mutability turned off by default
+
+    .. change::
+        :tags: orm
+        :tickets: 1895
+
+      Simplified polymorphic_on assignment
+
+    .. change::
+        :tags: orm
+        :tickets: 1912
+
+      Flushing of Orphans that have no parent is allowed
+
+    .. change::
+        :tags: orm
+        :tickets: 2041
+
+      Adjusted flush accounting step to occur before
+      the commit in the case of autocommit=True.  This allows
+      autocommit=True to work appropriately with
+      expire_on_commit=True, and also allows post-flush session
+      hooks to operate in the same transactional context
+      as when autocommit=False.
+
+    .. change::
+        :tags: orm
+        :tickets: 1973
+
+      Warnings generated when collection members, scalar referents
+      not part of the flush
+
+    .. change::
+        :tags: orm
+        :tickets: 1876
+
+      Non-`Table`-derived constructs can be mapped
+
+    .. change::
+        :tags: orm
+        :tickets: 1942
+
+      Tuple label names in Query Improved
+
+    .. change::
+        :tags: orm
+        :tickets: 1892
+
+      Mapped column attributes reference the most specific
+      column first
+
+    .. change::
+        :tags: orm
+        :tickets: 1896
+
+      Mapping to joins with two or more same-named columns
+      requires explicit declaration
+
+    .. change::
+        :tags: orm
+        :tickets: 1875
+
+      Mapper requires that polymorphic_on column be present
+      in the mapped selectable
+
+    .. change::
+        :tags: orm
+        :tickets: 1966
+
+      compile_mappers() renamed configure_mappers(), simplified
+      configuration internals
+
+    .. change::
+        :tags: orm
+        :tickets: 2018
+
+      the aliased() function, if passed a SQL FromClause element
+      (i.e. not a mapped class), will return element.alias()
+      instead of raising an error on AliasedClass.
+
+    .. change::
+        :tags: orm
+        :tickets: 2027
+
+      Session.merge() will check the version id of the incoming
+      state against that of the database, assuming the mapping
+      uses version ids and incoming state has a version_id
+      assigned, and raise StaleDataError if they don't
+      match.
+
+    .. change::
+        :tags: orm
+        :tickets: 1996
+
+      Session.connection(), Session.execute() accept 'bind',
+      to allow execute/connection operations to participate
+      in the open transaction of an engine explicitly.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      Query.join(), Query.outerjoin(), eagerload(),
+      eagerload_all(), others no longer allow lists
+      of attributes as arguments (i.e. option([x, y, z])
+      form, deprecated since 0.5)
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      ScopedSession.mapper is removed (deprecated since 0.5).
+
+    .. change::
+        :tags: orm
+        :tickets: 2031
+
+      Horizontal shard query places 'shard_id' in
+      context.attributes where it's accessible by the
+      "load()" event.
+
+    .. change::
+        :tags: orm
+        :tickets: 2032
+
+      A single contains_eager() call across
+      multiple entities will indicate all collections
+      along that path should load, instead of requiring
+      distinct contains_eager() calls for each endpoint
+      (which was never correctly documented).
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      The "name" field used in orm.aliased() now renders
+      in the resulting SQL statement.
+
+    .. change::
+        :tags: orm
+        :tickets: 1473
+
+      Session weak_instance_dict=False is deprecated.
+
+    .. change::
+        :tags: orm
+        :tickets: 2046
+
+      An exception is raised in the unusual case that an
+      append or similar event on a collection occurs after
+      the parent object has been dereferenced, which
+      prevents the parent from being marked as "dirty"
+      in the session.  Was a warning in 0.6.6.
+
+    .. change::
+        :tags: orm
+        :tickets: 1069
+
+      Query.distinct() now accepts column expressions
+      as *args, interpreted by the Postgresql dialect
+      as DISTINCT ON (<expr>).
+
+    .. change::
+        :tags: orm
+        :tickets: 2049
+
+      Additional tuning to "many-to-one" relationship
+      loads during a flush().   A change in version 0.6.6
+      ([ticket:2002]) required that more "unnecessary" m2o
+      loads during a flush could occur.   Extra loading modes have
+      been added so that the SQL emitted in this
+      specific use case is trimmed back, while still
+      retrieving the information the flush needs in order
+      to not miss anything.
+
+    .. change::
+        :tags: orm
+        :tickets: 
+
+      the value of "passive" as passed to
+      attributes.get_history() should be one of the
+      constants defined in the attributes package.  Sending
+      True or False is deprecated.
+
+    .. change::
+        :tags: orm
+        :tickets: 2030
+
+      Added a `name` argument to `Query.subquery()`, to allow
+      a fixed name to be assigned to the alias object. (also in 0.6.7)
+
+    .. change::
+        :tags: orm
+        :tickets: 2019
+
+      A warning is emitted when a joined-table inheriting mapper
+      has no primary keys on the locally mapped table
+      (but has pks on the superclass table). 
+      (also in 0.6.7)
+
+    .. change::
+        :tags: orm
+        :tickets: 2038
+
+      Fixed bug where "middle" class in a polymorphic hierarchy
+      would have no 'polymorphic_on' column if it didn't also
+      specify a 'polymorphic_identity', leading to strange
+      errors upon refresh, wrong class loaded when querying
+      from that target. Also emits the correct WHERE criterion
+      when using single table inheritance.
+      (also in 0.6.7)
+
+    .. change::
+        :tags: orm
+        :tickets: 1995
+
+      Fixed bug where a column with a SQL or server side default
+      that was excluded from a mapping with include_properties
+      or exclude_properties would result in UnmappedColumnError. (also in 0.6.7)
+
+    .. change::
+        :tags: orm
+        :tickets: 2046
+
+      A warning is emitted in the unusual case that an
+      append or similar event on a collection occurs after
+      the parent object has been dereferenced, which
+      prevents the parent from being marked as "dirty"
+      in the session.  This will be an exception in 0.7. (also in 0.6.7)
+
+    .. change::
+        :tags: declarative
+        :tickets: 2050
+
+      Added an explicit check for the case that the name
+      'metadata' is used for a column attribute on a
+      declarative class. (also in 0.6.7)
+
+    .. change::
+        :tags: sql
+        :tickets: 1844
+
+      Added over() function, method to FunctionElement
+      classes, produces the _Over() construct which
+      in turn generates "window functions", i.e.
+      "<window function> OVER (PARTITION BY <partition by>,
+      ORDER BY <order by>)".
+
+    .. change::
+        :tags: sql
+        :tickets: 805
+
+      LIMIT/OFFSET clauses now use bind parameters
+
+    .. change::
+        :tags: sql
+        :tickets: 1069
+
+      select.distinct() now accepts column expressions
+      as *args, interpreted by the Postgresql dialect
+      as DISTINCT ON (<expr>).  Note this was already
+      available via passing a list to the `distinct`
+      keyword argument to select().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      select.prefix_with() accepts multiple expressions
+      (i.e. *expr), 'prefix' keyword argument to select()
+      accepts a list or tuple.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Passing a string to the `distinct` keyword argument
+      of `select()` for the purpose of emitting special
+      MySQL keywords (DISTINCTROW etc.) is deprecated -
+      use `prefix_with()` for this.
+
+    .. change::
+        :tags: sql
+        :tickets: 2006, 2005
+
+      TypeDecorator works with primary key columns
+
+    .. change::
+        :tags: sql
+        :tickets: 1897
+
+      DDL() constructs now escape percent signs
+
+    .. change::
+        :tags: sql
+        :tickets: 1917, 1893
+
+      Table.c / MetaData.tables refined a bit, don't allow direct
+      mutation
+
+    .. change::
+        :tags: sql
+        :tickets: 1950
+
+      Callables passed to `bindparam()` don't get evaluated
+
+    .. change::
+        :tags: sql
+        :tickets: 1870
+
+      types.type_map is now private, types._type_map
+
+    .. change::
+        :tags: sql
+        :tickets: 1982
+
+      Non-public Pool methods underscored
+
+    .. change::
+        :tags: sql
+        :tickets: 723
+
+      Added NULLS FIRST and NULLS LAST support. It's implemented
+      as an extension to the asc() and desc() operators, called
+      nullsfirst() and nullslast().
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      The Index() construct can be created inline with a Table
+      definition, using strings as column names, as an alternative
+      to the creation of the index outside of the Table.
+
+    .. change::
+        :tags: sql
+        :tickets: 2001
+
+      execution_options() on Connection accepts
+      "isolation_level" argument, sets transaction isolation
+      level for that connection only until returned to the
+      connection pool, for thsoe backends which support it
+      (SQLite, Postgresql)
+
+    .. change::
+        :tags: sql
+        :tickets: 2005
+
+      A TypeDecorator of Integer can be used with a primary key
+      column, and the "autoincrement" feature of various dialects
+      as well as the "sqlite_autoincrement" flag will honor
+      the underlying database type as being Integer-based.
+
+    .. change::
+        :tags: sql
+        :tickets: 2020, 2021
+
+      Established consistency when server_default is present
+      on an Integer PK column.  SQLA doesn't pre-fetch these,
+      nor do they come back in cursor.lastrowid (DBAPI).
+      Ensured all backends consistently return None
+      in result.inserted_primary_key for these. Regarding
+      reflection for this case, reflection of an int PK col
+      with a server_default sets the "autoincrement" flag to False,
+      except in the case of a PG SERIAL col where we detected a
+      sequence default.
+
+    .. change::
+        :tags: sql
+        :tickets: 2006
+
+      Result-row processors are applied to pre-executed SQL
+      defaults, as well as cursor.lastrowid, when determining
+      the contents of result.inserted_primary_key.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      Bind parameters present in the "columns clause" of a select
+      are now auto-labeled like other "anonymous" clauses,
+      which among other things allows their "type" to be meaningful
+      when the row is fetched, as in result row processors.
+
+    .. change::
+        :tags: sql
+        :tickets: 
+
+      TypeDecorator is present in the "sqlalchemy" import space.
+
+    .. change::
+        :tags: sql
+        :tickets: 2015
+
+      Non-DBAPI errors which occur in the scope of an `execute()`
+      call are now wrapped in sqlalchemy.exc.StatementError,
+      and the text of the SQL statement and repr() of params
+      is included.  This makes it easier to identify statement
+      executions which fail before the DBAPI becomes
+      involved.
+
+    .. change::
+        :tags: sql
+        :tickets: 2048
+
+      The concept of associating a ".bind" directly with a
+      ClauseElement has been explicitly moved to Executable,
+      i.e. the mixin that describes ClauseElements which represent
+      engine-executable constructs.  This change is an improvement
+      to internal organization and is unlikely to affect any
+      real-world usage.
+
+    .. change::
+        :tags: sql
+        :tickets: 2028
+
+      Column.copy(), as used in table.tometadata(), copies the
+      'doc' attribute.  (also in 0.6.7)
+
+    .. change::
+        :tags: sql
+        :tickets: 2023
+
+      Added some defs to the resultproxy.c extension so that
+      the extension compiles and runs on Python 2.4. (also in 0.6.7)
+
+    .. change::
+        :tags: sql
+        :tickets: 2042
+
+      The compiler extension now supports overriding the default
+      compilation of expression._BindParamClause including that
+      the auto-generated binds within the VALUES/SET clause
+      of an insert()/update() statement will also use the new
+      compilation rules. (also in 0.6.7)
+
+    .. change::
+        :tags: sql
+        :tickets: 1921
+
+      SQLite dialect now uses `NullPool` for file-based databases
+
+    .. change::
+        :tags: sql
+        :tickets: 2036
+
+      The path given as the location of a sqlite database is now
+      normalized via os.path.abspath(), so that directory changes
+      within the process don't affect the ultimate location
+      of a relative file path.
+
+    .. change::
+        :tags: postgresql
+        :tickets: 1083
+
+      When explicit sequence execution derives the name
+      of the auto-generated sequence of a SERIAL column,
+      which currently only occurs if implicit_returning=False,
+      now accommodates if the table + column name is greater
+      than 63 characters using the same logic Postgresql uses. (also in 0.6.7)
+
+    .. change::
+        :tags: postgresql
+        :tickets: 2044
+
+      Added an additional libpq message to the list of "disconnect"
+      exceptions, "could not receive data from server" (also in 0.6.7)
+
+    .. change::
+        :tags: mssql
+        :tickets: 1833
+
+      the String/Unicode types, and their counterparts VARCHAR/
+      NVARCHAR, emit "max" as the length when no length is
+      specified, so that the default length, normally '1'
+      as per SQL server documentation, is instead
+      'unbounded'.  This also occurs for the VARBINARY type..
+      
+      This behavior makes these types more closely compatible
+      with Postgresql's VARCHAR type which is similarly unbounded
+      when no length is specified.
+
+    .. change::
+        :tags: mysql
+        :tickets: 1991
+
+      New DBAPI support for pymysql, a pure Python port
+      of MySQL-python.
+
+    .. change::
+        :tags: mysql
+        :tickets: 2047
+
+      oursql dialect accepts the same "ssl" arguments in
+      create_engine() as that of MySQLdb. 
+      (also in 0.6.7)
+
+    .. change::
+        :tags: firebird
+        :tickets: 1885
+
+      Some adjustments so that Interbase is supported as well.
+      FB/Interbase version idents are parsed into a structure
+      such as (8, 1, 1, 'interbase') or (2, 1, 588, 'firebird')
+      so they can be distinguished.
diff --git a/doc/build/changelog/index.rst b/doc/build/changelog/index.rst
new file mode 100644 (file)
index 0000000..7460214
--- /dev/null
@@ -0,0 +1,34 @@
+.. _changelog_toplevel:
+
+Changes and Migration
+=====================
+
+Migration Guides
+----------------
+
+SQLAlchemy migration guides are now available within the main documentation.
+
+.. toctree::
+       :maxdepth: 1
+
+       migration_07
+       migration_06
+       migration_05
+       migration_04
+
+Change logs
+-----------
+
+SQLAlchemy changelogs are now available within the main documentation.
+
+.. toctree::
+   :maxdepth: 2
+
+   changelog_07
+   changelog_06
+   changelog_05
+   changelog_04
+   changelog_03
+   changelog_02
+   changelog_01
+
diff --git a/doc/build/changelog/migration_04.rst b/doc/build/changelog/migration_04.rst
new file mode 100644 (file)
index 0000000..236bfc3
--- /dev/null
@@ -0,0 +1,868 @@
+=============================
+What's new in SQLAlchemy 0.4?
+=============================
+
+.. admonition:: About this Document
+
+    This document describes changes between SQLAlchemy version 0.3,
+    last released October 14, 2007, and SQLAlchemy version 0.4,
+    last released October 12, 2008.
+
+    Document date:  March 21, 2008
+
+First Things First
+==================
+
+If you're using any ORM features, make sure you import from
+``sqlalchemy.orm``:
+
+::
+
+    from sqlalchemy import *
+    from sqlalchemy.orm import *
+
+Secondly, anywhere you used to say ``engine=``,
+``connectable=``, ``bind_to=``, ``something.engine``,
+``metadata.connect()``, use ``bind``:
+
+::
+
+    myengine = create_engine('sqlite://')
+
+    meta = MetaData(myengine)
+
+    meta2 = MetaData()
+    meta2.bind = myengine
+
+    session = create_session(bind=myengine)
+
+    statement = select([table], bind=myengine)
+
+Got those ?  Good!  You're now (95%) 0.4 compatible.  If
+you're using 0.3.10, you can make these changes immediately;
+they'll work there too.
+
+Module Imports
+==============
+
+In 0.3, "``from sqlachemy import *``" would import all of
+sqlachemy's sub-modules into your namespace. Version 0.4 no
+longer imports sub-modules into the namespace. This may mean
+you need to add extra imports into your code.
+
+In 0.3, this code worked:
+
+::
+
+    from sqlalchemy import *
+
+    class UTCDateTime(types.TypeDecorator):
+        pass
+
+In 0.4, one must do:
+
+::
+
+    from sqlalchemy import *
+    from sqlalchemy import types
+
+    class UTCDateTime(types.TypeDecorator):
+        pass
+
+Object Relational Mapping
+=========================
+
+Querying
+--------
+
+New Query API
+^^^^^^^^^^^^^
+
+Query is standardized on the generative interface (old
+interface is still there, just deprecated).   While most of
+the generative interface is available in 0.3, the 0.4 Query
+has the inner guts to match the generative outside, and has
+a lot more tricks.  All result narrowing is via ``filter()``
+and ``filter_by()``, limiting/offset is either through array
+slices or ``limit()``/``offset()``, joining is via
+``join()`` and ``outerjoin()`` (or more manually, through
+``select_from()`` as well as manually-formed criteria).
+
+To avoid deprecation warnings, you must make some changes to
+your 03 code
+
+User.query.get_by( \**kwargs )
+
+::
+
+    User.query.filter_by(**kwargs).first()
+
+User.query.select_by( \**kwargs )
+
+::
+
+    User.query.filter_by(**kwargs).all()
+
+User.query.select()
+
+::
+
+    User.query.filter(xxx).all()
+
+New Property-Based Expression Constructs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+By far the most palpable difference within the ORM is that
+you can now construct your query criterion using class-based
+attributes directly.  The ".c." prefix is no longer needed
+when working with mapped classes:
+
+::
+
+    session.query(User).filter(and_(User.name == 'fred', User.id > 17))
+
+While simple column-based comparisons are no big deal, the
+class attributes have some new "higher level" constructs
+available, including what was previously only available in
+``filter_by()``:
+
+::
+
+    # comparison of scalar relations to an instance
+    filter(Address.user == user)
+
+    # return all users who contain a particular address
+    filter(User.addresses.contains(address))
+
+    # return all users who *dont* contain the address
+    filter(~User.address.contains(address))
+
+    # return all users who contain a particular address with
+    # the email_address like '%foo%'
+    filter(User.addresses.any(Address.email_address.like('%foo%')))
+
+    # same, email address equals 'foo@bar.com'.  can fall back to keyword
+    # args for simple comparisons
+    filter(User.addresses.any(email_address = 'foo@bar.com'))
+
+    # return all Addresses whose user attribute has the username 'ed'
+    filter(Address.user.has(name='ed'))
+
+    # return all Addresses whose user attribute has the username 'ed'
+    # and an id > 5 (mixing clauses with kwargs)
+    filter(Address.user.has(User.id > 5, name='ed'))
+
+The ``Column`` collection remains available on mapped
+classes in the ``.c`` attribute.  Note that property-based
+expressions are only available with mapped properties of
+mapped classes.  ``.c`` is still used to access columns in
+regular tables and selectable objects produced from SQL
+Expressions.
+
+Automatic Join Aliasing
+^^^^^^^^^^^^^^^^^^^^^^^
+
+We've had join() and outerjoin() for a while now:
+
+::
+
+    session.query(Order).join('items')...
+
+Now you can alias them:
+
+::
+
+    session.query(Order).join('items', aliased=True).
+       filter(Item.name='item 1').join('items', aliased=True).filter(Item.name=='item 3')
+
+The above will create two joins from orders->items using
+aliases.  the ``filter()`` call subsequent to each will
+adjust its table criterion to that of the alias.  To get at
+the ``Item`` objects, use ``add_entity()`` and target each
+join with an ``id``:
+
+::
+
+    session.query(Order).join('items', id='j1', aliased=True).
+    filter(Item.name == 'item 1').join('items', aliased=True, id='j2').
+    filter(Item.name == 'item 3').add_entity(Item, id='j1').add_entity(Item, id='j2')
+
+Returns tuples in the form: ``(Order, Item, Item)``.
+
+Self-referential Queries
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+So query.join() can make aliases now.  What does that give
+us ?  Self-referential queries !   Joins can be done without
+any ``Alias`` objects:
+
+::
+
+    # standard self-referential TreeNode mapper with backref
+    mapper(TreeNode, tree_nodes, properties={
+        'children':relation(TreeNode, backref=backref('parent', remote_side=tree_nodes.id))
+    })
+
+    # query for node with child containing "bar" two levels deep
+    session.query(TreeNode).join(["children", "children"], aliased=True).filter_by(name='bar')
+
+To add criterion for each table along the way in an aliased
+join, you can use ``from_joinpoint`` to keep joining against
+the same line of aliases:
+
+::
+
+    # search for the treenode along the path "n1/n12/n122"
+
+    # first find a Node with name="n122"
+    q = sess.query(Node).filter_by(name='n122')
+
+    # then join to parent with "n12"
+    q = q.join('parent', aliased=True).filter_by(name='n12')
+
+    # join again to the next parent with 'n1'.  use 'from_joinpoint'
+    # so we join from the previous point, instead of joining off the
+    # root table
+    q = q.join('parent', aliased=True, from_joinpoint=True).filter_by(name='n1')
+
+    node = q.first()
+
+``query.populate_existing()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The eager version of ``query.load()`` (or
+``session.refresh()``).  Every instance loaded from the
+query, including all eagerly loaded items, get refreshed
+immediately if already present in the session:
+
+::
+
+    session.query(Blah).populate_existing().all()
+
+Relations
+---------
+
+SQL Clauses Embedded in Updates/Inserts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For inline execution of SQL clauses, embedded right in the
+UPDATE or INSERT, during a ``flush()``:
+
+::
+
+
+    myobject.foo = mytable.c.value + 1
+
+    user.pwhash = func.md5(password)
+
+    order.hash = text("select hash from hashing_table")
+
+The column-attribute is set up with a deferred loader after
+the operation, so that it issues the SQL to load the new
+value when you next access.
+
+Self-referential and Cyclical Eager Loading
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Since our alias-fu has improved, ``relation()`` can join
+along the same table \*any number of times*; you tell it how
+deep you want to go.  Lets show the self-referential
+``TreeNode`` more clearly:
+
+::
+
+    nodes = Table('nodes', metadata,
+         Column('id', Integer, primary_key=True),
+         Column('parent_id', Integer, ForeignKey('nodes.id')),
+         Column('name', String(30)))
+
+    class TreeNode(object):
+        pass
+
+    mapper(TreeNode, nodes, properties={
+        'children':relation(TreeNode, lazy=False, join_depth=3)
+    })
+
+So what happens when we say:
+
+::
+
+    create_session().query(TreeNode).all()
+
+?  A join along aliases, three levels deep off the parent:
+
+::
+
+    SELECT
+    nodes_3.id AS nodes_3_id, nodes_3.parent_id AS nodes_3_parent_id, nodes_3.name AS nodes_3_name,
+    nodes_2.id AS nodes_2_id, nodes_2.parent_id AS nodes_2_parent_id, nodes_2.name AS nodes_2_name,
+    nodes_1.id AS nodes_1_id, nodes_1.parent_id AS nodes_1_parent_id, nodes_1.name AS nodes_1_name,
+    nodes.id AS nodes_id, nodes.parent_id AS nodes_parent_id, nodes.name AS nodes_name
+    FROM nodes LEFT OUTER JOIN nodes AS nodes_1 ON nodes.id = nodes_1.parent_id
+    LEFT OUTER JOIN nodes AS nodes_2 ON nodes_1.id = nodes_2.parent_id
+    LEFT OUTER JOIN nodes AS nodes_3 ON nodes_2.id = nodes_3.parent_id
+    ORDER BY nodes.oid, nodes_1.oid, nodes_2.oid, nodes_3.oid
+
+Notice the nice clean alias names too.  The joining doesn't
+care if it's against the same immediate table or some other
+object which then cycles back to the beginining.  Any kind
+of chain of eager loads can cycle back onto itself when
+``join_depth`` is specified.  When not present, eager
+loading automatically stops when it hits a cycle.
+
+Composite Types
+^^^^^^^^^^^^^^^
+
+This is one from the Hibernate camp.  Composite Types let
+you define a custom datatype that is composed of more than
+one column (or one column, if you wanted).   Lets define a
+new type, ``Point``.  Stores an x/y coordinate:
+
+::
+
+    class Point(object):
+        def __init__(self, x, y):
+            self.x = x
+            self.y = y
+        def __composite_values__(self):
+            return self.x, self.y
+        def __eq__(self, other):
+            return other.x == self.x and other.y == self.y
+        def __ne__(self, other):
+            return not self.__eq__(other)
+
+The way the ``Point`` object is defined is specific to a
+custom type; constructor takes a list of arguments, and the
+``__composite_values__()`` method produces a sequence of
+those arguments.  The order will match up to our mapper, as
+we'll see in a moment.
+
+Let's create a table of vertices storing two points per row:
+
+::
+
+    vertices = Table('vertices', metadata,
+        Column('id', Integer, primary_key=True),
+        Column('x1', Integer),
+        Column('y1', Integer),
+        Column('x2', Integer),
+        Column('y2', Integer),
+        )
+
+Then, map it !  We'll create a ``Vertex`` object which
+stores two ``Point`` objects:
+
+::
+
+    class Vertex(object):
+        def __init__(self, start, end):
+            self.start = start
+            self.end = end
+
+    mapper(Vertex, vertices, properties={
+        'start':composite(Point, vertices.c.x1, vertices.c.y1),
+        'end':composite(Point, vertices.c.x2, vertices.c.y2)
+    })
+
+Once you've set up your composite type, it's usable just
+like any other type:
+
+::
+
+
+    v = Vertex(Point(3, 4), Point(26,15))
+    session.save(v)
+    session.flush()
+
+    # works in queries too
+    q = session.query(Vertex).filter(Vertex.start == Point(3, 4))
+
+If you'd like to define the way the mapped attributes
+generate SQL clauses when used in expressions, create your
+own ``sqlalchemy.orm.PropComparator`` subclass, defining any
+of the common operators (like ``__eq__()``, ``__le__()``,
+etc.), and send it in to ``composite()``.  Composite types
+work as primary keys too, and are usable in ``query.get()``:
+
+::
+
+    # a Document class which uses a composite Version
+    # object as primary key
+    document = query.get(Version(1, 'a'))
+
+``dynamic_loader()`` relations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A ``relation()`` that returns a live ``Query`` object for
+all read operations.  Write operations are limited to just
+``append()`` and ``remove()``, changes to the collection are
+not visible until the session is flushed.  This feature is
+particularly handy with an "autoflushing" session which will
+flush before each query.
+
+::
+
+    mapper(Foo, foo_table, properties={
+        'bars':dynamic_loader(Bar, backref='foo', <other relation() opts>)
+    })
+
+    session = create_session(autoflush=True)
+    foo = session.query(Foo).first()
+
+    foo.bars.append(Bar(name='lala'))
+
+    for bar in foo.bars.filter(Bar.name=='lala'):
+        print bar
+
+    session.commit()
+
+New Options: ``undefer_group()``, ``eagerload_all()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A couple of query options which are handy.
+``undefer_group()`` marks a whole group of "deferred"
+columns as undeferred:
+
+::
+
+    mapper(Class, table, properties={
+        'foo' : deferred(table.c.foo, group='group1'),
+        'bar' : deferred(table.c.bar, group='group1'),
+        'bat' : deferred(table.c.bat, group='group1'),
+    )
+
+    session.query(Class).options(undefer_group('group1')).filter(...).all()
+
+and ``eagerload_all()`` sets a chain of attributes to be
+eager in one pass:
+
+::
+
+    mapper(Foo, foo_table, properties={
+       'bar':relation(Bar)
+    })
+    mapper(Bar, bar_table, properties={
+       'bat':relation(Bat)
+    })
+    mapper(Bat, bat_table)
+
+    # eager load bar and bat
+    session.query(Foo).options(eagerload_all('bar.bat')).filter(...).all()
+
+New Collection API
+^^^^^^^^^^^^^^^^^^
+
+Collections are no longer proxied by an
+{{{InstrumentedList}}} proxy, and access to members, methods
+and attributes is direct.   Decorators now intercept objects
+entering and leaving the collection, and it is now possible
+to easily write a custom collection class that manages its
+own membership.  Flexible decorators also replace the named
+method interface of custom collections in 0.3, allowing any
+class to be easily adapted to use as a collection container.
+
+Dictionary-based collections are now much easier to use and
+fully ``dict``-like.  Changing ``__iter__`` is no longer
+needed for ``dict``s, and new built-in ``dict`` types cover
+many needs:
+
+::
+
+    # use a dictionary relation keyed by a column
+    relation(Item, collection_class=column_mapped_collection(items.c.keyword))
+    # or named attribute
+    relation(Item, collection_class=attribute_mapped_collection('keyword'))
+    # or any function you like
+    relation(Item, collection_class=mapped_collection(lambda entity: entity.a + entity.b))
+
+Existing 0.3 ``dict``-like and freeform object derived
+collection classes will need to be updated for the new API.
+In most cases this is simply a matter of adding a couple
+decorators to the class definition.
+
+Mapped Relations from External Tables/Subqueries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This feature quietly appeared in 0.3 but has been improved
+in 0.4 thanks to better ability to convert subqueries
+against a table into subqueries against an alias of that
+table; this is key for eager loading, aliased joins in
+queries, etc.  It reduces the need to create mappers against
+select statements when you just need to add some extra
+columns or subqueries:
+
+::
+
+    mapper(User, users, properties={
+           'fullname': column_property((users.c.firstname + users.c.lastname).label('fullname')),
+           'numposts': column_property(
+                select([func.count(1)], users.c.id==posts.c.user_id).correlate(users).label('posts')
+           )
+        })
+
+a typical query looks like:
+
+::
+
+    SELECT (SELECT count(1) FROM posts WHERE users.id = posts.user_id) AS count,
+    users.firstname || users.lastname AS fullname,
+    users.id AS users_id, users.firstname AS users_firstname, users.lastname AS users_lastname
+    FROM users ORDER BY users.oid
+
+Horizontal Scaling (Sharding) API
+---------------------------------
+
+[browser:/sqlalchemy/trunk/examples/sharding/attribute_shard
+.py]
+
+Sessions
+--------
+
+New Session Create Paradigm; SessionContext, assignmapper Deprecated
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+That's right, the whole shebang is being replaced with two
+configurational functions.  Using both will produce the most
+0.1-ish feel we've had since 0.1 (i.e., the least amount of
+typing).
+
+Configure your own ``Session`` class right where you define
+your ``engine`` (or anywhere):
+
+::
+
+    from sqlalchemy import create_engine
+    from sqlalchemy.orm import sessionmaker
+
+    engine = create_engine('myengine://')
+    Session = sessionmaker(bind=engine, autoflush=True, transactional=True)
+
+    # use the new Session() freely
+    sess = Session()
+    sess.save(someobject)
+    sess.flush()
+
+
+If you need to post-configure your Session, say with an
+engine, add it later with ``configure()``:
+
+::
+
+    Session.configure(bind=create_engine(...))
+
+All the behaviors of ``SessionContext`` and the ``query``
+and ``__init__`` methods of ``assignmapper`` are moved into
+the new ``scoped_session()`` function, which is compatible
+with both ``sessionmaker`` as well as ``create_session()``:
+
+::
+
+    from sqlalchemy.orm import scoped_session, sessionmaker
+
+    Session = scoped_session(sessionmaker(autoflush=True, transactional=True))
+    Session.configure(bind=engine)
+
+    u = User(name='wendy')
+
+    sess = Session()
+    sess.save(u)
+    sess.commit()
+
+    # Session constructor is thread-locally scoped.  Everyone gets the same
+    # Session in the thread when scope="thread".
+    sess2 = Session()
+    assert sess is sess2
+
+
+When using a thread-local ``Session``, the returned class
+has all of ``Session's`` interface implemented as
+classmethods, and "assignmapper"'s functionality is
+available using the ``mapper`` classmethod.  Just like the
+old ``objectstore`` days....
+
+::
+
+
+    # "assignmapper"-like functionality available via ScopedSession.mapper
+    Session.mapper(User, users_table)
+
+    u = User(name='wendy')
+
+    Session.commit()
+
+
+Sessions are again Weak Referencing By Default
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The weak_identity_map flag is now set to ``True`` by default
+on Session.  Instances which are externally deferenced and
+fall out of scope are removed from the session
+automatically.   However, items which have "dirty" changes
+present will remain strongly referenced until those changes
+are flushed at which case the object reverts to being weakly
+referenced (this works for 'mutable' types, like picklable
+attributes, as well).  Setting weak_identity_map to
+``False`` restores the old strong-referencing behavior for
+those of you using the session like a cache.
+
+Auto-Transactional Sessions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As you might have noticed above, we are calling ``commit()``
+on ``Session``.  The flag ``transactional=True`` means the
+``Session`` is always in a transaction, ``commit()``
+persists permanently.
+
+Auto-Flushing Sessions
+^^^^^^^^^^^^^^^^^^^^^^
+
+Also, ``autoflush=True`` means the ``Session`` will
+``flush()`` before each ``query`` as well as when you call
+``flush()`` or ``commit()``.  So now this will work:
+
+::
+
+    Session = sessionmaker(bind=engine, autoflush=True, transactional=True)
+
+    u = User(name='wendy')
+
+    sess = Session()
+    sess.save(u)
+
+    # wendy is flushed, comes right back from a query
+    wendy = sess.query(User).filter_by(name='wendy').one()
+
+Transactional methods moved onto sessions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``commit()`` and ``rollback()``, as well as ``begin()`` are
+now directly on ``Session``.  No more need to use
+``SessionTransaction`` for anything (it remains in the
+background).
+
+::
+
+    Session = sessionmaker(autoflush=True, transactional=False)
+
+    sess = Session()
+    sess.begin()
+
+    # use the session
+
+    sess.commit() # commit transaction
+
+Sharing a ``Session`` with an enclosing engine-level (i.e.
+non-ORM) transaction is easy:
+
+::
+
+    Session = sessionmaker(autoflush=True, transactional=False)
+
+    conn = engine.connect()
+    trans = conn.begin()
+    sess = Session(bind=conn)
+
+    # ... session is transactional
+
+    # commit the outermost transaction
+    trans.commit()
+
+Nested Session Transactions with SAVEPOINT
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Available at the Engine and ORM level.  ORM docs so far:
+
+http://www.sqlalchemy.org/docs/04/session.html#unitofwork_ma
+naging
+
+Two-Phase Commit Sessions
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Available at the Engine and ORM level.  ORM docs so far:
+
+http://www.sqlalchemy.org/docs/04/session.html#unitofwork_ma
+naging
+
+Inheritance
+-----------
+
+Polymorphic Inheritance with No Joins or Unions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+New docs for inheritance:  http://www.sqlalchemy.org/docs/04
+/mappers.html#advdatamapping_mapper_inheritance_joined
+
+Better Polymorphic Behavior with ``get()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All classes within a joined-table inheritance hierarchy get
+an ``_instance_key`` using the base class, i.e.
+``(BaseClass, (1, ), None)``.  That way when you call
+``get()`` a ``Query`` against the base class, it can locate
+subclass instances in the current identity map without
+querying the database.
+
+Types
+-----
+
+Custom Subclasses of ``sqlalchemy.types.TypeDecorator``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There is a `New API <http://www.sqlalchemy.org/docs/04/types
+.html#types_custom>`_ for subclassing a TypeDecorator.
+Using the 0.3 API causes compilation errors in some cases.
+
+SQL Expressions
+===============
+
+All New, Deterministic Label/Alias Generation
+---------------------------------------------
+
+All the "anonymous" labels and aliases use a simple
+<name>_<number> format now.  SQL is much easier to read and
+is compatible with plan optimizer caches.  Just check out
+some of the examples in the tutorials:
+http://www.sqlalchemy.org/docs/04/ormtutorial.html
+http://www.sqlalchemy.org/docs/04/sqlexpression.html
+
+Generative select() Constructs
+------------------------------
+
+This is definitely the way to go with ``select()``.  See htt
+p://www.sqlalchemy.org/docs/04/sqlexpression.html#sql_transf
+orm .
+
+New Operator System
+-------------------
+
+SQL operators and more or less every SQL keyword there is
+are now abstracted into the compiler layer.  They now act
+intelligently and are type/backend aware, see: http://www.sq
+lalchemy.org/docs/04/sqlexpression.html#sql_operators
+
+All ``type`` Keyword Arguments Renamed to ``type_``
+---------------------------------------------------
+
+Just like it says:
+
+::
+
+       b = bindparam('foo', type_=String)
+
+in_ Function Changed to Accept Sequence or Selectable
+-----------------------------------------------------
+
+The in_ function now takes a sequence of values or a
+selectable as its sole argument. The previous API of passing
+in values as positional arguments still works, but is now
+deprecated. This means that
+
+::
+
+    my_table.select(my_table.c.id.in_(1,2,3)
+    my_table.select(my_table.c.id.in_(*listOfIds)
+
+should be changed to
+
+::
+
+    my_table.select(my_table.c.id.in_([1,2,3])
+    my_table.select(my_table.c.id.in_(listOfIds)
+
+Schema and Reflection
+=====================
+
+``MetaData``, ``BoundMetaData``, ``DynamicMetaData``...
+-------------------------------------------------------
+
+In the 0.3.x series, ``BoundMetaData`` and
+``DynamicMetaData`` were deprecated in favor of ``MetaData``
+and ``ThreadLocalMetaData``.  The older names have been
+removed in 0.4.  Updating is simple:
+
+::
+
+    +-------------------------------------+-------------------------+
+    |If You Had                           | Now Use                 |
+    +=====================================+=========================+
+    | ``MetaData``                        | ``MetaData``            |
+    +-------------------------------------+-------------------------+
+    | ``BoundMetaData``                   | ``MetaData``            |
+    +-------------------------------------+-------------------------+
+    | ``DynamicMetaData`` (with one       | ``MetaData``            |
+    | engine or threadlocal=False)        |                         |
+    +-------------------------------------+-------------------------+
+    | ``DynamicMetaData``                 | ``ThreadLocalMetaData`` |
+    | (with different engines per thread) |                         |
+    +-------------------------------------+-------------------------+
+
+The seldom-used ``name`` parameter to ``MetaData`` types has
+been removed.  The ``ThreadLocalMetaData`` constructor now
+takes no arguments.  Both types can now be bound to an
+``Engine`` or a single ``Connection``.
+
+One Step Multi-Table Reflection
+-------------------------------
+
+You can now load table definitions and automatically create
+``Table`` objects from an entire database or schema in one
+pass:
+
+::
+
+    >>> metadata = MetaData(myengine, reflect=True)
+    >>> metadata.tables.keys()
+    ['table_a', 'table_b', 'table_c', '...']
+
+``MetaData`` also gains a ``.reflect()`` method enabling
+finer control over the loading process, including
+specification of a subset of available tables to load.
+
+SQL Execution
+=============
+
+``engine``, ``connectable``, and ``bind_to`` are all now ``bind``
+-----------------------------------------------------------------
+
+``Transactions``, ``NestedTransactions`` and ``TwoPhaseTransactions``
+---------------------------------------------------------------------
+
+Connection Pool Events
+----------------------
+
+The connection pool now fires events when new DB-API
+connections are created, checked out and checked back into
+the pool.   You can use these to execute session-scoped SQL
+setup statements on fresh connections, for example.
+
+Oracle Engine Fixed
+-------------------
+
+In 0.3.11, there were bugs in the Oracle Engine on how
+Primary Keys are handled.  These bugs could cause programs
+that worked fine with other engines, such as sqlite, to fail
+when using the Oracle Engine.  In 0.4, the Oracle Engine has
+been reworked, fixing these Primary Key problems.
+
+Out Parameters for Oracle
+-------------------------
+
+::
+
+    result = engine.execute(text("begin foo(:x, :y, :z); end;", bindparams=[bindparam('x', Numeric), outparam('y', Numeric), outparam('z', Numeric)]), x=5)
+    assert result.out_parameters == {'y':10, 'z':75}
+
+Connection-bound ``MetaData``, ``Sessions``
+-------------------------------------------
+
+``MetaData`` and ``Session`` can be explicitly bound to a
+connection:
+
+::
+
+    conn = engine.connect()
+    sess = create_session(bind=conn)
+
+Faster, More Foolproof ``ResultProxy`` Objects
+----------------------------------------------
+
diff --git a/doc/build/changelog/migration_05.rst b/doc/build/changelog/migration_05.rst
new file mode 100644 (file)
index 0000000..c79f8b0
--- /dev/null
@@ -0,0 +1,746 @@
+=============================
+What's new in SQLAlchemy 0.5?
+=============================
+
+.. admonition:: About this Document
+
+    This document describes changes between SQLAlchemy version 0.4,
+    last released October 12, 2008, and SQLAlchemy version 0.5,
+    last released January 16, 2010.
+
+    Document date: August 4, 2009
+
+
+This guide documents API changes which affect users
+migrating their applications from the 0.4 series of
+SQLAlchemy to 0.5.   It's also recommended for those working
+from  `Essential SQLAlchemy
+<http://oreilly.com/catalog/9780596516147/>`_, which only
+covers 0.4 and seems to even have some old 0.3isms in it.
+Note that SQLAlchemy 0.5 removes many behaviors which were
+deprecated throughout the span of the 0.4 series, and also
+deprecates more behaviors specific to 0.4.
+
+Major Documentation Changes
+===========================
+
+Some sections of the documentation have been completely
+rewritten and can serve as an introduction to new ORM
+features.  The ``Query`` and ``Session`` objects in
+particular have some distinct differences in API and
+behavior which fundamentally change many of the basic ways
+things are done, particularly with regards to constructing
+highly customized ORM queries and dealing with stale session
+state, commits and rollbacks.
+
+* `ORM Tutorial
+  <http://www.sqlalchemy.org/docs/05/ormtutorial.html>`_
+
+* `Session Documentation
+  <http://www.sqlalchemy.org/docs/05/session.html>`_
+
+Deprecations Source
+===================
+
+Another source of information is documented within a series
+of unit tests illustrating up to date usages of some common
+``Query`` patterns; this file can be viewed at
+[source:sqlalchemy/trunk/test/orm/test_deprecations.py].
+
+Requirements Changes
+====================
+
+* Python 2.4 or higher is required.  The SQLAlchemy 0.4 line
+  is the last version with Python 2.3 support.
+
+Object Relational Mapping
+=========================
+
+* **Column level expressions within Query.** - as detailed
+  in the `tutorial
+  <http://www.sqlalchemy.org/docs/05/ormtutorial.html>`_,
+  ``Query`` has the capability to create specific SELECT
+  statements, not just those against full rows:
+
+  ::
+
+      session.query(User.name, func.count(Address.id).label("numaddresses")).join(Address).group_by(User.name)
+
+  The tuples returned by any multi-column/entity query are
+  *named*' tuples:
+
+  ::
+
+      for row in session.query(User.name, func.count(Address.id).label('numaddresses')).join(Address).group_by(User.name):
+         print "name", row.name, "number", row.numaddresses
+
+  ``Query`` has a ``statement`` accessor, as well as a
+  ``subquery()`` method which allow ``Query`` to be used to
+  create more complex combinations:
+
+  ::
+
+      subq = session.query(Keyword.id.label('keyword_id')).filter(Keyword.name.in_(['beans', 'carrots'])).subquery()
+      recipes = session.query(Recipe).filter(exists().
+         where(Recipe.id==recipe_keywords.c.recipe_id).
+         where(recipe_keywords.c.keyword_id==subq.c.keyword_id)
+      )
+
+* **Explicit ORM aliases are recommended for aliased joins**
+  - The ``aliased()`` function produces an "alias" of a
+  class, which allows fine-grained control of aliases in
+  conjunction with ORM queries.  While a table-level alias
+  (i.e. ``table.alias()``) is still usable, an ORM level
+  alias retains the semantics of the ORM mapped object which
+  is significant for inheritance mappings, options, and
+  other scenarios.  E.g.:
+
+  ::
+
+      Friend = aliased(Person)
+      session.query(Person, Friend).join((Friend, Person.friends)).all()
+
+* **query.join() greatly enhanced.** - You can now specify
+  the target and ON clause for a join in multiple ways.   A
+  target class alone can be provided where SQLA will attempt
+  to form a join to it via foreign key in the same way as
+  ``table.join(someothertable)``.  A target and an explicit
+  ON condition can be provided, where the ON condition can
+  be a ``relation()`` name, an actual class descriptor, or a
+  SQL expression.  Or the old way of just a ``relation()``
+  name or class descriptor works too.   See the ORM tutorial
+  which has several examples.
+
+* **Declarative is recommended for applications which don't
+  require (and don't prefer) abstraction between tables and
+  mappers** - The [/docs/05/reference/ext/declarative.html
+  Declarative] module, which is used to combine the
+  expression of ``Table``, ``mapper()``, and user defined
+  class objects together, is highly recommended as it
+  simplifies application configuration, ensures the "one
+  mapper per class" pattern, and allows the full range of
+  configuration available to distinct ``mapper()`` calls.
+  Separate ``mapper()`` and ``Table`` usage is now referred
+  to as "classical SQLAlchemy usage" and of course is freely
+  mixable with declarative.
+
+* **The .c. attribute has been removed** from classes (i.e.
+  ``MyClass.c.somecolumn``).  As is the case in 0.4, class-
+  level properties are usable as query elements, i.e.
+  ``Class.c.propname`` is now superseded by
+  ``Class.propname``, and the ``c`` attribute continues to
+  remain on ``Table`` objects where they indicate the
+  namespace of ``Column`` objects present on the table.
+
+  To get at the Table for a mapped class (if you didn't keep
+  it around already):
+
+  ::
+
+      table = class_mapper(someclass).mapped_table
+
+  Iterate through columns:
+
+  ::
+
+      for col in table.c:
+          print col
+
+  Work with a specific column:
+
+  ::
+
+      table.c.somecolumn
+
+  The class-bound descriptors support the full set of Column
+  operators as well as the documented relation-oriented
+  operators like ``has()``, ``any()``, ``contains()``, etc.
+
+  The reason for the hard removal of ``.c.`` is that in 0.5,
+  class-bound descriptors carry potentially different
+  meaning, as well as information regarding class mappings,
+  versus plain ``Column`` objects - and there are use cases
+  where you'd specifically want to use one or the other.
+  Generally, using class-bound descriptors invokes a set of
+  mapping/polymorphic aware translations, and using table-
+  bound columns does not.  In 0.4, these translations were
+  applied across the board to all expressions, but 0.5
+  differentiates completely between columns and mapped
+  descriptors, only applying translations to the latter.  So
+  in many cases, particularly when dealing with joined table
+  inheritance configurations as well as when using
+  ``query(<columns>)``, ``Class.propname`` and
+  ``table.c.colname`` are not interchangeable.
+
+  For example, ``session.query(users.c.id, users.c.name)``
+  is different versus ``session.query(User.id, User.name)``;
+  in the latter case, the ``Query`` is aware of the mapper
+  in use and further mapper-specific operations like
+  ``query.join(<propname>)``, ``query.with_parent()`` etc.
+  may be used, but in the former case cannot.  Additionally,
+  in polymorphic inheritance scenarios, the class-bound
+  descriptors refer to the columns present in the
+  polymorphic selectable in use, not necessarily the table
+  column which directly corresponds to the descriptor.  For
+  example, a set of classes related by joined-table
+  inheritance to the ``person`` table along the
+  ``person_id`` column of each table will all have their
+  ``Class.person_id`` attribute mapped to the ``person_id``
+  column in ``person``, and not their subclass table.
+  Version 0.4 would map this behavior onto table-bound
+  ``Column`` objects automatically.  In 0.5, this automatic
+  conversion has been removed, so that you in fact *can* use
+  table-bound columns as a means to override the
+  translations which occur with polymorphic querying; this
+  allows ``Query`` to be able to create optimized selects
+  among joined-table or concrete-table inheritance setups,
+  as well as portable subqueries, etc.
+
+* **Session Now Synchronizes Automatically with
+  Transactions.** Session now synchronizes against the
+  transaction automatically by default, including autoflush
+  and autoexpire.  A transaction is present at all times
+  unless disabled using the ``autocommit`` option.  When all
+  three flags are set to their default, the Session recovers
+  gracefully after rollbacks and it's very difficult to get
+  stale data into the session.  See the new Session
+  documentation for details.
+
+* **Implicit Order By Is Removed**.  This will impact ORM
+  users who rely upon SA's "implicit ordering" behavior,
+  which states that all Query objects which don't have an
+  ``order_by()`` will ORDER BY the "id" or "oid" column of
+  the primary mapped table, and all lazy/eagerly loaded
+  collections apply a similar ordering.   In 0.5, automatic
+  ordering must be explicitly configured on ``mapper()`` and
+  ``relation()`` objects (if desired), or otherwise when
+  using ``Query``.
+
+  To convert an 0.4 mapping to 0.5, such that its ordering
+  behavior will be extremely similar to 0.4 or previous, use
+  the ``order_by`` setting on ``mapper()`` and
+  ``relation()``:
+
+  ::
+
+          mapper(User, users, properties={
+              'addresses':relation(Address, order_by=addresses.c.id)
+          }, order_by=users.c.id)
+
+  To set ordering on a backref, use the ``backref()``
+  function:
+
+  ::
+
+          'keywords':relation(Keyword, secondary=item_keywords,
+                order_by=keywords.c.name, backref=backref('items', order_by=items.c.id))
+
+  Using declarative ?  To help with the new ``order_by``
+  requirement, ``order_by`` and friends can now be set using
+  strings which are evaluated in Python later on (this works
+  **only** with declarative, not plain mappers):
+
+  ::
+
+          class MyClass(MyDeclarativeBase):
+              ...
+              'addresses':relation("Address", order_by="Address.id")
+
+  It's generally a good idea to set ``order_by`` on
+  ``relation()s`` which load list-based collections of
+  items, since that ordering cannot otherwise be affected.
+  Other than that, the best practice is to use
+  ``Query.order_by()`` to control ordering of the primary
+  entities being loaded.
+
+* **Session is now
+  autoflush=True/autoexpire=True/autocommit=False.** - To
+  set it up, just call ``sessionmaker()`` with no arguments.
+  The name ``transactional=True`` is now
+  ``autocommit=False``.  Flushes occur upon each query
+  issued (disable with ``autoflush=False``), within each
+  ``commit()`` (as always), and before each
+  ``begin_nested()`` (so rolling back to the SAVEPOINT is
+  meaningful).   All objects are expired after each
+  ``commit()`` and after each ``rollback()``.  After
+  rollback, pending objects are expunged, deleted objects
+  move back to persistent.  These defaults work together
+  very nicely and there's really no more need for old
+  techniques like ``clear()`` (which is renamed to
+  ``expunge_all()`` as well).
+
+  P.S.:  sessions are now reusable after a ``rollback()``.
+  Scalar and collection attribute changes, adds and deletes
+  are all rolled back.
+
+* **session.add() replaces session.save(), session.update(),
+  session.save_or_update().** - the
+  ``session.add(someitem)`` and ``session.add_all([list of
+  items])`` methods replace ``save()``, ``update()``, and
+  ``save_or_update()``.  Those methods will remain
+  deprecated throughout 0.5.
+
+* **backref configuration made less verbose.** - The
+  ``backref()`` function now uses the ``primaryjoin`` and
+  ``secondaryjoin`` arguments of the forwards-facing
+  ``relation()`` when they are not explicitly stated.  It's
+  no longer necessary to specify
+  ``primaryjoin``/``secondaryjoin`` in both directions
+  separately.
+
+* **Simplified polymorphic options.** - The ORM's
+  "polymorphic load" behavior has been simplified.  In 0.4,
+  mapper() had an argument called ``polymorphic_fetch``
+  which could be configured as ``select`` or ``deferred``.
+  This option is removed; the mapper will now just defer any
+  columns which were not present in the SELECT statement.
+  The actual SELECT statement used is controlled by the
+  ``with_polymorphic`` mapper argument (which is also in 0.4
+  and replaces ``select_table``), as well as the
+  ``with_polymorphic()`` method on ``Query`` (also in 0.4).
+
+  An improvement to the deferred loading of inheriting
+  classes is that the mapper now produces the "optimized"
+  version of the SELECT statement in all cases; that is, if
+  class B inherits from A, and several attributes only
+  present on class B have been expired, the refresh
+  operation will only include B's table in the SELECT
+  statement and will not JOIN to A.
+
+* The ``execute()`` method on ``Session`` converts plain
+  strings into ``text()`` constructs, so that bind
+  parameters may all be specified as ":bindname" without
+  needing to call ``text()`` explicitly.  If "raw" SQL is
+  desired here, use ``session.connection().execute("raw
+  text")``.
+
+* ``session.Query().iterate_instances()`` has been renamed
+  to just ``instances()``. The old ``instances()`` method
+  returning a list instead of an iterator no longer exists.
+  If you were relying on that behavior, you should use
+  ``list(your_query.instances())``.
+
+Extending the ORM
+=================
+
+In 0.5 we're moving forward with more ways to modify and
+extend the ORM.  Heres a summary:
+
+* **MapperExtension.** - This is the classic extension
+  class, which remains.   Methods which should rarely be
+  needed are ``create_instance()`` and
+  ``populate_instance()``.  To control the initialization of
+  an object when it's loaded from the database, use the
+  ``reconstruct_instance()`` method, or more easily the
+  ``@reconstructor`` decorator described in the
+  documentation.
+
+* **SessionExtension.** - This is an easy to use extension
+  class for session events.  In particular, it provides
+  ``before_flush()``, ``after_flush()`` and
+  ``after_flush_postexec()`` methods.  It's usage is
+  recommended over ``MapperExtension.before_XXX`` in many
+  cases since within ``before_flush()`` you can modify the
+  flush plan of the session freely, something which cannot
+  be done from within ``MapperExtension``.
+
+* **AttributeExtension.** - This class is now part of the
+  public API, and allows the interception of userland events
+  on attributes, including attribute set and delete
+  operations, and collection appends and removes.  It also
+  allows the value to be set or appended to be modified.
+  The ``@validates`` decorator, described in the
+  documentation, provides a quick way to mark any mapped
+  attributes as being "validated" by a particular class
+  method.
+
+* **Attribute Instrumentation Customization.** - An API is
+  provided for ambitious efforts to entirely replace
+  SQLAlchemy's attribute instrumentation, or just to augment
+  it in some cases.  This API was produced for the purposes
+  of the Trellis toolkit, but is available as a public API.
+  Some examples are provided in the distribution in the
+  ``/examples/custom_attributes`` directory.
+
+Schema/Types
+============
+
+* **String with no length no longer generates TEXT, it
+  generates VARCHAR** - The ``String`` type no longer
+  magically converts into a ``Text`` type when specified
+  with no length.  This only has an effect when CREATE TABLE
+  is issued, as it will issue ``VARCHAR`` with no length
+  parameter, which is not valid on many (but not all)
+  databases.  To create a TEXT (or CLOB, i.e. unbounded
+  string) column, use the ``Text`` type.
+
+* **PickleType() with mutable=True requires an __eq__()
+  method** - The ``PickleType`` type needs to compare values
+  when mutable=True.  The method of comparing
+  ``pickle.dumps()`` is inefficient and unreliable.  If an
+  incoming object does not implement ``__eq__()`` and is
+  also not ``None``, the ``dumps()`` comparison is used but
+  a warning is raised.  For types which implement
+  ``__eq__()`` which includes all dictionaries, lists, etc.,
+  comparison will use ``==`` and is now reliable by default.
+
+* **convert_bind_param() and convert_result_value() methods
+  of TypeEngine/TypeDecorator are removed.** - The O'Reilly
+  book unfortunately documented these methods even though
+  they were deprecated post 0.3.   For a user-defined type
+  which subclasses ``TypeEngine``, the ``bind_processor()``
+  and ``result_processor()`` methods should be used for
+  bind/result processing.  Any user defined type, whether
+  extending ``TypeEngine`` or ``TypeDecorator``, which uses
+  the old 0.3 style can be easily adapted to the new style
+  using the following adapter:
+
+  ::
+
+      class AdaptOldConvertMethods(object):
+          """A mixin which adapts 0.3-style convert_bind_param and
+          convert_result_value methods
+
+          """
+          def bind_processor(self, dialect):
+              def convert(value):
+                  return self.convert_bind_param(value, dialect)
+              return convert
+
+          def result_processor(self, dialect):
+              def convert(value):
+                  return self.convert_result_value(value, dialect)
+              return convert
+
+          def convert_result_value(self, value, dialect):
+              return value
+
+          def convert_bind_param(self, value, dialect):
+              return value
+
+  To use the above mixin:
+
+  ::
+
+      class MyType(AdaptOldConvertMethods, TypeEngine):
+         # ...
+
+* The ``quote`` flag on ``Column`` and ``Table`` as well as
+  the ``quote_schema`` flag on ``Table`` now control quoting
+  both positively and negatively.  The default is ``None``,
+  meaning let regular quoting rules take effect. When
+  ``True``, quoting is forced on.  When ``False``, quoting
+  is forced off.
+
+* Column ``DEFAULT`` value DDL can now be more conveniently
+  specified with ``Column(..., server_default='val')``,
+  deprecating ``Column(..., PassiveDefault('val'))``.
+  ``default=`` is now exclusively for Python-initiated
+  default values, and can coexist with server_default.  A
+  new ``server_default=FetchedValue()`` replaces the
+  ``PassiveDefault('')`` idiom for marking columns as
+  subject to influence from external triggers and has no DDL
+  side effects.
+
+* SQLite's ``DateTime``, ``Time`` and ``Date`` types now
+  **only accept datetime objects, not strings** as bind
+  parameter input.  If you'd like to create your own
+  "hybrid" type which accepts strings and returns results as
+  date objects (from whatever format you'd like), create a
+  ``TypeDecorator`` that builds on ``String``.  If you only
+  want string-based dates, just use ``String``.
+
+* Additionally, the ``DateTime`` and ``Time`` types, when
+  used with SQLite, now represent the "microseconds" field
+  of the Python ``datetime.datetime`` object in the same
+  manner as ``str(datetime)`` - as fractional seconds, not a
+  count of microseconds.  That is:
+
+  ::
+
+       dt = datetime.datetime(2008, 6, 27, 12, 0, 0, 125)  # 125 usec
+
+       # old way
+       '2008-06-27 12:00:00.125'
+
+       # new way
+       '2008-06-27 12:00:00.000125'
+
+  So if an existing SQLite file-based database intends to be
+  used across 0.4 and 0.5, you either have to upgrade the
+  datetime columns to store the new format (NOTE: please
+  test this, I'm pretty sure its correct):
+
+  ::
+
+       UPDATE mytable SET somedatecol =
+         substr(somedatecol, 0, 19) || '.' || substr((substr(somedatecol, 21, -1) / 1000000), 3, -1);
+
+  or, enable "legacy" mode as follows:
+
+  ::
+
+       from sqlalchemy.databases.sqlite import DateTimeMixin
+       DateTimeMixin.__legacy_microseconds__ = True
+
+Connection Pool no longer threadlocal by default
+================================================
+
+0.4 has an unfortunate default setting of
+"pool_threadlocal=True", leading to surprise behavior when,
+for example, using multiple Sessions within a single thread.
+This flag is now off in 0.5.   To re-enable 0.4's behavior,
+specify ``pool_threadlocal=True`` to ``create_engine()``, or
+alternatively use the "threadlocal" strategy via
+``strategy="threadlocal"``.
+
+\*args Accepted, \*args No Longer Accepted
+==========================================
+
+The policy with ``method(\*args)`` vs. ``method([args])``
+is, if the method accepts a variable-length set of items
+which represent a fixed structure, it takes ``\*args``.  If
+the method accepts a variable-length set of items that are
+data-driven, it takes ``[args]``.
+
+* The various Query.options() functions ``eagerload()``,
+  ``eagerload_all()``, ``lazyload()``, ``contains_eager()``,
+  ``defer()``, ``undefer()`` all accept variable-length
+  ``\*keys`` as their argument now, which allows a path to
+  be formulated using descriptors, ie.:
+
+  ::
+
+         query.options(eagerload_all(User.orders, Order.items, Item.keywords))
+
+  A single array argument is still accepted for backwards
+  compatibility.
+
+* Similarly, the ``Query.join()`` and ``Query.outerjoin()``
+  methods accept a variable length \*args, with a single
+  array accepted for backwards compatibility:
+
+  ::
+
+         query.join('orders', 'items')
+         query.join(User.orders, Order.items)
+
+* the ``in_()`` method on columns and similar only accepts a
+  list argument now.  It no longer accepts ``\*args``.
+
+Removed
+=======
+
+* **entity_name** - This feature was always problematic and
+  rarely used.  0.5's more deeply fleshed out use cases
+  revealed further issues with ``entity_name`` which led to
+  its removal.  If different mappings are required for a
+  single class, break the class into separate subclasses and
+  map them separately.  An example of this is at
+  [wiki:UsageRecipes/EntityName].  More information
+  regarding rationale is described at http://groups.google.c
+  om/group/sqlalchemy/browse_thread/thread/9e23a0641a88b96d?
+  hl=en .
+
+* **get()/load() cleanup**
+
+
+  The ``load()`` method has been removed.  It's
+  functionality was kind of arbitrary and basically copied
+  from Hibernate, where it's also not a particularly
+  meaningful method.
+
+  To get equivalent functionality:
+
+  ::
+
+       x = session.query(SomeClass).populate_existing().get(7)
+
+  ``Session.get(cls, id)`` and ``Session.load(cls, id)``
+  have been removed.  ``Session.get()`` is redundant vs.
+  ``session.query(cls).get(id)``.
+
+  ``MapperExtension.get()`` is also removed (as is
+  ``MapperExtension.load()``).  To override the
+  functionality of ``Query.get()``, use a subclass:
+
+  ::
+
+       class MyQuery(Query):
+           def get(self, ident):
+               # ...
+
+       session = sessionmaker(query_cls=MyQuery)()
+
+       ad1 = session.query(Address).get(1)
+
+* ``sqlalchemy.orm.relation()``
+
+
+  The following deprecated keyword arguments have been
+  removed:
+
+  foreignkey, association, private, attributeext, is_backref
+
+  In particular, ``attributeext`` is replaced with
+  ``extension`` - the ``AttributeExtension`` class is now in
+  the public API.
+
+* ``session.Query()``
+
+
+  The following deprecated functions have been removed:
+
+  list, scalar, count_by, select_whereclause, get_by,
+  select_by, join_by, selectfirst, selectone, select,
+  execute, select_statement, select_text, join_to, join_via,
+  selectfirst_by, selectone_by, apply_max, apply_min,
+  apply_avg, apply_sum
+
+  Additionally, the ``id`` keyword argument to ``join()``,
+  ``outerjoin()``, ``add_entity()`` and ``add_column()`` has
+  been removed.  To target table aliases in ``Query`` to
+  result columns, use the ``aliased`` construct:
+
+  ::
+
+      from sqlalchemy.orm import aliased
+      address_alias = aliased(Address)
+      print session.query(User, address_alias).join((address_alias, User.addresses)).all()
+
+* ``sqlalchemy.orm.Mapper``
+
+
+  * instances()
+
+
+  * get_session() - this method was not very noticeable, but
+    had the effect of associating lazy loads with a
+    particular session even if the parent object was
+    entirely detached, when an extension such as
+    ``scoped_session()`` or the old ``SessionContextExt``
+    was used.  It's possible that some applications which
+    relied upon this behavior will no longer work as
+    expected;  but the better programming practice here is
+    to always ensure objects are present within sessions if
+    database access from their attributes are required.
+
+* ``mapper(MyClass, mytable)``
+
+
+  Mapped classes no are longer instrumented with a "c" class
+  attribute; e.g. ``MyClass.c``
+
+* ``sqlalchemy.orm.collections``
+
+
+  The _prepare_instrumentation alias for
+  prepare_instrumentation has been removed.
+
+* ``sqlalchemy.orm``
+
+
+  Removed the ``EXT_PASS`` alias of ``EXT_CONTINUE``.
+
+* ``sqlalchemy.engine``
+
+
+  The alias from ``DefaultDialect.preexecute_sequences`` to
+  ``.preexecute_pk_sequences`` has been removed.
+
+  The deprecated engine_descriptors() function has been
+  removed.
+
+* ``sqlalchemy.ext.activemapper``
+
+
+  Module removed.
+
+* ``sqlalchemy.ext.assignmapper``
+
+
+  Module removed.
+
+* ``sqlalchemy.ext.associationproxy``
+
+
+  Pass-through of keyword args on the proxy's
+  ``.append(item, \**kw)`` has been removed and is now
+  simply ``.append(item)``
+
+* ``sqlalchemy.ext.selectresults``,
+  ``sqlalchemy.mods.selectresults``
+
+  Modules removed.
+
+* ``sqlalchemy.ext.declarative``
+
+
+  ``declared_synonym()`` removed.
+
+* ``sqlalchemy.ext.sessioncontext``
+
+
+  Module removed.
+
+* ``sqlalchemy.log``
+
+
+  The ``SADeprecationWarning`` alias to
+  ``sqlalchemy.exc.SADeprecationWarning`` has been removed.
+
+* ``sqlalchemy.exc``
+
+
+  ``exc.AssertionError`` has been removed and usage replaced
+  by the Python built-in of the same name.
+
+* ``sqlalchemy.databases.mysql``
+
+
+  The deprecated ``get_version_info`` dialect method has
+  been removed.
+
+Renamed or Moved
+================
+
+* ``sqlalchemy.exceptions`` is now ``sqlalchemy.exc``
+
+
+  The module may still be imported under the old name until
+  0.6.
+
+* ``FlushError``, ``ConcurrentModificationError``,
+  ``UnmappedColumnError`` -> sqlalchemy.orm.exc
+
+  These exceptions moved to the orm package.  Importing
+  'sqlalchemy.orm' will install aliases in sqlalchemy.exc
+  for compatibility until 0.6.
+
+* ``sqlalchemy.logging`` -> ``sqlalchemy.log``
+
+
+  This internal module was renamed.  No longer needs to be
+  special cased when packaging SA with py2app and similar
+  tools that scan imports.
+
+* ``session.Query().iterate_instances()`` ->
+  ``session.Query().instances()``.
+
+Deprecated
+==========
+
+* ``Session.save()``, ``Session.update()``,
+  ``Session.save_or_update()``
+
+  All three replaced by ``Session.add()``
+
+* ``sqlalchemy.PassiveDefault``
+
+
+  Use ``Column(server_default=...)`` Translates to
+  sqlalchemy.DefaultClause() under the hood.
+
+* ``session.Query().iterate_instances()``. It has been
+  renamed to ``instances()``.
+
diff --git a/doc/build/changelog/migration_06.rst b/doc/build/changelog/migration_06.rst
new file mode 100644 (file)
index 0000000..d561452
--- /dev/null
@@ -0,0 +1,1228 @@
+==============================
+What's New in SQLAlchemy 0.6 ?
+==============================
+
+.. admonition:: About this Document
+
+    This document describes changes between SQLAlchemy version 0.5,
+    last released January 16, 2010, and SQLAlchemy version 0.6,
+    last released May 5, 2012.
+
+    Document date:  June 6, 2010
+
+This guide documents API changes which affect users
+migrating their applications from the 0.5 series of
+SQLAlchemy to 0.6.  Note that SQLAlchemy 0.6 removes some
+behaviors which were deprecated throughout the span of the
+0.5 series, and also deprecates more behaviors specific to
+0.5.
+
+Platform Support
+================
+
+* cPython versions 2.4 and upwards throughout the 2.xx
+  series
+
+* Jython 2.5.1 - using the zxJDBC DBAPI included with
+  Jython.
+
+* cPython 3.x - see [source:sqlalchemy/trunk/README.py3k]
+  for information on how to build for python3.
+
+New Dialect System
+==================
+
+Dialect modules are now broken up into distinct
+subcomponents, within the scope of a single database
+backend.   Dialect implementations are now in the
+``sqlalchemy.dialects`` package.  The
+``sqlalchemy.databases`` package still exists as a
+placeholder to provide some level of backwards compatibility
+for simple imports.
+
+For each supported database, a sub-package exists within
+``sqlalchemy.dialects`` where several files are contained.
+Each package contains a module called ``base.py`` which
+defines the specific SQL dialect used by that database.   It
+also contains one or more "driver" modules, each one
+corresponding to a specific DBAPI - these files are named
+corresponding to the DBAPI itself, such as ``pysqlite``,
+``cx_oracle``, or ``pyodbc``.  The classes used by
+SQLAlchemy dialects are first declared in the ``base.py``
+module, defining all behavioral characteristics defined by
+the database.  These include capability mappings, such as
+"supports sequences", "supports returning", etc., type
+definitions, and SQL compilation rules.  Each "driver"
+module in turn provides subclasses of those classes as
+needed which override the default behavior to accommodate
+the additional features, behaviors, and quirks of that
+DBAPI.    For DBAPIs that support multiple backends (pyodbc,
+zxJDBC, mxODBC), the dialect module will use mixins from the
+``sqlalchemy.connectors`` package, which provide
+functionality common to that DBAPI across all backends, most
+typically dealing with connect arguments.   This means that
+connecting using pyodbc, zxJDBC or mxODBC (when implemented)
+is extremely consistent across supported backends.
+
+The URL format used by ``create_engine()`` has been enhanced
+to handle any number of DBAPIs for a particular backend,
+using a scheme that is inspired by that of JDBC.   The
+previous format still works, and will select a "default"
+DBAPI implementation, such as the Postgresql URL below that
+will use psycopg2:
+
+::
+
+    create_engine('postgresql://scott:tiger@localhost/test')
+
+However to specify a specific DBAPI backend such as pg8000,
+add it to the "protocol" section of the URL using a plus
+sign "+":
+
+::
+
+    create_engine('postgresql+pg8000://scott:tiger@localhost/test')
+
+Important Dialect Links:
+
+* Documentation on connect arguments:
+  http://www.sqlalchemy.org/docs/06/dbengine.html#create-
+  engine-url-arguments.
+
+* Reference documentation for individual dialects: http://ww
+  w.sqlalchemy.org/docs/06/reference/dialects/index.html
+
+* The tips and tricks at DatabaseNotes.
+
+
+Other notes regarding dialects:
+
+* the type system has been changed dramatically in
+  SQLAlchemy 0.6.  This has an impact on all dialects
+  regarding naming conventions, behaviors, and
+  implementations.  See the section on "Types" below.
+
+* the ``ResultProxy`` object now offers a 2x speed
+  improvement in some cases thanks to some refactorings.
+
+* the ``RowProxy``, i.e. individual result row object, is
+  now directly pickleable.
+
+* the setuptools entrypoint used to locate external dialects
+  is now called ``sqlalchemy.dialects``.  An external
+  dialect written against 0.4 or 0.5 will need to be
+  modified to work with 0.6 in any case so this change does
+  not add any additional difficulties.
+
+* dialects now receive an initialize() event on initial
+  connection to determine connection properties.
+
+* Functions and operators generated by the compiler now use
+  (almost) regular dispatch functions of the form
+  "visit_<opname>" and "visit_<funcname>_fn" to provide
+  customed processing. This replaces the need to copy the
+  "functions" and "operators" dictionaries in compiler
+  subclasses with straightforward visitor methods, and also
+  allows compiler subclasses complete control over
+  rendering, as the full _Function or _BinaryExpression
+  object is passed in.
+
+Dialect Imports
+---------------
+
+The import structure of dialects has changed.  Each dialect
+now exports its base "dialect" class as well as the full set
+of SQL types supported on that dialect via
+``sqlalchemy.dialects.<name>``.  For example, to import a
+set of PG types:
+
+::
+
+    from sqlalchemy.dialects.postgresql import INTEGER, BIGINT, SMALLINT,\
+                                                VARCHAR, MACADDR, DATE, BYTEA
+
+Above, ``INTEGER`` is actually the plain ``INTEGER`` type
+from ``sqlalchemy.types``, but the PG dialect makes it
+available in the same way as those types which are specific
+to PG, such as ``BYTEA`` and ``MACADDR``.
+
+Expression Language Changes
+===========================
+
+An Important Expression Language Gotcha
+---------------------------------------
+
+There's one quite significant behavioral change to the
+expression language which may affect some applications.
+The boolean value of Python boolean expressions, i.e.
+``==``, ``!=``, and similar, now evaluates accurately with
+regards to the two clause objects being compared.
+
+As we know, comparing a ``ClauseElement`` to any other
+object returns another ``ClauseElement``:
+
+::
+
+    >>> from sqlalchemy.sql import column
+    >>> column('foo') == 5
+    <sqlalchemy.sql.expression._BinaryExpression object at 0x1252490>
+
+This so that Python expressions produce SQL expressions when
+converted to strings:
+
+::
+
+    >>> str(column('foo') == 5)
+    'foo = :foo_1'
+
+But what happens if we say this?
+
+::
+
+    >>> if column('foo') == 5:
+    ...     print "yes"
+    ...
+
+In previous versions of SQLAlchemy, the returned
+``_BinaryExpression`` was a plain Python object which
+evaluated to ``True``.  Now it evaluates to whether or not
+the actual ``ClauseElement`` should have the same hash value
+as to that being compared.  Meaning:
+
+::
+
+    >>> bool(column('foo') == 5)
+    False
+    >>> bool(column('foo') == column('foo'))
+    False
+    >>> c = column('foo')
+    >>> bool(c == c)
+    True
+    >>>
+
+That means code such as the following:
+
+::
+
+    if expression:
+        print "the expression is:", expression
+
+Would not evaluate if ``expression`` was a binary clause.
+Since the above pattern should never be used, the base
+``ClauseElement`` now raises an exception if called in a
+boolean context:
+
+::
+
+    >>> bool(c)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+      ...
+        raise TypeError("Boolean value of this clause is not defined")
+    TypeError: Boolean value of this clause is not defined
+
+Code that wants to check for the presence of a
+``ClauseElement`` expression should instead say:
+
+::
+
+    if expression is not None:
+        print "the expression is:", expression
+
+Keep in mind, **this applies to Table and Column objects
+too**.
+
+The rationale for the change is twofold:
+
+* Comparisons of the form ``if c1 == c2:  <do something>``
+  can actually be written now
+
+* Support for correct hashing of ``ClauseElement`` objects
+  now works on alternate platforms, namely Jython.  Up until
+  this point SQLAlchemy relied heavily on the specific
+  behavior of cPython in this regard (and still had
+  occasional problems with it).
+
+Stricter "executemany" Behavior
+-------------------------------
+
+An "executemany" in SQLAlchemy corresponds to a call to
+``execute()``, passing along a collection of bind parameter
+sets:
+
+::
+
+    connection.execute(table.insert(), {'data':'row1'}, {'data':'row2'}, {'data':'row3'})
+
+When the ``Connection`` object sends off the given
+``insert()`` construct for compilation, it passes to the
+compiler the keynames present in the first set of binds
+passed along to determine the construction of the
+statement's VALUES clause.   Users familiar with this
+construct will know that additional keys present in the
+remaining dictionaries don't have any impact.   What's
+different now is that all subsequent dictionaries need to
+include at least *every* key that is present in the first
+dictionary.  This means that a call like this no longer
+works:
+
+::
+
+    connection.execute(table.insert(),
+                            {'timestamp':today, 'data':'row1'},
+                            {'timestamp':today, 'data':'row2'},
+                            {'data':'row3'})
+
+Because the third row does not specify the 'timestamp'
+column.  Previous versions of SQLAlchemy would simply insert
+NULL for these missing columns.  However, if the
+``timestamp`` column in the above example contained a
+Python-side default value or function, it would *not* be
+used.  This because the "executemany" operation is optimized
+for maximum performance across huge numbers of parameter
+sets, and does not attempt to evaluate Python-side defaults
+for those missing keys.   Because defaults are often
+implemented either as SQL expressions which are embedded
+inline with the INSERT statement, or are server side
+expressions which again are triggered based on the structure
+of the INSERT string, which by definition cannot fire off
+conditionally based on each parameter set, it would be
+inconsistent for Python side defaults to behave differently
+vs. SQL/server side defaults.   (SQL expression based
+defaults are embedded inline as of the 0.5 series, again to
+minimize the impact of huge numbers of parameter sets).
+
+SQLAlchemy 0.6 therefore establishes predictable consistency
+by forbidding any subsequent parameter sets from leaving any
+fields blank.  That way, there's no more silent failure of
+Python side default values and functions, which additionally
+are allowed to remain consistent in their behavior versus
+SQL and server side defaults.
+
+UNION and other "compound" constructs parenthesize consistently
+---------------------------------------------------------------
+
+A rule that was designed to help SQLite has been removed,
+that of the first compound element within another compound
+(such as, a ``union()`` inside of an ``except_()``) wouldn't
+be parenthesized.   This is inconsistent and produces the
+wrong results on Postgresql, which has precedence rules
+regarding INTERSECTION, and its generally a surprise.   When
+using complex composites with SQLite, you now need to turn
+the first element into a subquery (which is also compatible
+on PG).   A new example is in the SQL expression tutorial at
+the end of
+[http://www.sqlalchemy.org/docs/06/sqlexpression.html
+#unions-and-other-set-operations].  See :ticket:`1665` and
+r6690 for more background.
+
+C Extensions for Result Fetching
+================================
+
+The ``ResultProxy`` and related elements, including most
+common "row processing" functions such as unicode
+conversion, numerical/boolean conversions and date parsing,
+have been re-implemented as optional C extensions for the
+purposes of performance.   This represents the beginning of
+SQLAlchemy's path to the "dark side" where we hope to
+continue improving performance by reimplementing critical
+sections in C.   The extensions can be built by specifying
+``--with-cextensions``, i.e. ``python setup.py --with-
+cextensions install``.
+
+The extensions have the most dramatic impact on result
+fetching using direct ``ResultProxy`` access, i.e. that
+which is returned by ``engine.execute()``,
+``connection.execute()``, or ``session.execute()``.   Within
+results returned by an ORM ``Query`` object, result fetching
+is not as high a percentage of overhead, so ORM performance
+improves more modestly, and mostly in the realm of fetching
+large result sets.   The performance improvements highly
+depend on the dbapi in use and on the syntax used to access
+the columns of each row (eg ``row['name']`` is much faster
+than ``row.name``).  The current extensions have no impact
+on the speed of inserts/updates/deletes, nor do they improve
+the latency of SQL execution, that is, an application that
+spends most of its time executing many statements with very
+small result sets will not see much improvement.
+
+Performance has been improved in 0.6 versus 0.5 regardless
+of the extensions.   A quick overview of what connecting and
+fetching 50,000 rows looks like with SQLite, using mostly
+direct SQLite access, a ``ResultProxy``, and a simple mapped
+ORM object:
+
+::
+
+    sqlite select/native: 0.260s
+
+    0.6 / C extension
+
+    sqlalchemy.sql select: 0.360s
+    sqlalchemy.orm fetch: 2.500s
+
+    0.6 / Pure Python
+
+    sqlalchemy.sql select: 0.600s
+    sqlalchemy.orm fetch: 3.000s
+
+    0.5 / Pure Python
+
+    sqlalchemy.sql select: 0.790s
+    sqlalchemy.orm fetch: 4.030s
+
+Above, the ORM fetches the rows 33% faster than 0.5 due to
+in-python performance enhancements.   With the C extensions
+we get another 20%.   However, ``ResultProxy`` fetches
+improve by 67% with the C extension versus not.   Other
+tests report as much as a 200% speed improvement for some
+scenarios, such as those where lots of string conversions
+are occurring.
+
+New Schema Capabilities
+=======================
+
+The ``sqlalchemy.schema`` package has received some long-
+needed attention.   The most visible change is the newly
+expanded DDL system.   In SQLAlchemy, it was possible since
+version 0.5 to create custom DDL strings and associate them
+with tables or metadata objects:
+
+::
+
+    from sqlalchemy.schema import DDL
+
+    DDL('CREATE TRIGGER users_trigger ...').execute_at('after-create', metadata)
+
+Now the full suite of DDL constructs are available under the
+same system, including those for CREATE TABLE, ADD
+CONSTRAINT, etc.:
+
+::
+
+    from sqlalchemy.schema import Constraint, AddConstraint
+
+    AddContraint(CheckConstraint("value > 5")).execute_at('after-create', mytable)
+
+Additionally, all the DDL objects are now regular
+``ClauseElement`` objects just like any other SQLAlchemy
+expression object:
+
+::
+
+    from sqlalchemy.schema import CreateTable
+
+    create = CreateTable(mytable)
+
+    # dumps the CREATE TABLE as a string
+    print create
+
+    # executes the CREATE TABLE statement
+    engine.execute(create)
+
+and using the ``sqlalchemy.ext.compiler`` extension you can
+make your own:
+
+::
+
+    from sqlalchemy.schema import DDLElement
+    from sqlalchemy.ext.compiler import compiles
+
+    class AlterColumn(DDLElement):
+
+        def __init__(self, column, cmd):
+            self.column = column
+            self.cmd = cmd
+
+    @compiles(AlterColumn)
+    def visit_alter_column(element, compiler, **kw):
+        return "ALTER TABLE %s ALTER COLUMN %s %s ..." % (
+            element.column.table.name,
+            element.column.name,
+            element.cmd
+        )
+
+    engine.execute(AlterColumn(table.c.mycolumn, "SET DEFAULT 'test'"))
+
+Deprecated/Removed Schema Elements
+----------------------------------
+
+The schema package has also been greatly streamlined.   Many
+options and methods which were deprecated throughout 0.5
+have been removed.  Other little known accessors and methods
+have also been removed.
+
+* the "owner" keyword argument is removed from ``Table``.
+  Use "schema" to represent any namespaces to be prepended
+  to the table name.
+
+* deprecated ``MetaData.connect()`` and
+  ``ThreadLocalMetaData.connect()`` have been removed - send
+  the "bind" attribute to bind a metadata.
+
+* deprecated metadata.table_iterator() method removed (use
+  sorted_tables)
+
+* the "metadata" argument is removed from
+  ``DefaultGenerator`` and subclasses, but remains locally
+  present on ``Sequence``, which is a standalone construct
+  in DDL.
+
+* deprecated ``PassiveDefault`` - use ``DefaultClause``.
+
+
+* Removed public mutability from ``Index`` and
+  ``Constraint`` objects:
+
+  * ``ForeignKeyConstraint.append_element()``
+
+
+  * ``Index.append_column()``
+
+
+  * ``UniqueConstraint.append_column()``
+
+
+  * ``PrimaryKeyConstraint.add()``
+
+
+  * ``PrimaryKeyConstraint.remove()``
+
+
+These should be constructed declaratively (i.e. in one
+construction).
+
+* Other removed things:
+
+
+  * ``Table.key`` (no idea what this was for)
+
+
+  * ``Column.bind``       (get via column.table.bind)
+
+
+  * ``Column.metadata``   (get via column.table.metadata)
+
+
+  * ``Column.sequence``   (use column.default)
+
+
+Other Behavioral Changes
+------------------------
+
+* ``UniqueConstraint``, ``Index``, ``PrimaryKeyConstraint``
+  all accept lists of column names or column objects as
+  arguments.
+
+* The ``use_alter`` flag on ``ForeignKey`` is now a shortcut
+  option for operations that can be hand-constructed using
+  the ``DDL()`` event system. A side effect of this refactor
+  is that ``ForeignKeyConstraint`` objects with
+  ``use_alter=True`` will *not* be emitted on SQLite, which
+  does not support ALTER for foreign keys. This has no
+  effect on SQLite's behavior since SQLite does not actually
+  honor FOREIGN KEY constraints.
+
+* ``Table.primary_key`` is not assignable - use
+  ``table.append_constraint(PrimaryKeyConstraint(...))``
+
+* A ``Column`` definition with a ``ForeignKey`` and no type,
+  e.g. ``Column(name, ForeignKey(sometable.c.somecol))``
+  used to get the type of the referenced column. Now support
+  for that automatic type inference is partial and may not
+  work in all cases.
+
+Logging opened up
+=================
+
+At the expense of a few extra method calls here and there,
+you can set log levels for INFO and DEBUG after an engine,
+pool, or mapper has been created, and logging will commence.
+The ``isEnabledFor(INFO)`` method is now called
+per-``Connection`` and ``isEnabledFor(DEBUG)``
+per-``ResultProxy`` if already enabled on the parent
+connection.  Pool logging sends to ``log.info()`` and
+``log.debug()`` with no check - note that pool
+checkout/checkin is typically once per transaction.
+
+Reflection/Inspector API
+========================
+
+The reflection system, which allows reflection of table
+columns via ``Table('sometable', metadata, autoload=True)``
+has been opened up into its own fine-grained API, which
+allows direct inspection of database elements such as
+tables, columns, constraints, indexes, and more.   This API
+expresses return values as simple lists of strings,
+dictionaries, and ``TypeEngine`` objects.   The internals of
+``autoload=True`` now build upon this system such that the
+translation of raw database information into
+``sqlalchemy.schema`` constructs is centralized and the
+contract of individual dialects greatly simplified, vastly
+reducing bugs and inconsistencies across different backends.
+
+To use an inspector:
+
+::
+
+    from sqlalchemy.engine.reflection import Inspector
+    insp = Inspector.from_engine(my_engine)
+
+    print insp.get_schema_names()
+
+the ``from_engine()`` method will in some cases provide a
+backend-specific inspector with additional capabilities,
+such as that of Postgresql which provides a
+``get_table_oid()`` method:
+
+::
+
+
+    my_engine = create_engine('postgresql://...')
+    pg_insp = Inspector.from_engine(my_engine)
+
+    print pg_insp.get_table_oid('my_table')
+
+RETURNING Support
+=================
+
+The ``insert()``, ``update()`` and ``delete()`` constructs
+now support a ``returning()`` method, which corresponds to
+the SQL RETURNING clause as supported by Postgresql, Oracle,
+MS-SQL, and Firebird.   It is not supported for any other
+backend at this time.
+
+Given a list of column expressions in the same manner as
+that of a ``select()`` construct, the values of these
+columns will be returned as a regular result set:
+
+::
+
+
+    result = connection.execute(
+                table.insert().values(data='some data').returning(table.c.id, table.c.timestamp)
+            )
+    row = result.first()
+    print "ID:", row['id'], "Timestamp:", row['timestamp']
+
+The implementation of RETURNING across the four supported
+backends varies wildly, in the case of Oracle requiring an
+intricate usage of OUT parameters which are re-routed into a
+"mock" result set, and in the case of MS-SQL using an
+awkward SQL syntax.  The usage of RETURNING is subject to
+limitations:
+
+* it does not work for any "executemany()" style of
+  execution.   This is a limitation of all supported DBAPIs.
+
+* Some backends, such as Oracle, only support RETURNING that
+  returns a single row - this includes UPDATE and DELETE
+  statements, meaning the update() or delete() construct
+  must match only a single row, or an error is raised (by
+  Oracle, not SQLAlchemy).
+
+RETURNING is also used automatically by SQLAlchemy, when
+available and when not otherwise specified by an explicit
+``returning()`` call, to fetch the value of newly generated
+primary key values for single-row INSERT statements.   This
+means there's no more "SELECT nextval(sequence)" pre-
+execution for insert statements where the primary key value
+is required.   Truth be told, implicit RETURNING feature
+does incur more method overhead than the old "select
+nextval()" system, which used a quick and dirty
+cursor.execute() to get at the sequence value, and in the
+case of Oracle requires additional binding of out
+parameters.  So if method/protocol overhead is proving to be
+more expensive than additional database round trips, the
+feature can be disabled by specifying
+``implicit_returning=False`` to ``create_engine()``.
+
+Type System Changes
+===================
+
+New Archicture
+--------------
+
+The type system has been completely reworked behind the
+scenes to provide two goals:
+
+* Separate the handling of bind parameters and result row
+  values, typically a DBAPI requirement, from the SQL
+  specification of the type itself, which is a database
+  requirement.   This is consistent with the overall dialect
+  refactor that separates database SQL behavior from DBAPI.
+
+* Establish a clear and consistent contract for generating
+  DDL from a ``TypeEngine`` object and for constructing
+  ``TypeEngine`` objects based on column reflection.
+
+Highlights of these changes include:
+
+* The construction of types within dialects has been totally
+  overhauled. Dialects now define publically available types
+  as UPPERCASE names exclusively, and internal
+  implementation types using underscore identifiers (i.e.
+  are private). The system by which types are expressed in
+  SQL and DDL has been moved to the compiler system. This
+  has the effect that there are much fewer type objects
+  within most dialects. A detailed document on this
+  architecture for dialect authors is in [source:/lib/sqlalc
+  hemy/dialects/type_migration_guidelines.txt].
+
+* Reflection of types now returns the exact UPPERCASE type
+  within types.py, or the UPPERCASE type within the dialect
+  itself if the type is not a standard SQL type. This means
+  reflection now returns more accurate information about
+  reflected types.
+
+* User defined types that subclass ``TypeEngine`` and wish
+  to provide ``get_col_spec()`` should now subclass
+  ``UserDefinedType``.
+
+* The ``result_processor()`` method on all type classes now
+  accepts an additional argument ``coltype``.   This is the
+  DBAPI type object attached to cursor.description, and
+  should be used when applicable to make better decisions on
+  what kind of result-processing callable should be
+  returned.  Ideally result processor functions would never
+  need to use ``isinstance()``, which is an expensive call
+  at this level.
+
+Native Unicode Mode
+-------------------
+
+As more DBAPIs support returning Python unicode objects
+directly, the base dialect now performs a check upon the
+first connection which establishes whether or not the DBAPI
+returns a Python unicode object for a basic select of a
+VARCHAR value.   If so, the ``String`` type and all
+subclasses (i.e. ``Text``, ``Unicode``, etc.) will skip the
+"unicode" check/conversion step when result rows are
+received.  This offers a dramatic performance increase for
+large result sets.  The "unicode mode" currently is known to
+work with:
+
+* sqlite3 / pysqlite
+
+
+* psycopg2 - SQLA 0.6 now uses the "UNICODE" type extension
+  by default on each psycopg2 connection object
+
+* pg8000
+
+
+* cx_oracle (we use an output processor - nice feature !)
+
+
+Other types may choose to disable unicode processing as
+needed, such as the ``NVARCHAR`` type when used with MS-SQL.
+
+In particular, if porting an application based on a DBAPI
+that formerly returned non-unicode strings, the "native
+unicode" mode has a plainly different default behavior -
+columns that are declared as ``String`` or ``VARCHAR`` now
+return unicode by default whereas they would return strings
+before.   This can break code which expects non-unicode
+strings.   The psycopg2 "native unicode" mode can be
+disabled by passing ``use_native_unicode=False`` to
+``create_engine()``.
+
+A more general solution for string columns that explicitly
+do not want a unicode object is to use a ``TypeDecorator``
+that converts unicode back to utf-8, or whatever is desired:
+
+::
+
+    class UTF8Encoded(TypeDecorator):
+        """Unicode type which coerces to utf-8."""
+
+        impl = sa.VARCHAR
+
+        def process_result_value(self, value, dialect):
+            if isinstance(value, unicode):
+                value = value.encode('utf-8')
+            return value
+
+Note that the ``assert_unicode`` flag is now deprecated.
+SQLAlchemy allows the DBAPI and backend database in use to
+handle Unicode parameters when available, and does not add
+operational overhead by checking the incoming type; modern
+systems like sqlite and Postgresql will raise an encoding
+error on their end if invalid data is passed.  In those
+cases where SQLAlchemy does need to coerce a bind parameter
+from Python Unicode to an encoded string, or when the
+Unicode type is used explicitly, a warning is raised if the
+object is a bytestring.   This warning can be suppressed or
+converted to an exception using the Python warnings filter
+documented at: http://docs.python.org/library/warnings.html
+
+Generic Enum Type
+-----------------
+
+We now have an ``Enum`` in the ``types`` module.  This is a
+string type that is given a collection of "labels" which
+constrain the possible values given to those labels.  By
+default, this type generates a ``VARCHAR`` using the size of
+the largest label, and applies a CHECK constraint to the
+table within the CREATE TABLE statement.   When using MySQL,
+the type by default uses MySQL's ENUM type, and when using
+Postgresql the type will generate a user defined type using
+``CREATE TYPE <mytype> AS ENUM``.  In order to create the
+type using Postgresql, the ``name`` parameter must be
+specified to the constructor.  The type also accepts a
+``native_enum=False`` option which will issue the
+VARCHAR/CHECK strategy for all databases.  Note that
+Postgresql ENUM types currently don't work with pg8000 or
+zxjdbc.
+
+Reflection Returns Dialect-Specific Types
+-----------------------------------------
+
+Reflection now returns the most specific type possible from
+the database. That is, if you create a table using
+``String``, then reflect it back, the reflected column will
+likely be ``VARCHAR``. For dialects that support a more
+specific form of the type, that's what you'll get. So a
+``Text`` type would come back as ``oracle.CLOB`` on Oracle,
+a ``LargeBinary`` might be an ``mysql.MEDIUMBLOB`` etc. The
+obvious advantage here is that reflection preserves as much
+information possible from what the database had to say.
+
+Some applications that deal heavily in table metadata may
+wish to compare types across reflected tables and/or non-
+reflected tables.  There's a semi-private accessor available
+on ``TypeEngine`` called ``_type_affinity`` and an
+associated comparison helper ``_compare_type_affinity``.
+This accessor returns the "generic" ``types`` class which
+the type corresponds to:
+
+::
+
+    >>> String(50)._compare_type_affinity(postgresql.VARCHAR(50))
+    True
+    >>> Integer()._compare_type_affinity(mysql.REAL)
+    False
+
+Miscellaneous API Changes
+-------------------------
+
+The usual "generic" types are still the general system in
+use, i.e. ``String``, ``Float``, ``DateTime``.   There's a
+few changes there:
+
+* Types no longer make any guesses as to default parameters.
+  In particular, ``Numeric``, ``Float``, as well as
+  subclasses NUMERIC, FLOAT, DECIMAL don't generate any
+  length or scale unless specified.   This also continues to
+  include the controversial ``String`` and ``VARCHAR`` types
+  (although MySQL dialect will pre-emptively raise when
+  asked to render VARCHAR with no length).   No defaults are
+  assumed, and if they are used in a CREATE TABLE statement,
+  an error will be raised if the underlying database does
+  not allow non-lengthed versions of these types.
+
+* the ``Binary`` type has been renamed to ``LargeBinary``,
+  for BLOB/BYTEA/similar types.  For ``BINARY`` and
+  ``VARBINARY``, those are present directly as
+  ``types.BINARY``, ``types.VARBINARY``, as well as in the
+  MySQL and MS-SQL dialects.
+
+* ``PickleType`` now uses == for comparison of values when
+  mutable=True, unless the "comparator" argument with a
+  comparison function is specified to the type.   If you are
+  pickling a custom object you should implement an
+  ``__eq__()`` method so that value-based comparisons are
+  accurate.
+
+* The default "precision" and "scale" arguments of Numeric
+  and Float have been removed and now default to None.
+  NUMERIC and FLOAT will be rendered with no numeric
+  arguments by default unless these values are provided.
+
+* DATE, TIME and DATETIME types on SQLite can now take
+  optional "storage_format" and "regexp" argument.
+  "storage_format" can be used to store those types using a
+  custom string format. "regexp" allows to use a custom
+  regular expression to match string values from the
+  database.
+
+* ``__legacy_microseconds__`` on SQLite ``Time`` and
+  ``DateTime`` types is not supported anymore. You should
+  use the new "storage_format" argument instead.
+
+* ``DateTime`` types on SQLite now use by a default a
+  stricter regular expression to match strings from the
+  database. Use the new "regexp" argument if you are using
+  data stored in a legacy format.
+
+ORM Changes
+===========
+
+Upgrading an ORM application from 0.5 to 0.6 should require
+little to no changes, as the ORM's behavior remains almost
+identical.   There are some default argument and name
+changes, and some loading behaviors have been improved.
+
+New Unit of Work
+----------------
+
+The internals for the unit of work, primarily
+``topological.py`` and ``unitofwork.py``, have been
+completely rewritten and are vastly simplified.   This
+should have no impact on usage, as all existing behavior
+during flush has been maintained exactly (or at least, as
+far as it is exercised by our testsuite and the handful of
+production environments which have tested it heavily).  The
+performance of flush() now uses 20-30% fewer method calls
+and should also use less memory.  The intent and flow of the
+source code should now be reasonably easy to follow, and the
+architecture of the flush is fairly open-ended at this
+point, creating room for potential new areas of
+sophistication.   The flush process no longer has any
+reliance on recursion so flush plans of arbitrary size and
+complexity can be flushed.  Additionally, the mapper's
+"save" process, which issues INSERT and UPDATE statements,
+now caches the "compiled" form of the two statements so that
+callcounts are further dramatically reduced with very large
+flushes.
+
+Any changes in behavior observed with flush versus earlier
+versions of 0.6 or 0.5 should be reported to us ASAP - we'll
+make sure no functionality is lost.
+
+Changes to ``query.update()`` and ``query.delete()``
+----------------------------------------------------
+
+* the 'expire' option on query.update() has been renamed to
+  'fetch', thus matching that of query.delete()
+
+* ``query.update()`` and ``query.delete()`` both default to
+  'evaluate' for the synchronize strategy.
+
+* the 'synchronize' strategy for update() and delete()
+  raises an error on failure. There is no implicit fallback
+  onto "fetch". Failure of evaluation is based on the
+  structure of criteria, so success/failure is deterministic
+  based on code structure.
+
+``relation()`` is officially named ``relationship()``
+-----------------------------------------------------
+
+This to solve the long running issue that "relation" means a
+"table or derived table" in relational algebra terms.  The
+``relation()`` name, which is less typing, will hang around
+for the foreseeable future so this change should be entirely
+painless.
+
+Subquery eager loading
+----------------------
+
+A new kind of eager loading is added called "subquery"
+loading.   This is a load that emits a second SQL query
+immediately after the first which loads full collections for
+all the parents in the first query, joining upwards to the
+parent using INNER JOIN.   Subquery loading is used simlarly
+to the current joined-eager loading, using the
+```subqueryload()```` and ````subqueryload_all()```` options
+as well as the ````lazy='subquery'```` setting on
+````relationship()```.   The subquery load is usually much
+more efficient for loading many larger collections as it
+uses INNER JOIN unconditionally and also doesn't re-load
+parent rows.
+
+```eagerload()````, ````eagerload_all()```` is now ````joinedload()````, ````joinedload_all()```
+------------------------------------------------------------------------------------------------
+
+To make room for the new subquery load feature, the existing
+```eagerload()````/````eagerload_all()```` options are now
+superceded by ````joinedload()```` and
+````joinedload_all()````.   The old names will hang around
+for the foreseeable future just like ````relation()```.
+
+```lazy=False|None|True|'dynamic'```` now accepts ````lazy='noload'|'joined'|'subquery'|'select'|'dynamic'```
+-------------------------------------------------------------------------------------------------------------
+
+Continuing on the theme of loader strategies opened up, the
+standard keywords for the ```lazy```` option on
+````relationship()```` are now ````select```` for lazy
+loading (via a SELECT issued on attribute access),
+````joined```` for joined-eager loading, ````subquery````
+for subquery-eager loading, ````noload```` for no loading
+should occur, and ````dynamic```` for a "dynamic"
+relationship.   The old ````True````, ````False````,
+````None``` arguments are still accepted with the identical
+behavior as before.
+
+innerjoin=True on relation, joinedload
+--------------------------------------
+
+Joined-eagerly loaded scalars and collections can now be
+instructed to use INNER JOIN instead of OUTER JOIN.   On
+Postgresql this is observed to provide a 300-600% speedup on
+some queries.   Set this flag for any many-to-one which is
+on a NOT NULLable foreign key, and similarly for any
+collection where related items are guaranteed to exist.
+
+At mapper level:
+
+::
+
+    mapper(Child, child)
+    mapper(Parent, parent, properties={
+        'child':relationship(Child, lazy='joined', innerjoin=True)
+    })
+
+At query time level:
+
+::
+
+    session.query(Parent).options(joinedload(Parent.child, innerjoin=True)).all()
+
+The ``innerjoin=True`` flag at the ``relationship()`` level
+will also take effect for any ``joinedload()`` option which
+does not override the value.
+
+Many-to-one Enhancements
+------------------------
+
+* many-to-one relations now fire off a lazyload in fewer
+  cases, including in most cases will not fetch the "old"
+  value when a new one is replaced.
+
+* many-to-one relation to a joined-table subclass now uses
+  get() for a simple load (known as the "use_get"
+  condition), i.e. ``Related``->``Sub(Base)``, without the
+  need to redefine the primaryjoin condition in terms of the
+  base table. [ticket:1186]
+
+* specifying a foreign key with a declarative column, i.e.
+  ``ForeignKey(MyRelatedClass.id)`` doesn't break the
+  "use_get" condition from taking place [ticket:1492]
+
+* relationship(), joinedload(), and joinedload_all() now
+  feature an option called "innerjoin". Specify ``True`` or
+  ``False`` to control whether an eager join is constructed
+  as an INNER or OUTER join. Default is ``False`` as always.
+  The mapper options will override whichever setting is
+  specified on relationship(). Should generally be set for
+  many-to-one, not nullable foreign key relations to allow
+  improved join performance. [ticket:1544]
+
+* the behavior of joined eager loading such that the main
+  query is wrapped in a subquery when LIMIT/OFFSET are
+  present now makes an exception for the case when all eager
+  loads are many-to-one joins. In those cases, the eager
+  joins are against the parent table directly along with the
+  limit/offset without the extra overhead of a subquery,
+  since a many-to-one join does not add rows to the result.
+
+  For example, in 0.5 this query:
+
+  ::
+
+      session.query(Address).options(eagerload(Address.user)).limit(10)
+
+  would produce SQL like:
+
+  ::
+
+      SELECT * FROM
+        (SELECT * FROM addresses LIMIT 10) AS anon_1
+        LEFT OUTER JOIN users AS users_1 ON users_1.id = anon_1.addresses_user_id
+
+  This because the presence of any eager loaders suggests
+  that some or all of them may relate to multi-row
+  collections, which would necessitate wrapping any kind of
+  rowcount-sensitive modifiers like LIMIT inside of a
+  subquery.
+
+  In 0.6, that logic is more sensitive and can detect if all
+  eager loaders represent many-to-ones, in which case the
+  eager joins don't affect the rowcount:
+
+  ::
+
+      SELECT * FROM addresses LEFT OUTER JOIN users AS users_1 ON users_1.id = addresses.user_id LIMIT 10
+
+Mutable Primary Keys with Joined Table Inheritance
+--------------------------------------------------
+
+A joined table inheritance config where the child table has
+a PK that foreign keys to the parent PK can now be updated
+on a CASCADE-capable database like Postgresql.
+``mapper()`` now has an option ``passive_updates=True``
+which indicates this foreign key is updated automatically.
+If on a non-cascading database like SQLite or MySQL/MyISAM,
+set this flag to ``False``.  A future feature enhancement
+will try to get this flag to be auto-configuring based on
+dialect/table style in use.
+
+Beaker Caching
+--------------
+
+A promising new example of Beaker integration is in
+``examples/beaker_caching``.   This is a straightforward
+recipe which applies a Beaker cache within the result-
+generation engine of ``Query``.  Cache parameters are
+provided via ``query.options()``, and allows full control
+over the contents of the cache.   SQLAlchemy 0.6 includes
+improvements to the ``Session.merge()`` method to support
+this and similar recipes, as well as to provide
+significantly improved performance in most scenarios.
+
+Other Changes
+-------------
+
+* the "row tuple" object returned by ``Query`` when multiple
+  column/entities are selected is now picklable as well as
+  higher performing.
+
+* ``query.join()`` has been reworked to provide more
+  consistent behavior and more flexibility (includes
+  [ticket:1537])
+
+* ``query.select_from()`` accepts multiple clauses to
+  produce multiple comma separated entries within the FROM
+  clause. Useful when selecting from multiple-homed join()
+  clauses.
+
+* the "dont_load=True" flag on ``Session.merge()`` is
+  deprecated and is now "load=False".
+
+* added "make_transient()" helper function which transforms
+  a persistent/ detached instance into a transient one (i.e.
+  deletes the instance_key and removes from any session.)
+  [ticket:1052]
+
+* the allow_null_pks flag on mapper() is deprecated and has
+  been renamed to allow_partial_pks.   It is turned "on" by
+  default.  This means that a row which has a non-null value
+  for any of its primary key columns will be considered an
+  identity. The need for this scenario typically only occurs
+  when mapping to an outer join.  When set to False, a PK
+  that has NULLs in it will not be considered a primary key
+  - in particular this means a result row will come back as
+  None (or not be filled into a collection), and new in 0.6
+  also indicates that session.merge() won't issue a round
+  trip to the database for such a PK value. [ticket:1680]
+
+* the mechanics of "backref" have been fully merged into the
+  finer grained "back_populates" system, and take place
+  entirely within the ``_generate_backref()`` method of
+  ``RelationProperty``. This makes the initialization
+  procedure of ``RelationProperty`` simpler and allows
+  easier propagation of settings (such as from subclasses of
+  ``RelationProperty``) into the reverse reference. The
+  internal ``BackRef()`` is gone and ``backref()`` returns a
+  plain tuple that is understood by ``RelationProperty``.
+
+* the keys attribute of ``ResultProxy`` is now a method, so
+  references to it (``result.keys``) must be changed to
+  method invocations (``result.keys()``)
+
+* ``ResultProxy.last_inserted_ids`` is now deprecated, use
+  ``ResultProxy.inserted_primary_key`` instead.
+
+Deprecated/Removed ORM Elements
+-------------------------------
+
+Most elements that were deprecated throughout 0.5 and raised
+deprecation warnings have been removed (with a few
+exceptions).  All elements that were marked "pending
+deprecation" are now deprecated and will raise a warning
+upon use.
+
+* 'transactional' flag on sessionmaker() and others is
+  removed. Use 'autocommit=True' to indicate
+  'transactional=False'.
+
+* 'polymorphic_fetch' argument on mapper() is removed.
+  Loading can be controlled using the 'with_polymorphic'
+  option.
+
+* 'select_table' argument on mapper() is removed.  Use
+  'with_polymorphic=("*", <some selectable>)' for this
+  functionality.
+
+* 'proxy' argument on synonym() is removed.  This flag   did
+  nothing throughout 0.5, as the "proxy generation"
+  behavior is now automatic.
+
+* Passing a single list of elements to joinedload(),
+  joinedload_all(), contains_eager(), lazyload(),   defer(),
+  and undefer() instead of multiple positional   \*args is
+  deprecated.
+
+* Passing a single list of elements to query.order_by(),
+  query.group_by(), query.join(), or query.outerjoin()
+  instead of multiple positional \*args is deprecated.
+
+* ``query.iterate_instances()`` is removed.  Use
+  ``query.instances()``.
+
+* ``Query.query_from_parent()`` is removed.  Use the
+  sqlalchemy.orm.with_parent() function to produce a
+  "parent" clause, or alternatively ``query.with_parent()``.
+
+* ``query._from_self()`` is removed, use
+  ``query.from_self()``   instead.
+
+* the "comparator" argument to composite() is removed.   Use
+  "comparator_factory".
+
+* ``RelationProperty._get_join()`` is removed.
+
+
+* the 'echo_uow' flag on Session is removed.  Use   logging
+  on the "sqlalchemy.orm.unitofwork" name.
+
+* ``session.clear()`` is removed.  use
+  ``session.expunge_all()``.
+
+* ``session.save()``, ``session.update()``,
+  ``session.save_or_update()``   are removed.  Use
+  ``session.add()`` and ``session.add_all()``.
+
+* the "objects" flag on session.flush() remains deprecated.
+
+
+* the "dont_load=True" flag on session.merge() is deprecated
+  in favor of "load=False".
+
+* ``ScopedSession.mapper`` remains deprecated.  See the
+  usage recipe at   http://www.sqlalchemy.org/trac/wiki/Usag
+  eRecipes/SessionAwareMapper
+
+* passing an ``InstanceState`` (internal SQLAlchemy state
+  object) to   ``attributes.init_collection()`` or
+  ``attributes.get_history()`` is   deprecated.  These
+  functions are public API and normally   expect a regular
+  mapped object instance.
+
+* the 'engine' parameter to ``declarative_base()`` is
+  removed.   Use the 'bind' keyword argument.
+
+Extensions
+==========
+
+SQLSoup
+-------
+
+SQLSoup has been modernized and updated to reflect common
+0.5/0.6 capabilities, including well defined session
+integration.  Please read the new docs at [http://www.sqlalc
+hemy.org/docs/06/reference/ext/sqlsoup.html].
+
+Declarative
+-----------
+
+The ``DeclarativeMeta`` (default metaclass for
+``declarative_base``) previously allowed subclasses to
+modify ``dict_`` to add class attributes (e.g. columns).
+This no longer works, the ``DeclarativeMeta`` constructor
+now ignores ``dict_``. Instead, the class attributes should
+be assigned directly, e.g. ``cls.id=Column(...)``, or the
+`MixIn class <http://www.sqlalchemy.org/docs/reference/ext/d
+eclarative.html#mix-in-classes>`_ approach should be used
+instead of the metaclass approach.
+
diff --git a/doc/build/changelog/migration_07.rst b/doc/build/changelog/migration_07.rst
new file mode 100644 (file)
index 0000000..810b412
--- /dev/null
@@ -0,0 +1,1360 @@
+==============================
+What's New in SQLAlchemy 0.7 ?
+==============================
+
+.. admonition:: About this Document
+
+    This document describes changes between SQLAlchemy version 0.6,
+    last released May 5, 2012, and SQLAlchemy version 0.7,
+    undergoing maintenance releases as of October, 2012.
+
+    Document date: July 27, 2011
+
+Introduction
+============
+
+This guide introduces what's new in SQLAlchemy version 0.7,
+and also documents changes which affect users migrating
+their applications from the 0.6 series of SQLAlchemy to 0.7.
+
+To as great a degree as possible, changes are made in such a
+way as to not break compatibility with applications built
+for 0.6.   The changes that are necessarily not backwards
+compatible are very few, and all but one, the change to
+mutable attribute defaults, should affect an exceedingly
+small portion of applications - many of the changes regard
+non-public APIs and undocumented hacks some users may have
+been attempting to use.
+
+A second, even smaller class of non-backwards-compatible
+changes is also documented. This class of change regards
+those features and behaviors that have been deprecated at
+least since version 0.5 and have been raising warnings since
+their deprecation. These changes would only affect
+applications that are still using 0.4- or early 0.5-style
+APIs. As the project matures, we have fewer and fewer of
+these kinds of changes with 0.x level releases, which is a
+product of our API having ever fewer features that are less
+than ideal for the use cases they were meant to solve.
+
+An array of existing functionalities have been superseded in
+SQLAlchemy 0.7.  There's not much difference between the
+terms "superseded" and "deprecated", except that the former
+has a much weaker suggestion of the old feature would ever
+be removed. In 0.7, features like ``synonym`` and
+``comparable_property``, as well as all the ``Extension``
+and other event classes, have been superseded.  But these
+"superseded" features have been re-implemented such that
+their implementations live mostly outside of core ORM code,
+so their continued "hanging around" doesn't impact
+SQLAlchemy's ability to further streamline and refine its
+internals, and we expect them to remain within the API for
+the foreseeable future.
+
+New Features
+============
+
+New Event System
+----------------
+
+SQLAlchemy started early with the ``MapperExtension`` class,
+which provided hooks into the persistence cycle of mappers.
+As SQLAlchemy quickly became more componentized, pushing
+mappers into a more focused configurational role, many more
+"extension", "listener", and "proxy" classes popped up to
+solve various activity-interception use cases in an ad-hoc
+fashion.   Part of this was driven by the divergence of
+activities; ``ConnectionProxy`` objects wanted to provide a
+system of rewriting statements and parameters;
+``AttributeExtension`` provided a system of replacing
+incoming values, and ``DDL`` objects had events that could
+be switched off of dialect-sensitive callables.
+
+0.7 re-implements virtually all of these plugin points with
+a new, unified approach, which retains all the
+functionalities of the different systems, provides more
+flexibility and less boilerplate, performs better, and
+eliminates the need to learn radically different APIs for
+each event subsystem.  The pre-existing classes
+``MapperExtension``, ``SessionExtension``,
+``AttributeExtension``, ``ConnectionProxy``,
+``PoolListener`` as well as the ``DDLElement.execute_at``
+method are deprecated and now implemented in terms of the
+new system - these APIs remain fully functional and are
+expected to remain in place for the foreseeable future.
+
+The new approach uses named events and user-defined
+callables to associate activities with events. The API's
+look and feel was driven by such diverse sources as JQuery,
+Blinker, and Hibernate, and was also modified further on
+several occasions during conferences with dozens of users on
+Twitter, which appears to have a much higher response rate
+than the mailing list for such questions.
+
+It also features an open-ended system of target
+specification that allows events to be associated with API
+classes, such as for all ``Session`` or ``Engine`` objects,
+with specific instances of API classes, such as for a
+specific ``Pool`` or ``Mapper``, as well as for related
+objects like a user- defined class that's mapped, or
+something as specific as a certain attribute on instances of
+a particular subclass of a mapped parent class. Individual
+listener subsystems can apply wrappers to incoming user-
+defined listener functions which modify how they are called
+- an mapper event can receive either the instance of the
+object being operated upon, or its underlying
+``InstanceState`` object. An attribute event can opt whether
+or not to have the responsibility of returning a new value.
+
+Several systems now build upon the new event API, including
+the new "mutable attributes" API as well as composite
+attributes. The greater emphasis on events has also led to
+the introduction of a handful of new events, including
+attribute expiration and refresh operations, pickle
+loads/dumps operations, completed mapper construction
+operations.
+
+.. seealso::
+
+  :ref:`event_toplevel`
+
+:ticket:`1902`
+
+Hybrid Attributes, implements/supersedes synonym(), comparable_property()
+-------------------------------------------------------------------------
+
+The "derived attributes" example has now been turned into an
+official extension.   The typical use case for ``synonym()``
+is to provide descriptor access to a mapped column; the use
+case for ``comparable_property()`` is to be able to return a
+``PropComparator`` from any descriptor.   In practice, the
+approach of "derived" is easier to use, more extensible, is
+implemented in a few dozen lines of pure Python with almost
+no imports, and doesn't require the ORM core to even be
+aware of it.   The feature is now known as the "Hybrid
+Attributes" extension.
+
+``synonym()`` and ``comparable_property()`` are still part
+of the ORM, though their implementations have been moved
+outwards, building on an approach that is similar to that of
+the hybrid extension, so that the core ORM
+mapper/query/property modules aren't really aware of them
+otherwise.
+
+.. seealso::
+
+  :ref:`hybrids_toplevel`
+
+:ticket:`1903`
+
+Speed Enhancements
+------------------
+
+As is customary with all major SQLA releases, a wide pass
+through the internals to reduce overhead and callcounts has
+been made which further reduces the work needed in common
+scenarios. Highlights of this release include:
+
+* The flush process will now bundle INSERT statements into
+  batches fed   to ``cursor.executemany()``, for rows where
+  the primary key is already   present.   In particular this
+  usually applies to the "child" table on a joined   table
+  inheritance configuration, meaning the number of calls to
+  ``cursor.execute``   for a large bulk insert of joined-
+  table objects can be cut in half, allowing   native DBAPI
+  optimizations to take place for those statements passed
+  to ``cursor.executemany()`` (such as re-using a prepared
+  statement).
+
+* The codepath invoked when accessing a many-to-one
+  reference to a related object   that's already loaded has
+  been greatly simplified.  The identity map is checked
+  directly without the need to generate a new ``Query``
+  object first, which is   expensive in the context of
+  thousands of in-memory many-to-ones being accessed.   The
+  usage of constructed-per-call "loader" objects is also no
+  longer used for   the majority of lazy attribute loads.
+
+* The rewrite of composites allows a shorter codepath when
+  mapper internals   access mapped attributes within a
+  flush.
+
+* New inlined attribute access functions replace the
+  previous usage of   "history" when the "save-update" and
+  other cascade operations need to   cascade among the full
+  scope of datamembers associated with an attribute.   This
+  reduces the overhead of generating a new ``History``
+  object for this speed-critical   operation.
+
+* The internals of the ``ExecutionContext``, the object
+  corresponding to a statement   execution, have been
+  inlined and simplified.
+
+* The ``bind_processor()`` and ``result_processor()``
+  callables generated by types   for each statement
+  execution are now cached (carefully, so as to avoid memory
+  leaks for ad-hoc types and dialects) for the lifespan of
+  that type, further   reducing per-statement call overhead.
+
+* The collection of "bind processors" for a particular
+  ``Compiled`` instance of   a statement is also cached on
+  the ``Compiled`` object, taking further   advantage of the
+  "compiled cache" used by the flush process to re-use the
+  same   compiled form of INSERT, UPDATE, DELETE statements.
+
+A demonstration of callcount reduction including a sample
+benchmark script is at
+http://techspot.zzzeek.org/2010/12/12/a-tale-of-three-
+profiles/
+
+Composites Rewritten
+--------------------
+
+The "composite" feature has been rewritten, like
+``synonym()`` and ``comparable_property()``, to use a
+lighter weight implementation based on descriptors and
+events, rather than building into the ORM internals.  This
+allowed the removal of some latency from the mapper/unit of
+work internals, and simplifies the workings of composite.
+The composite attribute now no longer conceals the
+underlying columns it builds upon, which now remain as
+regular attributes.  Composites can also act as a proxy for
+``relationship()`` as well as ``Column()`` attributes.
+
+The major backwards-incompatible change of composites is
+that they no longer use the ``mutable=True`` system to
+detect in-place mutations.   Please use the `Mutation
+Tracking <http://www.sqlalchemy.org/docs/07/orm/extensions/m
+utable.html>`_ extension to establish in-place change events
+to existing composite usage.
+
+.. seealso::
+
+  :ref:`mapper_composite`
+
+  :ref:`mutable_toplevel`
+
+:ticket:`2008` :ticket:`2024`
+
+More succinct form of query.join(target, onclause)
+--------------------------------------------------
+
+The default method of issuing ``query.join()`` to a target
+with an explicit onclause is now:
+
+::
+
+    query.join(SomeClass, SomeClass.id==ParentClass.some_id)
+
+In 0.6, this usage was considered to be an error, because
+``join()`` accepts multiple arguments corresponding to
+multiple JOIN clauses - the two-argument form needed to be
+in a tuple to disambiguate between single-argument and two-
+argument join targets.  In the middle of 0.6 we added
+detection and an error message for this specific calling
+style, since it was so common.  In 0.7, since we are
+detecting the exact pattern anyway, and since having to type
+out a tuple for no reason is extremely annoying, the non-
+tuple method now becomes the "normal" way to do it.  The
+"multiple JOIN" use case is exceedingly rare compared to the
+single join case, and multiple joins these days are more
+clearly represented by multiple calls to ``join()``.
+
+The tuple form will remain for backwards compatibility.
+
+Note that all the other forms of ``query.join()`` remain
+unchanged:
+
+::
+
+    query.join(MyClass.somerelation)
+    query.join("somerelation")
+    query.join(MyTarget)
+    # ... etc
+
+`Querying with Joins
+<http://www.sqlalchemy.org/docs/07/orm/tutorial.html
+#querying-with-joins>`_
+
+:ticket:`1923`
+
+Mutation event extension, supersedes "mutable=True"
+---------------------------------------------------
+
+A new extension, `Mutation Tracking <http://www.sqlalchemy.o
+rg/docs/07/orm/extensions/mutable.html>`_, provides a
+mechanism by which user-defined datatypes can provide change
+events back to the owning parent or parents.   The extension
+includes an approach for scalar database values, such as
+those managed by ``PickleType``, ``postgresql.ARRAY``, or
+other custom ``MutableType`` classes, as well as an approach
+for ORM "composites", those configured using :ref:`composite()
+<mapper_composite>`_.
+
+.. seealso::
+
+    :ref:`mutable_toplevel`
+
+NULLS FIRST / NULLS LAST operators
+----------------------------------
+
+These are implemented as an extension to the ``asc()`` and
+``desc()`` operators, called ``nullsfirst()`` and
+``nullslast()``.
+
+.. seealso::
+
+    :func:`.nullsfirst`
+
+    :func:`.nullslast`
+
+:ticket:`723`
+
+select.distinct(), query.distinct() accepts \*args for Postgresql DISTINCT ON
+-----------------------------------------------------------------------------
+
+This was already available by passing a list of expressions
+to the ``distinct`` keyword argument of ``select()``, the
+``distinct()`` method of ``select()`` and ``Query`` now
+accept positional arguments which are rendered as DISTINCT
+ON when a Postgresql backend is used.
+
+`distinct() <http://www.sqlalchemy.org/docs/07/core/expressi
+on_api.html#sqlalchemy.sql.expression.Select.distinct>`_
+
+`Query.distinct() <http://www.sqlalchemy.org/docs/07/orm/que
+ry.html#sqlalchemy.orm.query.Query.distinct>`_
+
+:ticket:`1069`
+
+``Index()`` can be placed inline inside of ``Table``, ``__table_args__``
+------------------------------------------------------------------------
+
+The Index() construct can be created inline with a Table
+definition, using strings as column names, as an alternative
+to the creation of the index outside of the Table.  That is:
+
+::
+
+    Table('mytable', metadata,
+            Column('id',Integer, primary_key=True),
+            Column('name', String(50), nullable=False),
+            Index('idx_name', 'name')
+    )
+
+The primary rationale here is for the benefit of declarative
+``__table_args__``, particularly when used with mixins:
+
+::
+
+    class HasNameMixin(object):
+        name = Column('name', String(50), nullable=False)
+        @declared_attr
+        def __table_args__(cls):
+            return (Index('name'), {})
+
+    class User(HasNameMixin, Base):
+        __tablename__ = 'user'
+        id = Column('id', Integer, primary_key=True)
+
+`Indexes <http://www.sqlalchemy.org/docs/07/core/schema.html
+#indexes>`_
+
+Window Function SQL Construct
+-----------------------------
+
+A "window function" provides to a statement information
+about the result set as it's produced. This allows criteria
+against various things like "row number", "rank" and so
+forth. They are known to be supported at least by
+Postgresql, SQL Server and Oracle, possibly others.
+
+The best introduction to window functions is on Postgresql's
+site, where window functions have been supported since
+version 8.4:
+
+http://www.postgresql.org/docs/9.0/static/tutorial-
+window.html
+
+SQLAlchemy provides a simple construct typically invoked via
+an existing function clause, using the ``over()`` method,
+which accepts ``order_by`` and ``partition_by`` keyword
+arguments. Below we replicate the first example in PG's
+tutorial:
+
+::
+
+    from sqlalchemy.sql import table, column, select, func
+
+    empsalary = table('empsalary',
+                    column('depname'),
+                    column('empno'),
+                    column('salary'))
+
+    s = select([
+            empsalary,
+            func.avg(empsalary.c.salary).
+                  over(partition_by=empsalary.c.depname).
+                  label('avg')
+        ])
+
+    print s
+
+SQL:
+
+::
+
+    SELECT empsalary.depname, empsalary.empno, empsalary.salary,
+    avg(empsalary.salary) OVER (PARTITION BY empsalary.depname) AS avg
+    FROM empsalary
+
+`sqlalchemy.sql.expression.over <http://www.sqlalchemy.org/d
+ocs/07/core/expression_api.html#sqlalchemy.sql.expression.ov
+er>`_
+
+:ticket:`1844`
+
+execution_options() on Connection accepts "isolation_level" argument
+--------------------------------------------------------------------
+
+This sets the transaction isolation level for a single
+``Connection``, until that ``Connection`` is closed and its
+underlying DBAPI resource returned to the connection pool,
+upon which the isolation level is reset back to the default.
+The default isolation level is set using the
+``isolation_level`` argument to ``create_engine()``.
+
+Transaction isolation support is currently only supported by
+the Postgresql and SQLite backends.
+
+`execution_options() <http://www.sqlalchemy.org/docs/07/core
+/connections.html#sqlalchemy.engine.base.Connection.executio
+n_options>`_
+
+:ticket:`2001`
+
+``TypeDecorator`` works with integer primary key columns
+--------------------------------------------------------
+
+A ``TypeDecorator`` which extends the behavior of
+``Integer`` can be used with a primary key column.  The
+"autoincrement" feature of ``Column`` will now recognize
+that the underlying database column is still an integer so
+that lastrowid mechanisms continue to function.   The
+``TypeDecorator`` itself will have its result value
+processor applied to newly generated primary keys, including
+those received by the DBAPI ``cursor.lastrowid`` accessor.
+
+:ticket:`2005` :ticket:`2006`
+
+``TypeDecorator`` is present in the "sqlalchemy" import space
+-------------------------------------------------------------
+
+No longer need to import this from ``sqlalchemy.types``,
+it's now mirrored in ``sqlalchemy``.
+
+New Dialects
+------------
+
+Dialects have been added:
+
+* a MySQLdb driver for the Drizzle database:
+
+
+  `Drizzle <http://www.sqlalchemy.org/docs/07/dialects/drizz
+  le.html>`_
+
+* support for the pymysql DBAPI:
+
+
+  `pymsql Notes
+  <http://www.sqlalchemy.org/docs/07/dialects/mysql.html
+  #module-sqlalchemy.dialects.mysql.pymysql>`_
+
+* psycopg2 now works with Python 3
+
+
+Behavioral Changes (Backwards Compatible)
+=========================================
+
+C Extensions Build by Default
+-----------------------------
+
+This is as of 0.7b4.   The exts will build if cPython 2.xx
+is detected.   If the build fails, such as on a windows
+install, that condition is caught and the non-C install
+proceeds.    The C exts won't build if Python 3 or Pypy is
+used.
+
+Query.count() simplified, should work virtually always
+------------------------------------------------------
+
+The very old guesswork which occurred within
+``Query.count()`` has been modernized to use
+``.from_self()``.  That is, ``query.count()`` is now
+equivalent to:
+
+::
+
+    query.from_self(func.count(literal_column('1'))).scalar()
+
+Previously, internal logic attempted to rewrite the columns
+clause of the query itself, and upon detection of a
+"subquery" condition, such as a column-based query that
+might have aggregates in it, or a query with DISTINCT, would
+go through a convoluted process of rewriting the columns
+clause.   This logic failed in complex conditions,
+particularly those involving joined table inheritance, and
+was long obsolete by the more comprehensive ``.from_self()``
+call.
+
+The SQL emitted by ``query.count()`` is now always of the
+form:
+
+::
+
+    SELECT count(1) AS count_1 FROM (
+        SELECT user.id AS user_id, user.name AS user_name from user
+    ) AS anon_1
+
+that is, the original query is preserved entirely inside of
+a subquery, with no more guessing as to how count should be
+applied.
+
+:ticket:`2093`
+
+To emit a non-subquery form of count()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+MySQL users have already reported that the MyISAM engine not
+surprisingly falls over completely with this simple change.
+Note that for a simple ``count()`` that optimizes for DBs
+that can't handle simple subqueries, ``func.count()`` should
+be used:
+
+::
+
+    from sqlalchemy import func
+    session.query(func.count(MyClass.id)).scalar()
+
+or for ``count(*)``:
+
+::
+
+    from sqlalchemy import func, literal_column
+    session.query(func.count(literal_column('*'))).select_from(MyClass).scalar()
+
+LIMIT/OFFSET clauses now use bind parameters
+--------------------------------------------
+
+The LIMIT and OFFSET clauses, or their backend equivalents
+(i.e. TOP, ROW NUMBER OVER, etc.), use bind parameters for
+the actual values, for all backends which support it (most
+except for Sybase).  This allows better query optimizer
+performance as the textual string for multiple statements
+with differing LIMIT/OFFSET are now identical.
+
+:ticket:`805`
+
+Logging enhancements
+--------------------
+
+Vinay Sajip has provided a patch to our logging system such
+that the "hex string" embedded in logging statements for
+engines and pools is no longer needed to allow the ``echo``
+flag to work correctly.  A new system that uses filtered
+logging objects allows us to maintain our current behavior
+of ``echo`` being local to individual engines without the
+need for additional identifying strings local to those
+engines.
+
+:ticket:`1926`
+
+Simplified polymorphic_on assignment
+------------------------------------
+
+The population of the ``polymorphic_on`` column-mapped
+attribute, when used in an inheritance scenario, now occurs
+when the object is constructed, i.e. its ``__init__`` method
+is called, using the init event.  The attribute then behaves
+the same as any other column-mapped attribute.   Previously,
+special logic would fire off during flush to populate this
+column, which prevented any user code from modifying its
+behavior.   The new approach improves upon this in three
+ways: 1. the polymorphic identity is now present on the
+object as soon as its constructed; 2. the polymorphic
+identity can be changed by user code without any difference
+in behavior from any other column-mapped attribute; 3. the
+internals of the mapper during flush are simplified and no
+longer need to make special checks for this column.
+
+:ticket:`1895`
+
+contains_eager() chains across multiple paths (i.e. "all()")
+------------------------------------------------------------
+
+The ```contains_eager()```` modifier now will chain itself
+for a longer path without the need to emit individual
+````contains_eager()``` calls. Instead of:
+
+::
+
+    session.query(A).options(contains_eager(A.b), contains_eager(A.b, B.c))
+
+you can say:
+
+::
+
+    session.query(A).options(contains_eager(A.b, B.c))
+
+:ticket:`2032`
+
+Flushing of orphans that have no parent is allowed
+--------------------------------------------------
+
+We've had a long standing behavior that checks for a so-
+called "orphan" during flush, that is, an object which is
+associated with a ``relationship()`` that specifies "delete-
+orphan" cascade, has been newly added to the session for an
+INSERT, and no parent relationship has been established.
+This check was added years ago to accommodate some test
+cases which tested the orphan behavior for consistency.   In
+modern SQLA, this check is no longer needed on the Python
+side.   The equivalent behavior of the "orphan check" is
+accomplished by making the foreign key reference to the
+object's parent row NOT NULL, where the database does its
+job of establishing data consistency in the same way SQLA
+allows most other operations to do.   If the object's parent
+foreign key is nullable, then the row can be inserted.   The
+"orphan" behavior runs when the object was persisted with a
+particular parent, and is then disassociated with that
+parent, leading to a DELETE statement emitted for it.
+
+:ticket:`1912`
+
+Warnings generated when collection members, scalar referents not part of the flush
+----------------------------------------------------------------------------------
+
+Warnings are now emitted when related objects referenced via
+a loaded ``relationship()`` on a parent object marked as
+"dirty" are not present in the current ``Session``.
+
+The ``save-update`` cascade takes effect when objects are
+added to the ``Session``, or when objects are first
+associated with a parent, so that an object and everything
+related to it are usually all present in the same
+``Session``.  However, if ``save-update`` cascade is
+disabled for a particular ``relationship()``, then this
+behavior does not occur, and the flush process does not try
+to correct for it, instead staying consistent to the
+configured cascade behavior.   Previously, when such objects
+were detected during the flush, they were silently skipped.
+The new behavior is that a warning is emitted, for the
+purposes of alerting to a situation that more often than not
+is the source of unexpected behavior.
+
+:ticket:`1973`
+
+Setup no longer installs a Nose plugin
+--------------------------------------
+
+Since we moved to nose we've used a plugin that installs via
+setuptools, so that the ``nosetests`` script would
+automatically run SQLA's plugin code, necessary for our
+tests to have a full environment.  In the middle of 0.6, we
+realized that the import pattern here meant that Nose's
+"coverage" plugin would break, since "coverage" requires
+that it be started before any modules to be covered are
+imported; so in the middle of 0.6 we made the situation
+worse by adding a separate ``sqlalchemy-nose`` package to
+the build to overcome this.
+
+In 0.7 we've done away with trying to get ``nosetests`` to
+work automatically, since the SQLAlchemy module would
+produce a large number of nose configuration options for all
+usages of ``nosetests``, not just the SQLAlchemy unit tests
+themselves, and the additional ``sqlalchemy-nose`` install
+was an even worse idea, producing an extra package in Python
+environments.   The ``sqla_nose.py`` script in 0.7 is now
+the only way to run the tests with nose.
+
+:ticket:`1949`
+
+Non-``Table``-derived constructs can be mapped
+----------------------------------------------
+
+A construct that isn't against any ``Table`` at all, like a
+function, can be mapped.
+
+::
+
+    from sqlalchemy import select, func
+    from sqlalchemy.orm import mapper
+
+    class Subset(object):
+        pass
+    selectable = select(["x", "y", "z"]).select_from(func.some_db_function()).alias()
+    mapper(Subset, selectable, primary_key=[selectable.c.x])
+
+:ticket:`1876`
+
+aliased() accepts ``FromClause`` elements
+-----------------------------------------
+
+This is a convenience helper such that in the case a plain
+``FromClause``, such as a ``select``, ``Table`` or ``join``
+is passed to the ``orm.aliased()`` construct, it passes
+through to the ``.alias()`` method of that from construct
+rather than constructing an ORM level ``AliasedClass``.
+
+:ticket:`2018`
+
+Session.connection(), Session.execute() accept 'bind'
+-----------------------------------------------------
+
+This is to allow execute/connection operations to
+participate in the open transaction of an engine explicitly.
+It also allows custom subclasses of ``Session`` that
+implement their own ``get_bind()`` method and arguments to
+use those custom arguments with both the ``execute()`` and
+``connection()`` methods equally.
+
+`Session.connection <http://www.sqlalchemy.org/docs/07/orm/s
+ession.html#sqlalchemy.orm.session.Session.connection>`_
+`Session.execute <http://www.sqlalchemy.org/docs/07/orm/sess
+ion.html#sqlalchemy.orm.session.Session.execute>`_
+
+:ticket:`1996`
+
+Standalone bind parameters in columns clause auto-labeled.
+----------------------------------------------------------
+
+Bind parameters present in the "columns clause" of a select
+are now auto-labeled like other "anonymous" clauses, which
+among other things allows their "type" to be meaningful when
+the row is fetched, as in result row processors.
+
+SQLite - relative file paths are normalized through os.path.abspath()
+---------------------------------------------------------------------
+
+This so that a script that changes the current directory
+will continue to target the same location as subsequent
+SQLite connections are established.
+
+:ticket:`2036`
+
+MS-SQL - ``String``/``Unicode``/``VARCHAR``/``NVARCHAR``/``VARBINARY`` emit "max" for no length
+-----------------------------------------------------------------------------------------------
+
+On the MS-SQL backend, the String/Unicode types, and their
+counterparts VARCHAR/ NVARCHAR, as well as VARBINARY
+(:ticket:`1833`) emit "max" as the length when no length is
+specified. This makes it more compatible with Postgresql's
+VARCHAR type which is similarly unbounded when no length
+specified.   SQL Server defaults the length on these types
+to '1' when no length is specified.
+
+Behavioral Changes (Backwards Incompatible)
+===========================================
+
+Note again, aside from the default mutability change, most
+of these changes are \*extremely minor* and will not affect
+most users.
+
+``PickleType`` and ARRAY mutability turned off by default
+---------------------------------------------------------
+
+This change refers to the default behavior of the ORM when
+mapping columns that have either the ``PickleType`` or
+``postgresql.ARRAY`` datatypes.  The ``mutable`` flag is now
+set to ``False`` by default. If an existing application uses
+these types and depends upon detection of in-place
+mutations, the type object must be constructed with
+``mutable=True`` to restore the 0.6 behavior:
+
+::
+
+    Table('mytable', metadata,
+        # ....
+
+        Column('pickled_data', PickleType(mutable=True))
+    )
+
+The ``mutable=True`` flag is being phased out, in favor of
+the new `Mutation Tracking <http://www.sqlalchemy.org/docs/0
+7/orm/extensions/mutable.html>`_ extension.  This extension
+provides a mechanism by which user-defined datatypes can
+provide change events back to the owning parent or parents.
+
+The previous approach of using ``mutable=True`` does not
+provide for change events - instead, the ORM must scan
+through all mutable values present in a session and compare
+them against their original value for changes every time
+``flush()`` is called, which is a very time consuming event.
+This is a holdover from the very early days of SQLAlchemy
+when ``flush()`` was not automatic and the history tracking
+system was not nearly as sophisticated as it is now.
+
+Existing applications which use ``PickleType``,
+``postgresql.ARRAY`` or other ``MutableType`` subclasses,
+and require in-place mutation detection, should migrate to
+the new mutation tracking system, as ``mutable=True`` is
+likely to be deprecated in the future.
+
+:ticket:`1980`
+
+Mutability detection of ``composite()`` requires the Mutation Tracking Extension
+--------------------------------------------------------------------------------
+
+So-called "composite" mapped attributes, those configured
+using the technique described at `Composite Column Types
+<http://www.sqlalchemy.org/docs/07/orm/mapper_config.html
+#composite-column-types>`_, have been re-implemented such
+that the ORM internals are no longer aware of them (leading
+to shorter and more efficient codepaths in critical
+sections).   While composite types are generally intended to
+be treated as immutable value objects, this was never
+enforced.   For applications that use composites with
+mutability, the `Mutation Tracking <http://www.sqlalchemy.or
+g/docs/07/orm/extensions/mutable.html>`_ extension offers a
+base class which establishes a mechanism for user-defined
+composite types to send change event messages back to the
+owning parent or parents of each object.
+
+Applications which use composite types and rely upon in-
+place mutation detection of these objects should either
+migrate to the "mutation tracking" extension, or change the
+usage of the composite types such that in-place changes are
+no longer needed (i.e., treat them as immutable value
+objects).
+
+SQLite - the SQLite dialect now uses ``NullPool`` for file-based databases
+--------------------------------------------------------------------------
+
+This change is **99.999% backwards compatible**, unless you
+are using temporary tables across connection pool
+connections.
+
+A file-based SQLite connection is blazingly fast, and using
+``NullPool`` means that each call to ``Engine.connect``
+creates a new pysqlite connection.
+
+Previously, the ``SingletonThreadPool`` was used, which
+meant that all connections to a certain engine in a thread
+would be the same connection.   It's intended that the new
+approach is more intuitive, particularly when multiple
+connections are used.
+
+``SingletonThreadPool`` is still the default engine when a
+``:memory:`` database is used.
+
+Note that this change **breaks temporary tables used across
+Session commits**, due to the way SQLite handles temp
+tables. See the note at
+http://www.sqlalchemy.org/docs/dialects/sqlite.html#using-
+temporary-tables-with-sqlite if temporary tables beyond the
+scope of one pool connection are desired.
+
+:ticket:`1921`
+
+``Session.merge()`` checks version ids for versioned mappers
+------------------------------------------------------------
+
+Session.merge() will check the version id of the incoming
+state against that of the database, assuming the mapping
+uses version ids and incoming state has a version_id
+assigned, and raise StaleDataError if they don't match.
+This is the correct behavior, in that if incoming state
+contains a stale version id, it should be assumed the state
+is stale.
+
+If merging data into a versioned state, the version id
+attribute can be left undefined, and no version check will
+take place.
+
+This check was confirmed by examining what Hibernate does -
+both the ``merge()`` and the versioning features were
+originally adapted from Hibernate.
+
+:ticket:`2027`
+
+Tuple label names in Query Improved
+-----------------------------------
+
+This improvement is potentially slightly backwards
+incompatible for an application that relied upon the old
+behavior.
+
+Given two mapped classes ``Foo`` and ``Bar`` each with a
+column ``spam``:
+
+::
+
+
+    qa = session.query(Foo.spam)
+    qb = session.query(Bar.spam)
+
+    qu = qa.union(qb)
+
+The name given to the single column yielded by ``qu`` will
+be ``spam``.  Previously it would be something like
+``foo_spam`` due to the way the ``union`` would combine
+things, which is inconsistent with the name ``spam`` in the
+case of a non-unioned query.
+
+:ticket:`1942`
+
+Mapped column attributes reference the most specific column first
+-----------------------------------------------------------------
+
+This is a change to the behavior involved when a mapped
+column attribute references multiple columns, specifically
+when dealing with an attribute on a joined-table subclass
+that has the same name as that of an attribute on the
+superclass.
+
+Using declarative, the scenario is this:
+
+::
+
+    class Parent(Base):
+        __tablename__ = 'parent'
+        id = Column(Integer, primary_key=True)
+
+    class Child(Parent):
+       __tablename__ = 'child'
+        id = Column(Integer, ForeignKey('parent.id'), primary_key=True)
+
+Above, the attribute ``Child.id`` refers to both the
+``child.id`` column as well as ``parent.id`` - this due to
+the name of the attribute.  If it were named differently on
+the class, such as ``Child.child_id``, it then maps
+distinctly to ``child.id``, with ``Child.id`` being the same
+attribute as ``Parent.id``.
+
+When the ``id`` attribute is made to reference both
+``parent.id`` and ``child.id``, it stores them in an ordered
+list.   An expression such as ``Child.id`` then refers to
+just *one* of those columns when rendered. Up until 0.6,
+this column would be ``parent.id``.  In 0.7, it is the less
+surprising ``child.id``.
+
+The legacy of this behavior deals with behaviors and
+restrictions of the ORM that don't really apply anymore; all
+that was needed was to reverse the order.
+
+A primary advantage of this approach is that it's now easier
+to construct ``primaryjoin`` expressions that refer to the
+local column:
+
+::
+
+    class Child(Parent):
+       __tablename__ = 'child'
+        id = Column(Integer, ForeignKey('parent.id'), primary_key=True)
+        some_related = relationship("SomeRelated",
+                        primaryjoin="Child.id==SomeRelated.child_id")
+
+    class SomeRelated(Base):
+       __tablename__ = 'some_related'
+        id = Column(Integer, primary_key=True)
+        child_id = Column(Integer, ForeignKey('child.id'))
+
+Prior to 0.7 the ``Child.id`` expression would reference
+``Parent.id``, and it would be necessary to map ``child.id``
+to a distinct attribute.
+
+It also means that a query like this one changes its
+behavior:
+
+::
+
+    session.query(Parent).filter(Child.id > 7)
+
+In 0.6, this would render:
+
+::
+
+    SELECT parent.id AS parent_id
+    FROM parent
+    WHERE parent.id > :id_1
+
+in 0.7, you get:
+
+::
+
+    SELECT parent.id AS parent_id
+    FROM parent, child
+    WHERE child.id > :id_1
+
+which you'll note is a cartesian product - this behavior is
+now equivalent to that of any other attribute that is local
+to ``Child``.   The ``with_polymorphic()`` method, or a
+similar strategy of explicitly joining the underlying
+``Table`` objects, is used to render a query against all
+``Parent`` objects with criteria against ``Child``, in the
+same manner as that of 0.5 and 0.6:
+
+::
+
+    print s.query(Parent).with_polymorphic([Child]).filter(Child.id > 7)
+
+Which on both 0.6 and 0.7 renders:
+
+::
+
+    SELECT parent.id AS parent_id, child.id AS child_id
+    FROM parent LEFT OUTER JOIN child ON parent.id = child.id
+    WHERE child.id > :id_1
+
+Another effect of this change is that a joined-inheritance
+load across two tables will populate from the child table's
+value, not that of the parent table. An unusual case is that
+a query against "Parent" using ``with_polymorphic="*"``
+issues a query against "parent", with a LEFT OUTER JOIN to
+"child".  The row is located in "Parent", sees the
+polymorphic identity corresponds to "Child", but suppose the
+actual row in "child" has been *deleted*.  Due to this
+corruption, the row comes in with all the columns
+corresponding to "child" set to NULL - this is now the value
+that gets populated, not the one in the parent table.
+
+:ticket:`1892`
+
+Mapping to joins with two or more same-named columns requires explicit declaration
+----------------------------------------------------------------------------------
+
+This is somewhat related to the previous change in
+:ticket:`1892`.   When mapping to a join, same-named columns
+must be explicitly linked to mapped attributes, i.e. as
+described in `Mapping a Class Against Multiple Tables <http:
+//www.sqlalchemy.org/docs/07/orm/mapper_config.html#mapping-
+a-class-against-multiple-tables>`_.
+
+Given two tables ``foo`` and ``bar``, each with a primary
+key column ``id``, the following now produces an error:
+
+::
+
+
+    foobar = foo.join(bar, foo.c.id==bar.c.foo_id)
+    mapper(FooBar, foobar)
+
+This because the ``mapper()`` refuses to guess what column
+is the primary representation of ``FooBar.id`` - is it
+``foo.c.id`` or is it ``bar.c.id`` ?   The attribute must be
+explicit:
+
+::
+
+
+    foobar = foo.join(bar, foo.c.id==bar.c.foo_id)
+    mapper(FooBar, foobar, properties={
+        'id':[foo.c.id, bar.c.id]
+    })
+
+:ticket:`1896`
+
+Mapper requires that polymorphic_on column be present in the mapped selectable
+------------------------------------------------------------------------------
+
+This is a warning in 0.6, now an error in 0.7.   The column
+given for ``polymorphic_on`` must be in the mapped
+selectable.  This to prevent some occasional user errors
+such as:
+
+::
+
+    mapper(SomeClass, sometable, polymorphic_on=some_lookup_table.c.id)
+
+where above the polymorphic_on needs to be on a
+``sometable`` column, in this case perhaps
+``sometable.c.some_lookup_id``.   There are also some
+"polymorphic union" scenarios where similar mistakes
+sometimes occur.
+
+Such a configuration error has always been "wrong", and the
+above mapping doesn't work as specified - the column would
+be ignored.  It is however potentially backwards
+incompatible in the rare case that an application has been
+unknowingly relying upon this behavior.
+
+:ticket:`1875`
+
+``DDL()`` constructs now escape percent signs
+---------------------------------------------
+
+Previously, percent signs in ``DDL()`` strings would have to
+be escaped, i.e. ``%%`` depending on DBAPI, for those DBAPIs
+that accept ``pyformat`` or ``format`` binds (i.e. psycopg2,
+mysql-python), which was inconsistent versus ``text()``
+constructs which did this automatically.  The same escaping
+now occurs for ``DDL()`` as for ``text()``.
+
+:ticket:`1897`
+
+``Table.c`` / ``MetaData.tables`` refined a bit, don't allow direct mutation
+----------------------------------------------------------------------------
+
+Another area where some users were tinkering around in such
+a way that doesn't actually work as expected, but still left
+an exceedingly small chance that some application was
+relying upon this behavior, the construct returned by the
+``.c`` attribute on ``Table`` and the ``.tables`` attribute
+on ``MetaData`` is explicitly non-mutable.    The "mutable"
+version of the construct is now private.   Adding columns to
+``.c`` involves using the ``append_column()`` method of
+``Table``, which ensures things are associated with the
+parent ``Table`` in the appropriate way; similarly,
+``MetaData.tables`` has a contract with the ``Table``
+objects stored in this dictionary, as well as a little bit
+of new bookkeeping in that a ``set()`` of all schema names
+is tracked, which is satisfied only by using the public
+``Table`` constructor as well as ``Table.tometadata()``.
+
+It is of course possible that the ``ColumnCollection`` and
+``dict`` collections consulted by these attributes could
+someday implement events on all of their mutational methods
+such that the appropriate bookkeeping occurred upon direct
+mutation of the collections, but until someone has the
+motivation to implement all that along with dozens of new
+unit tests, narrowing the paths to mutation of these
+collections will ensure no application is attempting to rely
+upon usages that are currently not supported.
+
+:ticket:`1893` :ticket:`1917`
+
+server_default consistently returns None for all inserted_primary_key values
+----------------------------------------------------------------------------
+
+Established consistency when server_default is present on an
+Integer PK column. SQLA doesn't pre-fetch these, nor do they
+come back in cursor.lastrowid (DBAPI). Ensured all backends
+consistently return None in result.inserted_primary_key for
+these - some backends may have returned a value previously.
+Using a server_default on a primary key column is extremely
+unusual.   If a special function or SQL expression is used
+to generate primary key defaults, this should be established
+as a Python-side "default" instead of server_default.
+
+Regarding reflection for this case, reflection of an int PK
+col with a server_default sets the "autoincrement" flag to
+False, except in the case of a PG SERIAL col where we
+detected a sequence default.
+
+:ticket:`2020` :ticket:`2021`
+
+The ``sqlalchemy.exceptions`` alias in sys.modules is removed
+-------------------------------------------------------------
+
+For a few years we've added the string
+``sqlalchemy.exceptions`` to ``sys.modules``, so that a
+statement like "``import sqlalchemy.exceptions``" would
+work.   The name of the core exceptions module has been
+``exc`` for a long time now, so the recommended import for
+this module is:
+
+::
+
+    from sqlalchemy import exc
+
+The ``exceptions`` name is still present in "``sqlalchemy``"
+for applications which might have said ``from sqlalchemy
+import exceptions``, but they should also start using the
+``exc`` name.
+
+Query Timing Recipe Changes
+---------------------------
+
+While not part of SQLAlchemy itself, it's worth mentioning
+that the rework of the ``ConnectionProxy`` into the new
+event system means it is no longer appropriate for the
+"Timing all Queries" recipe.  Please adjust query-timers to
+use the ``before_cursor_execute()`` and
+``after_cursor_execute()`` events, demonstrated in the
+updated recipe UsageRecipes/Profiling.
+
+Deprecated API
+==============
+
+Default constructor on types will not accept arguments
+------------------------------------------------------
+
+Simple types like ``Integer``, ``Date`` etc. in the core
+types module don't accept arguments.  The default
+constructor that accepts/ignores a catchall ``\*args,
+\**kwargs`` is restored as of 0.7b4/0.7.0, but emits a
+deprecation warning.
+
+If arguments are being used with a core type like
+``Integer``, it may be that you intended to use a dialect
+specific type, such as ``sqlalchemy.dialects.mysql.INTEGER``
+which does accept a "display_width" argument for example.
+
+compile_mappers() renamed configure_mappers(), simplified configuration internals
+---------------------------------------------------------------------------------
+
+This system slowly morphed from something small, implemented
+local to an individual mapper, and poorly named into
+something that's more of a global "registry-" level function
+and poorly named, so we've fixed both by moving the
+implementation out of ``Mapper`` altogether and renaming it
+to ``configure_mappers()``.   It is of course normally not
+needed for an application to call ``configure_mappers()`` as
+this process occurs on an as-needed basis, as soon as the
+mappings are needed via attribute or query access.
+
+:ticket:`1966`
+
+Core listener/proxy superseded by event listeners
+-------------------------------------------------
+
+``PoolListener``, ``ConnectionProxy``,
+``DDLElement.execute_at`` are superseded by
+``event.listen()``, using the ``PoolEvents``,
+``EngineEvents``, ``DDLEvents`` dispatch targets,
+respectively.
+
+ORM extensions superseded by event listeners
+--------------------------------------------
+
+``MapperExtension``, ``AttributeExtension``,
+``SessionExtension`` are superseded by ``event.listen()``,
+using the ``MapperEvents``/``InstanceEvents``,
+``AttributeEvents``, ``SessionEvents``, dispatch targets,
+respectively.
+
+Sending a string to 'distinct' in select() for MySQL should be done via prefixes
+--------------------------------------------------------------------------------
+
+This obscure feature allows this pattern with the MySQL
+backend:
+
+::
+
+    select([mytable], distinct='ALL', prefixes=['HIGH_PRIORITY'])
+
+The ``prefixes`` keyword or ``prefix_with()`` method should
+be used for non-standard or unusual prefixes:
+
+::
+
+    select([mytable]).prefix_with('HIGH_PRIORITY', 'ALL')
+
+``useexisting`` superseded by ``extend_existing`` and ``keep_existing``
+-----------------------------------------------------------------------
+
+The ``useexisting`` flag on Table has been superseded by a
+new pair of flags ``keep_existing`` and ``extend_existing``.
+``extend_existing`` is equivalent to ``useexisting`` - the
+existing Table is returned, and additional constructor
+elements are added. With ``keep_existing``, the existing
+Table is returned, but additional constructor elements are
+not added - these elements are only applied when the Table
+is newly created.
+
+Backwards Incompatible API Changes
+==================================
+
+Callables passed to ``bindparam()`` don't get evaluated - affects the Beaker example
+------------------------------------------------------------------------------------
+
+:ticket:`1950`
+
+Note this affects the Beaker caching example, where the
+workings of the ``_params_from_query()`` function needed a
+slight adjustment. If you're using code from the Beaker
+example, this change should be applied.
+
+types.type_map is now private, types._type_map
+----------------------------------------------
+
+We noticed some users tapping into this dictionary inside of
+``sqlalchemy.types`` as a shortcut to associating Python
+types with SQL types. We can't guarantee the contents or
+format of this dictionary, and additionally the business of
+associating Python types in a one-to-one fashion has some
+grey areas that should are best decided by individual
+applications, so we've underscored this attribute.
+
+:ticket:`1870`
+
+Renamed the ``alias`` keyword arg of standalone ``alias()`` function to ``name``
+--------------------------------------------------------------------------------
+
+This so that the keyword argument ``name`` matches that of
+the ``alias()`` methods on all ``FromClause`` objects as
+well as the ``name`` argument on ``Query.subquery()``.
+
+Only code that uses the standalone ``alias()`` function, and
+not the method bound functions, and passes the alias name
+using the explicit keyword name ``alias``, and not
+positionally, would need modification here.
+
+Non-public ``Pool`` methods underscored
+---------------------------------------
+
+All methods of ``Pool`` and subclasses which are not
+intended for public use have been renamed with underscores.
+That they were not named this way previously was a bug.
+
+Pooling methods now underscored or removed:
+
+``Pool.create_connection()`` ->
+``Pool._create_connection()``
+
+``Pool.do_get()`` -> ``Pool._do_get()``
+
+``Pool.do_return_conn()`` -> ``Pool._do_return_conn()``
+
+``Pool.do_return_invalid()`` -> removed, was not used
+
+``Pool.return_conn()`` -> ``Pool._return_conn()``
+
+``Pool.get()`` -> ``Pool._get()``, public API is
+``Pool.connect()``
+
+``SingletonThreadPool.cleanup()`` -> ``_cleanup()``
+
+``SingletonThreadPool.dispose_local()`` -> removed, use
+``conn.invalidate()``
+
+:ticket:`1982`
+
+Previously Deprecated, Now Removed
+==================================
+
+Query.join(), Query.outerjoin(), eagerload(), eagerload_all(), others no longer allow lists of attributes as arguments
+----------------------------------------------------------------------------------------------------------------------
+
+Passing a list of attributes or attribute names to
+``Query.join``, ``eagerload()``, and similar has been
+deprecated since 0.5:
+
+::
+
+    # old way, deprecated since 0.5
+    session.query(Houses).join([Houses.rooms, Room.closets])
+    session.query(Houses).options(eagerload_all([Houses.rooms, Room.closets]))
+
+These methods all accept \*args as of the 0.5 series:
+
+::
+
+    # current way, in place since 0.5
+    session.query(Houses).join(Houses.rooms, Room.closets)
+    session.query(Houses).options(eagerload_all(Houses.rooms, Room.closets))
+
+``ScopedSession.mapper`` is removed
+-----------------------------------
+
+This feature provided a mapper extension which linked class-
+based functionality with a particular ``ScopedSession``, in
+particular providing the behavior such that new object
+instances would be automatically associated with that
+session.   The feature was overused by tutorials and
+frameworks which led to great user confusion due to its
+implicit behavior, and was deprecated in 0.5.5.   Techniques
+for replicating its functionality are at
+[wiki:UsageRecipes/SessionAwareMapper]
+
index 7985b35b2451f6f74c60cdb6ec0daa076a95d2dd..245a84b80d6fd3cb43229c1f14967cb325a591a3 100644 (file)
@@ -11,7 +11,8 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys, os
+import sys
+import 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
@@ -33,7 +34,14 @@ import sqlalchemy
 #                'sphinx.ext.doctest', 'builder.builders']
 
 extensions = ['sphinx.ext.autodoc',
-                'sphinx.ext.doctest', 'builder.builders']
+                'sphinx.ext.doctest',
+                'sphinx.ext.doctest',
+                'builder.autodoc_mods',
+                'builder.changelog',
+                'builder.dialect_info',
+                'builder.mako',
+                'builder.sqlformatter',
+                ]
 
 # Add any paths that contain templates here, relative to this directory.
 # not sure why abspath() is needed here, some users
@@ -45,7 +53,19 @@ nitpicky = True
 # The suffix of source filenames.
 source_suffix = '.rst'
 
-template_bridge = "builder.builders.MakoBridge"
+# section names used by the changelog extension.
+changelog_sections = ["general", "orm", "orm declarative", "orm querying", \
+                "orm configuration", "engine", "sql", \
+                "schema", \
+                "postgresql", "mysql", "sqlite", "mssql", \
+                "oracle", "firebird"]
+# tags to sort on inside of sections
+changelog_inner_tag_sort = ["feature", "bug", "moved", "changed", "removed"]
+
+# how to render changelog links
+changelog_render_ticket = "http://www.sqlalchemy.org/trac/ticket/%s"
+changelog_render_pullreq = "https://bitbucket.org/sqlalchemy/sqlalchemy/pull-request/%s"
+changelog_render_changeset = "http://www.sqlalchemy.org/trac/changeset/%s"
 
 # The encoding of source files.
 #source_encoding = 'utf-8-sig'
index e4c7d5f6800f4bd04b96f8b07db80e7e5f37f2cc..8a64239a913e0b523b1d5512e66f6f99ce774e2f 100644 (file)
@@ -10,8 +10,9 @@ Getting Started
 A high level view and getting set up.
 
 :ref:`Overview <overview>` |
-:ref:`Installation Guide <installation>` |
-:ref:`Migration from 0.6 <migration>`
+:ref:`Installation Guide <installation>`  |
+:doc:`Migration from 0.6 <changelog/migration_07>` |
+:doc:`Changelog catalog <changelog/index>`
 
 SQLAlchemy ORM
 ==============
index 7c653e575dfe8a1df27ce4a55449c4360eacbd2d..471fb622cfd1c04bd2ae04d1320dbad2fae6a4c1 100644 (file)
@@ -189,5 +189,4 @@ Python prompt like this:
 0.6 to 0.7 Migration
 =====================
 
-Notes on what's changed from 0.6 to 0.7 is available on the SQLAlchemy wiki at
-`07Migration <http://www.sqlalchemy.org/trac/wiki/07Migration>`_.
+Notes on what's changed from 0.6 to 0.7 is available at :doc:`changelog/migration_07`.
index 23c3abe63254d3296a0a1b9ae51dca73b561eef6..c0dbdcb289a268607eccbf96bcdc286bf9a0261f 100644 (file)
@@ -7,7 +7,7 @@ body {
 }
 
 a {
-    font-weight:normal; 
+    font-weight:normal;
     text-decoration:none;
 }
 
@@ -29,7 +29,7 @@ a:hover {
 
 /* paragraph links after sections.
    These aren't visible until hovering
-   over the <h> tag, then have a 
+   over the <h> tag, then have a
    "reverse video" effect over the actual
    link
  */
@@ -226,13 +226,20 @@ a.headerlink:hover {
 #docs-body h1 {
   /* hide the <h1> for each content section. */
   display:none;
-  font-size:1.8em;
+  font-size:2.0em;
 }
 
 #docs-body h2 {
-  font-size:1.6em;
+  font-size:1.8em;
+  border-top:1px solid;
+  /*border-bottom:1px solid;*/
+  padding-top:20px;
 }
 
+#sqlalchemy-documentation h2 {
+  border-top:none;
+  padding-top:0;
+}
 #docs-body h3 {
   font-size:1.4em;
 }
@@ -252,7 +259,7 @@ a.headerlink:hover {
 }
 
 #docs-container pre {
-  background-color: #f0f0f0;  
+  background-color: #f0f0f0;
   border: solid 1px #ccc;
   box-shadow: 2px 2px 3px #DFDFDF;
   padding:10px;
@@ -284,7 +291,7 @@ a.headerlink:hover {
   line-height:1.2em;
 }
 
-#docs-container a.sql_link, 
+#docs-container a.sql_link,
 #docs-container .sql_link
 {
     text-decoration: none;
@@ -298,13 +305,21 @@ a.headerlink:hover {
     background-color: #900;
 }
 
+/* changeset stuff */
+
+#docs-container a.changeset-link {
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
 /* docutils-specific elements */
 
 th.field-name {
     text-align:right;
 }
 
-div.note, div.warning, p.deprecated, div.topic  {
+div.note, div.warning, p.deprecated, div.topic, div.admonition  {
     background-color:#EEFFEF;
 }
 
@@ -313,6 +328,14 @@ div.admonition, div.topic, p.deprecated, p.versionadded, p.versionchanged {
     border:1px solid #CCCCCC;
     padding:5px 10px;
     font-size:.9em;
+    margin-top:5px;
+    box-shadow: 2px 2px 3px #DFDFDF;
+}
+
+div.inherited-member {
+    border:1px solid #CCCCCC;
+    padding:5px 5px;
+    font-size:.9em;
     box-shadow: 2px 2px 3px #DFDFDF;
 }
 
@@ -353,6 +376,7 @@ dl.glossary > dt {
   font-size:1.1em;
 }
 
+
 dt:target, span.highlight {
     background-color:#FBE54E;
 }
@@ -404,7 +428,7 @@ tt {
 .go {color:#804049;}
 
 
-/* special "index page" sections 
+/* special "index page" sections
    with specific formatting
 */
 
index 472b5f8e10bc6132b03775fac8333a23864de126..7a4ef038e880cdc6a91ce3286a4f836173917a74 100644 (file)
@@ -1429,10 +1429,10 @@ class HistoryTest(fixtures.TestBase):
                 useobject=True)
         return Foo, Bar
 
-    def _someattr_history(self, f):
+    def _someattr_history(self, f, **kw):
         return attributes.get_state_history(
                     attributes.instance_state(f),
-                    'someattr')
+                    'someattr', **kw)
 
     def _commit_someattr(self, f):
         attributes.instance_state(f).commit(attributes.instance_dict(f),
@@ -1600,6 +1600,12 @@ class HistoryTest(fixtures.TestBase):
         assert 'someattr' not in f.__dict__
         assert 'someattr' not in attributes.instance_state(f).committed_state
 
+    def test_collection_never_set(self):
+        Foo = self._fixture(uselist=True, useobject=True,
+                                active_history=True)
+        f = Foo()
+        eq_(self._someattr_history(f, passive=True), ((), [], ()))
+
     def test_scalar_active_set(self):
         Foo = self._fixture(uselist=False, useobject=False,
                                 active_history=True)