]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- selected documentation issues
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 30 Nov 2013 21:07:14 +0000 (16:07 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 30 Nov 2013 21:07:14 +0000 (16:07 -0500)
- add glossary terms

doc/build/faq.rst
doc/build/glossary.rst
doc/build/orm/tutorial.rst

index 4d72d3109fc3c993b7075cbe63ee5e8dd814e29e..483660ec9a7b865cbdd5bf7fc7e02f30760b2ed8 100644 (file)
@@ -309,7 +309,7 @@ columns, though it's a good idea that they are.  It's only necessary that the co
 *behave* as a primary key does, e.g. as a unique and not nullable identifier
 for a row.
 
-Most ORMs require that objects have some kind of primary key defined at the
+Most ORMs require that objects have some kind of primary key defined
 because the object in memory must correspond to a uniquely identifiable
 row in the database table; at the very least, this allows the
 object can be targeted for UPDATE and DELETE statements which will affect only
index 9b3d7f5f072587316bdbd0b6b693f85e639d46e4..338f5fab22aa83967b0ba8e8c13fe1f555d752c1 100644 (file)
@@ -116,6 +116,7 @@ Glossary
 
     lazy load
     lazy loads
+    lazy loading
         In object relational mapping, a "lazy load" refers to an
         attribute that does not contain its database-side value
         for some period of time, typically when the object is
@@ -268,6 +269,15 @@ Glossary
 
             `PEP 249 - Python Database API Specification v2.0 <http://www.python.org/dev/peps/pep-0249/>`_
 
+    domain model
+
+        A domain model in problem solving and software engineering is a conceptual model of all the topics related to a specific problem. It describes the various entities, their attributes, roles, and relationships, plus the constraints that govern the problem domain.
+
+        (via Wikipedia)
+
+        .. seealso::
+
+            `Domain Model (wikipedia) <http://en.wikipedia.org/wiki/Domain_model>`_
 
     unit of work
         This pattern is where the system transparently keeps
@@ -441,6 +451,7 @@ Glossary
         clause is not possible, because the correlation can only proceed once the
         original source rows from the enclosing statement's FROM clause are available.
 
+
     ACID
     ACID model
         An acronym for "Atomicity, Consistency, Isolation,
@@ -561,3 +572,422 @@ Glossary
         on top of the RETURNING systems of these backends to provide a consistent
         interface for returning columns.  The ORM also includes many optimizations
         that make use of RETURNING when available.
+
+    one to many
+        A style of :func:`~sqlalchemy.orm.relationship` which links
+        the primary key of the parent mapper's table to the foreign
+        key of a related table.   Each unique parent object can
+        then refer to zero or more unique related objects.
+
+        The related objects in turn will have an implicit or
+        explicit :term:`many to one` relationship to their parent
+        object.
+
+        An example one to many schema (which, note, is identical
+        to the :term:`many to one` schema):
+
+        .. sourcecode:: sql
+
+            CREATE TABLE department (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30)
+            )
+
+            CREATE TABLE employee (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30),
+                dep_id INTEGER REFERENCES department(id)
+            )
+
+        The relationship from ``department`` to ``employee`` is
+        one to many, since many employee records can be associated with a
+        single department.  A SQLAlchemy mapping might look like::
+
+            class Department(Base):
+                __tablename__ = 'department'
+                id = Column(Integer, primary_key=True)
+                name = Column(String(30))
+                employees = relationship("Employee")
+
+            class Employee(Base):
+                __tablename__ = 'employee'
+                id = Column(Integer, primary_key=True)
+                name = Column(String(30))
+                dep_id = Column(Integer, ForeignKey('department.id'))
+
+        .. seealso::
+
+            :term:`relationship`
+
+            :term:`many to one`
+
+            :term:`backref`
+
+    many to one
+        A style of :func:`~sqlalchemy.orm.relationship` which links
+        a foreign key in the parent mapper's table to the primary
+        key of a related table.   Each parent object can
+        then refer to exactly zero or one related object.
+
+        The related objects in turn will have an implicit or
+        explicit :term:`one to many` relationship to any number
+        of parent objects that refer to them.
+
+        An example many to one schema (which, note, is identical
+        to the :term:`one to many` schema):
+
+        .. sourcecode:: sql
+
+            CREATE TABLE department (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30)
+            )
+
+            CREATE TABLE employee (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30),
+                dep_id INTEGER REFERENCES department(id)
+            )
+
+
+        The relationship from ``employee`` to ``department`` is
+        many to one, since many employee records can be associated with a
+        single department.  A SQLAlchemy mapping might look like::
+
+            class Department(Base):
+                __tablename__ = 'department'
+                id = Column(Integer, primary_key=True)
+                name = Column(String(30))
+
+            class Employee(Base):
+                __tablename__ = 'employee'
+                id = Column(Integer, primary_key=True)
+                name = Column(String(30))
+                dep_id = Column(Integer, ForeignKey('department.id'))
+                department = relationship("Department")
+
+        .. seealso::
+
+            :term:`relationship`
+
+            :term:`one to many`
+
+            :term:`backref`
+
+    backref
+    bidirectional relationship
+        An extension to the :term:`relationship` system whereby two
+        distinct :func:`~sqlalchemy.orm.relationship` objects can be
+        mutually associated with each other, such that they coordinate
+        in memory as changes occur to either side.   The most common
+        way these two relationships are constructed is by using
+        the :func:`~sqlalchemy.orm.relationship` function explicitly
+        for one side and specifying the ``backref`` keyword to it so that
+        the other :func:`~sqlalchemy.orm.relationship` is created
+        automatically.  We can illustrate this against the example we've
+        used in :term:`one to many` as follows::
+
+            class Department(Base):
+                __tablename__ = 'department'
+                id = Column(Integer, primary_key=True)
+                name = Column(String(30))
+                employees = relationship("Employee", backref="department")
+
+            class Employee(Base):
+                __tablename__ = 'employee'
+                id = Column(Integer, primary_key=True)
+                name = Column(String(30))
+                dep_id = Column(Integer, ForeignKey('department.id'))
+
+        A backref can be applied to any relationship, including one to many,
+        many to one, and :term:`many to many`.
+
+        .. seealso::
+
+            :term:`relationship`
+
+            :term:`one to many`
+
+            :term:`many to one`
+
+            :term:`many to many`
+
+    many to many
+        A style of :func:`sqlalchemy.orm.relationship` which links two tables together
+        via an intermediary table in the middle.   Using this configuration,
+        any number of rows on the left side may refer to any number of
+        rows on the right, and vice versa.
+
+        A schema where employees can be associated with projects:
+
+        .. sourcecode:: sql
+
+            CREATE TABLE employee (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30)
+            )
+
+            CREATE TABLE project (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30)
+            )
+
+            CREATE TABLE employee_project (
+                employee_id INTEGER PRIMARY KEY,
+                project_id INTEGER PRIMARY KEY,
+                FOREIGN KEY employee_id REFERENCES employee(id),
+                FOREIGN KEY project_id REFERENCES project(id)
+            )
+
+        Above, the ``employee_project`` table is the many-to-many table,
+        which naturally forms a composite primary key consisting
+        of the primary key from each related table.
+
+        In SQLAlchemy, the :func:`sqlalchemy.orm.relationship` function
+        can represent this style of relationship in a mostly
+        transparent fashion, where the many-to-many table is
+        specified using plain table metadata::
+
+            class Employee(Base):
+                __tablename__ = 'employee'
+
+                id = Column(Integer, primary_key)
+                name = Column(String(30))
+
+                projects = relationship(
+                    "Project",
+                    secondary=Table('employee_project', Base.metadata,
+                                Column("employee_id", Integer, ForeignKey('employee.id'),
+                                            primary_key=True),
+                                Column("project_id", Integer, ForeignKey('project.id'),
+                                            primary_key=True)
+                            ),
+                    backref="employees"
+                    )
+
+            class Project(Base):
+                __tablename__ = 'project'
+
+                id = Column(Integer, primary_key)
+                name = Column(String(30))
+
+        Above, the ``Employee.projects`` and back-referencing ``Project.employees``
+        collections are defined::
+
+            proj = Project(name="Client A")
+
+            emp1 = Employee(name="emp1")
+            emp2 = Employee(name="emp2")
+
+            proj.employees.extend([emp1, emp2])
+
+        .. seealso::
+
+            :term:`association relationship`
+
+            :term:`relationship`
+
+            :term:`one to many`
+
+            :term:`many to one`
+
+    relationship
+    relationships
+        A connecting unit between two mapped classes, corresponding
+        to some relationship between the two tables in the database.
+
+        The relationship is defined using the SQLAlchemy function
+        :func:`~sqlalchemy.orm.relationship`.   Once created, SQLAlchemy
+        inspects the arguments and underlying mappings involved
+        in order to classify the relationship as one of three types:
+        :term:`one to many`, :term:`many to one`, or :term:`many to many`.
+        With this classification, the relationship construct
+        handles the task of persisting the appropriate linkages
+        in the database in response to in-memory object associations,
+        as well as the job of loading object references and collections
+        into memory based on the current linkages in the
+        database.
+
+        .. seealso::
+
+            :ref:`relationship_config_toplevel`
+
+    association relationship
+        A two-tiered :term:`relationship` which links two tables
+        together using an association table in the middle.  The
+        association relationship differs from a :term:`many to many`
+        relationship in that the many-to-many table is mapped
+        by a full class, rather than invisibly handled by the
+        :func:`sqlalchemy.orm.relationship` construct as in the case
+        with many-to-many, so that additional attributes are
+        explicitly available.
+
+        For example, if we wanted to associate employees with
+        projects, also storing the specific role for that employee
+        with the project, the relational schema might look like:
+
+        .. sourcecode:: sql
+
+            CREATE TABLE employee (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30)
+            )
+
+            CREATE TABLE project (
+                id INTEGER PRIMARY KEY,
+                name VARCHAR(30)
+            )
+
+            CREATE TABLE employee_project (
+                employee_id INTEGER PRIMARY KEY,
+                project_id INTEGER PRIMARY KEY,
+                role_name VARCHAR(30),
+                FOREIGN KEY employee_id REFERENCES employee(id),
+                FOREIGN KEY project_id REFERENCES project(id)
+            )
+
+        A SQLAlchemy declarative mapping for the above might look like::
+
+            class Employee(Base):
+                __tablename__ = 'employee'
+
+                id = Column(Integer, primary_key)
+                name = Column(String(30))
+
+
+            class Project(Base):
+                __tablename__ = 'project'
+
+                id = Column(Integer, primary_key)
+                name = Column(String(30))
+
+
+            class EmployeeProject(Base):
+                __tablename__ = 'employee_project'
+
+                employee_id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
+                project_id = Column(Integer, ForeignKey('project.id'), primary_key=True)
+                role_name = Column(String(30))
+
+                project = relationship("Project", backref="project_employees")
+                employee = relationship("Employee", backref="employee_projects")
+
+
+        Employees can be added to a project given a role name::
+
+            proj = Project(name="Client A")
+
+            emp1 = Employee(name="emp1")
+            emp2 = Employee(name="emp2")
+
+            proj.project_employees.extend([
+                EmployeeProject(employee=emp1, role="tech lead"),
+                EmployeeProject(employee=emp2, role="account executive")
+            ])
+
+        .. seealso::
+
+            :term:`many to many`
+
+    constraint
+    constraints
+    constrained
+        Rules established within a relational database that ensure
+        the validity and consistency of data.   Common forms
+        of constraint include :term:`primary key constraint`,
+        :term:`foreign key constraint`, and :term:`check constraint`.
+
+    candidate key
+
+        A :term:`relational algebra` term referring to an attribute or set
+        of attributes that form a uniquely identifying key for a
+        row.  A row may have more than one candidate key, each of which
+        is suitable for use as the primary key of that row.
+        The primary key of a table is always a candidate key.
+
+        .. seealso::
+
+            :term:`primary key`
+
+            http://en.wikipedia.org/wiki/Candidate_key
+
+    primary key
+    primary key constraint
+
+        A :term:`constraint` that uniquely defines the characteristics
+        of each :term:`row`. The primary key has to consist of
+        characteristics that cannot be duplicated by any other row.
+        The primary key may consist of a single attribute or
+        multiple attributes in combination.
+        (via Wikipedia)
+
+        The primary key of a table is typically, though not always,
+        defined within the ``CREATE TABLE`` :term:`DDL`:
+
+        .. sourcecode:: sql
+
+            CREATE TABLE employee (
+                 emp_id INTEGER,
+                 emp_name VARCHAR(30),
+                 dep_id INTEGER,
+                 PRIMARY KEY (emp_id)
+            )
+
+        .. seealso::
+
+            http://en.wikipedia.org/wiki/Primary_Key
+
+    foreign key constraint
+        A referential constraint between two tables.  A foreign key is a field or set of fields in a
+        relational table that matches a :term:`candidate key` of another table.
+        The foreign key can be used to cross-reference tables.
+        (via Wikipedia)
+
+        A foreign key constraint can be added to a table in standard
+        SQL using :term:`DDL` like the following:
+
+        .. sourcecode:: sql
+
+            ALTER TABLE employee ADD CONSTRAINT dep_id_fk
+            FOREIGN KEY (employee) REFERENCES department (dep_id)
+
+        .. seealso::
+
+            http://en.wikipedia.org/wiki/Foreign_key_constraint
+
+    check constraint
+
+        A check constraint is a
+        condition that defines valid data when adding or updating an
+        entry in a table of a relational database. A check constraint
+        is applied to each row in the table.
+
+        (via Wikipedia)
+
+        A check constraint can be added to a table in standard
+        SQL using :term:`DDL` like the following:
+
+        .. sourcecode:: sql
+
+            ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
+
+        .. seealso::
+
+            http://en.wikipedia.org/wiki/Check_constraint
+
+    unique constraint
+    unique key index
+        A unique key index can uniquely identify each row of data
+        values in a database table. A unique key index comprises a
+        single column or a set of columns in a single database table.
+        No two distinct rows or data records in a database table can
+        have the same data value (or combination of data values) in
+        those unique key index columns if NULL values are not used.
+        Depending on its design, a database table may have many unique
+        key indexes but at most one primary key index.
+
+        (via Wikipedia)
+
+        .. seealso::
+
+            http://en.wikipedia.org/wiki/Unique_key#Defining_unique_keys
index 04c677cdedccff5a2b67d6d8b15450a1aaafbc12..32d75194a99784d36c7a5d3477970c7595b66579 100644 (file)
@@ -8,8 +8,7 @@ The SQLAlchemy Object Relational Mapper presents a method of associating
 user-defined Python classes with database tables, and instances of those
 classes (objects) with rows in their corresponding tables. It includes a
 system that transparently synchronizes all changes in state between objects
-and their related rows, called a `unit of work
-<http://martinfowler.com/eaaCatalog/unitOfWork.html>`_, as well as a system
+and their related rows, called a :term:`unit of work`, as well as a system
 for expressing database queries in terms of the user defined classes and their
 defined relationships between each other.
 
@@ -23,8 +22,7 @@ example of applied usage of the Expression Language.
 While there is overlap among the usage patterns of the ORM and the Expression
 Language, the similarities are more superficial than they may at first appear.
 One approaches the structure and content of data from the perspective of a
-user-defined `domain model
-<http://en.wikipedia.org/wiki/Domain_model>`_ which is transparently
+user-defined :term:`domain model` which is transparently
 persisted and refreshed from its underlying storage model. The other
 approaches it from the perspective of literal schema and SQL expression
 representations which are explicitly composed into messages consumed
@@ -387,7 +385,7 @@ that which we just added::
     >>> ed_user is our_user
     True
 
-The ORM concept at work here is known as an `identity map <http://martinfowler.com/eaaCatalog/identityMap.html>`_
+The ORM concept at work here is known as an :term:`identity map`
 and ensures that
 all operations upon a particular row within a
 :class:`~sqlalchemy.orm.session.Session` operate upon the same set of data.
@@ -736,7 +734,8 @@ users named "ed" with a full name of "Ed Jones", you can call
 Common Filter Operators
 -----------------------
 
-Here's a rundown of some of the most common operators used in :func:`~sqlalchemy.orm.query.Query.filter`:
+Here's a rundown of some of the most common operators used in
+:func:`~sqlalchemy.orm.query.Query.filter`:
 
 * equals::
 
@@ -755,8 +754,9 @@ Here's a rundown of some of the most common operators used in :func:`~sqlalchemy
     query.filter(User.name.in_(['ed', 'wendy', 'jack']))
 
     # works with query objects too:
-
-    query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%ed%'))))
+    query.filter(User.name.in_(
+            session.query(User.name).filter(User.name.like('%ed%'))
+    ))
 
 * NOT IN::
 
@@ -764,24 +764,28 @@ Here's a rundown of some of the most common operators used in :func:`~sqlalchemy
 
 * IS NULL::
 
-    filter(User.name == None)
+    query.filter(User.name == None)
 
 * IS NOT NULL::
 
-    filter(User.name != None)
+    query.filter(User.name != None)
 
 * AND::
 
+    # use and_()
     from sqlalchemy import and_
-    filter(and_(User.name == 'ed', User.fullname == 'Ed Jones'))
+    query.filter(and_(User.name == 'ed', User.fullname == 'Ed Jones'))
+
+    # or send multiple expressions to .filter()
+    query.filter(User.name == 'ed', User.fullname == 'Ed Jones')
 
-    # or call filter()/filter_by() multiple times
-    filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')
+    # or chain multiple filter()/filter_by() calls
+    query.filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')
 
 * OR::
 
     from sqlalchemy import or_
-    filter(or_(User.name == 'ed', User.name == 'wendy'))
+    query.filter(or_(User.name == 'ed', User.name == 'wendy'))
 
 * match::
 
@@ -792,76 +796,99 @@ Here's a rundown of some of the most common operators used in :func:`~sqlalchemy
 Returning Lists and Scalars
 ---------------------------
 
-The :meth:`~sqlalchemy.orm.query.Query.all()`,
-:meth:`~sqlalchemy.orm.query.Query.one()`, and
-:meth:`~sqlalchemy.orm.query.Query.first()` methods of
-:class:`~sqlalchemy.orm.query.Query` immediately issue SQL and return a
-non-iterator value. :meth:`~sqlalchemy.orm.query.Query.all()` returns a list:
-
-.. sourcecode:: python+sql
-
-    >>> query = session.query(User).filter(User.name.like('%ed')).order_by(User.id)
-    {sql}>>> query.all() #doctest: +NORMALIZE_WHITESPACE
-    SELECT users.id AS users_id,
-            users.name AS users_name,
-            users.fullname AS users_fullname,
-            users.password AS users_password
-    FROM users
-    WHERE users.name LIKE ? ORDER BY users.id
-    ('%ed',)
-    {stop}[<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>, <User(name='fred', fullname='Fred Flinstone', password='blah')>]
-
-:meth:`~sqlalchemy.orm.query.Query.first()` applies a limit of one and returns
-the first result as a scalar:
-
-.. sourcecode:: python+sql
-
-    {sql}>>> query.first() #doctest: +NORMALIZE_WHITESPACE
-    SELECT users.id AS users_id,
-            users.name AS users_name,
-            users.fullname AS users_fullname,
-            users.password AS users_password
-    FROM users
-    WHERE users.name LIKE ? ORDER BY users.id
-     LIMIT ? OFFSET ?
-    ('%ed', 1, 0)
-    {stop}<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>
-
-:meth:`~sqlalchemy.orm.query.Query.one()`, fully fetches all rows, and if not
-exactly one object identity or composite row is present in the result, raises
-an error:
-
-.. sourcecode:: python+sql
-
-    {sql}>>> from sqlalchemy.orm.exc import MultipleResultsFound
-    >>> try: #doctest: +NORMALIZE_WHITESPACE
-    ...     user = query.one()
-    ... except MultipleResultsFound, e:
-    ...     print e
-    SELECT users.id AS users_id,
-            users.name AS users_name,
-            users.fullname AS users_fullname,
-            users.password AS users_password
-    FROM users
-    WHERE users.name LIKE ? ORDER BY users.id
-    ('%ed',)
-    {stop}Multiple rows were found for one()
-
-.. sourcecode:: python+sql
-
-    {sql}>>> from sqlalchemy.orm.exc import NoResultFound
-    >>> try: #doctest: +NORMALIZE_WHITESPACE
-    ...     user = query.filter(User.id == 99).one()
-    ... except NoResultFound, e:
-    ...     print e
-    SELECT users.id AS users_id,
-            users.name AS users_name,
-            users.fullname AS users_fullname,
-            users.password AS users_password
-    FROM users
-    WHERE users.name LIKE ? AND users.id = ? ORDER BY users.id
-    ('%ed', 99)
-    {stop}No row was found for one()
+A number of methods on :class:`.Query`
+immediately issue SQL and return a value containing loaded
+database results.  Here's a brief tour:
+
+* :meth:`~.Query.all()` returns a list:
+
+  .. sourcecode:: python+sql
+
+      >>> query = session.query(User).filter(User.name.like('%ed')).order_by(User.id)
+      {sql}>>> query.all() #doctest: +NORMALIZE_WHITESPACE
+      SELECT users.id AS users_id,
+              users.name AS users_name,
+              users.fullname AS users_fullname,
+              users.password AS users_password
+      FROM users
+      WHERE users.name LIKE ? ORDER BY users.id
+      ('%ed',)
+      {stop}[<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>,
+            <User(name='fred', fullname='Fred Flinstone', password='blah')>]
+
+* :meth:`~.Query.first()` applies a limit of one and returns
+  the first result as a scalar:
+
+  .. sourcecode:: python+sql
+
+      {sql}>>> query.first() #doctest: +NORMALIZE_WHITESPACE
+      SELECT users.id AS users_id,
+              users.name AS users_name,
+              users.fullname AS users_fullname,
+              users.password AS users_password
+      FROM users
+      WHERE users.name LIKE ? ORDER BY users.id
+       LIMIT ? OFFSET ?
+      ('%ed', 1, 0)
+      {stop}<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>
+
+* :meth:`~.Query.one()`, fully fetches all rows, and if not
+  exactly one object identity or composite row is present in the result, raises
+  an error.  With multiple rows found:
+
+  .. sourcecode:: python+sql
+
+      {sql}>>> from sqlalchemy.orm.exc import MultipleResultsFound
+      >>> try: #doctest: +NORMALIZE_WHITESPACE
+      ...     user = query.one()
+      ... except MultipleResultsFound, e:
+      ...     print e
+      SELECT users.id AS users_id,
+              users.name AS users_name,
+              users.fullname AS users_fullname,
+              users.password AS users_password
+      FROM users
+      WHERE users.name LIKE ? ORDER BY users.id
+      ('%ed',)
+      {stop}Multiple rows were found for one()
+
+  With no rows found:
+
+  .. sourcecode:: python+sql
+
+      {sql}>>> from sqlalchemy.orm.exc import NoResultFound
+      >>> try: #doctest: +NORMALIZE_WHITESPACE
+      ...     user = query.filter(User.id == 99).one()
+      ... except NoResultFound, e:
+      ...     print e
+      SELECT users.id AS users_id,
+              users.name AS users_name,
+              users.fullname AS users_fullname,
+              users.password AS users_password
+      FROM users
+      WHERE users.name LIKE ? AND users.id = ? ORDER BY users.id
+      ('%ed', 99)
+      {stop}No row was found for one()
+
+  The :meth:`~.Query.one` method is great for systems that expect to handle
+  "no items found" versus "multiple items found" differently; such as a RESTful
+  web service, which may want to raise a "404 not found" when no results are found,
+  but raise an application error when multiple results are found.
+
+* :meth:`~.Query.scalar` invokes the :meth:`~.Query.one` method, and upon
+  success returns the first column of the row:
+
+  .. sourcecode:: python+sql
+
+      >>> query = session.query(User.id).filter(User.name.like('%ed')).\
+      ...    order_by(User.id)
+      {sql}>>> query.scalar() #doctest: +NORMALIZE_WHITESPACE
+      SELECT users.id AS users_id
+      FROM users
+      WHERE users.name LIKE ? ORDER BY users.id
+       LIMIT ? OFFSET ?
+      ('%ed', 1, 0)
+      {stop}7
 
 .. _orm_tutorial_literal_sql:
 
@@ -1123,7 +1150,7 @@ declarative, we define this table along with its mapped class, ``Address``:
 
 The above class introduces the :class:`.ForeignKey` construct, which is a
 directive applied to :class:`.Column` that indicates that values in this
-column should be **constrained** to be values present in the named remote
+column should be :term:`constrained` to be values present in the named remote
 column. This is a core feature of relational databases, and is the "glue" that
 transforms an otherwise unconnected collection of tables to have rich
 overlapping relationships. The :class:`.ForeignKey` above expresses that
@@ -1135,17 +1162,17 @@ tells the ORM that the ``Address`` class itself should be linked
 to the ``User`` class, using the attribute ``Address.user``.
 :func:`.relationship` uses the foreign key
 relationships between the two tables to determine the nature of
-this linkage, determining that ``Address.user`` will be **many-to-one**.
+this linkage, determining that ``Address.user`` will be :term:`many to one`.
 A subdirective of :func:`.relationship` called :func:`.backref` is
 placed inside of :func:`.relationship`, providing details about
 the relationship as expressed in reverse, that of a collection of ``Address``
 objects on ``User`` referenced by ``User.addresses``.  The reverse
-side of a many-to-one relationship is always **one-to-many**.
+side of a many-to-one relationship is always :term:`one to many`.
 A full catalog of available :func:`.relationship` configurations
 is at :ref:`relationship_patterns`.
 
 The two complementing relationships ``Address.user`` and ``User.addresses``
-are referred to as a **bidirectional relationship**, and is a key
+are referred to as a :term:`bidirectional relationship`, and is a key
 feature of the SQLAlchemy ORM.   The section :ref:`relationships_backref`
 discusses the "backref" feature in detail.
 
@@ -1285,7 +1312,7 @@ Let's look at the ``addresses`` collection.  Watch the SQL:
     {stop}[<Address(email_address='jack@google.com')>, <Address(email_address='j25@yahoo.com')>]
 
 When we accessed the ``addresses`` collection, SQL was suddenly issued. This
-is an example of a **lazy loading relationship**.  The ``addresses`` collection
+is an example of a :term:`lazy loading` relationship.  The ``addresses`` collection
 is now loaded and behaves just like an ordinary list.  We'll cover ways
 to optimize the loading of this collection in a bit.
 
@@ -1607,13 +1634,13 @@ and behavior:
 Eager Loading
 =============
 
-Recall earlier that we illustrated a **lazy loading** operation, when
+Recall earlier that we illustrated a :term:`lazy loading` operation, when
 we accessed the ``User.addresses`` collection of a ``User`` and SQL
 was emitted.  If you want to reduce the number of queries (dramatically, in many cases),
-we can apply an **eager load** to the query operation.   SQLAlchemy
+we can apply an :term:`eager load` to the query operation.   SQLAlchemy
 offers three types of eager loading, two of which are automatic, and a third
 which involves custom criterion.   All three are usually invoked via functions known
-as **query options** which give additional instructions to the :class:`.Query` on how
+as :term:`query options` which give additional instructions to the :class:`.Query` on how
 we would like various attributes to be loaded, via the :meth:`.Query.options` method.
 
 Subquery Load