Commit 86ed6e9d authored by Jim Fulton's avatar Jim Fulton

Finished the install-and-run topic and added docs for ZODB.config

parent 86b04522
...@@ -12,7 +12,11 @@ If you haven't yet, you should read the :ref:`Tutorial <tutorial-label>`. ...@@ -12,7 +12,11 @@ If you haven't yet, you should read the :ref:`Tutorial <tutorial-label>`.
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
install-and-run
writing-persistent-objects.rst writing-persistent-objects.rst
.. todo:
transaction.rst transaction.rst
storages.rst storages.rst
configuration.rst configuration.rst
......
...@@ -29,8 +29,8 @@ For more complex configurations, you'll probably find ZODB's ...@@ -29,8 +29,8 @@ For more complex configurations, you'll probably find ZODB's
configuration language easier to use. configuration language easier to use.
To understand database setup, it's important to understand ZODB's To understand database setup, it's important to understand ZODB's
architecture. In particular, ZODB separates database functionality architecture. ZODB separates database functionality
from low-level storage concerns. When you create a database object, from storage concerns. When you create a database object,
you specify a storage object for it to use, as in:: you specify a storage object for it to use, as in::
import ZODB, ZODB.FileStorage import ZODB, ZODB.FileStorage
...@@ -45,7 +45,7 @@ a database. ...@@ -45,7 +45,7 @@ a database.
Sometimes, storages are created through composition. For example, if Sometimes, storages are created through composition. For example, if
we want to save space, we could layer a ``ZlibStorage`` we want to save space, we could layer a ``ZlibStorage``
[#zlibstorage_]_ over the file storage:: [#zlibstoragefn]_ over the file storage::
import ZODB, ZODB.FileStorage, zc.zlibstorage import ZODB, ZODB.FileStorage, zc.zlibstorage
...@@ -61,11 +61,11 @@ Python configuration ...@@ -61,11 +61,11 @@ Python configuration
-------------------- --------------------
To set up a database with Python, you'll construct a storage using the To set up a database with Python, you'll construct a storage using the
ref:`storage APIs <included-storages-label>`, and then pass the :ref:`storage APIs <included-storages-label>`, and then pass the
storage to the class:`~ZODB.DB` class to create a database, as shown storage to the :class:`~ZODB.DB` class to create a database, as shown
in the examples in the previous section. in the examples in the previous section.
The class:`~ZODB.DB` class also accepts a string path name as it's The :class:`~ZODB.DB` class also accepts a string path name as it's
storage argument to automatically create a file storage. You can also storage argument to automatically create a file storage. You can also
pass ``None`` as the storage to automatically use a pass ``None`` as the storage to automatically use a
:class:`~ZODB.MappingStorage.MappingStorage`, which is convenient when :class:`~ZODB.MappingStorage.MappingStorage`, which is convenient when
...@@ -73,7 +73,147 @@ exploring ZODB:: ...@@ -73,7 +73,147 @@ exploring ZODB::
db = ZODB.DB(None) # Create an in-memory database. db = ZODB.DB(None) # Create an in-memory database.
Text configuration
------------------
.. [#zlibstorage_] `zc.zlibstorage ZODB supports a text-based configuration language. It uses a syntax
similar to Apache configuration files. The syntax was chosen to be
familiar to site administrators.
ZODB's text configuration uses `ZConfig
<https://pypi.python.org/pypi/ZConfig/3.1.0>`_. You can use ZConfig to
create your application's configuration, but it's more common to
include ZODB configuration strings in their own files or embedded in
simpler configuration files, such as `configarser
<https://docs.python.org/3/library/configparser.html#module-configparser>`_
files.
A database configuration string has a ``zodb`` section wrapping a
storage section, as in::
<zodb>
cache-size-bytes 100MB
<mappingstorage>
</mappingstorage>
</zodb>
.. -> snippet
In the example above, the :ref:`mappingstorage
<mappingstorage-text-configuration>` section defines the storage used
by the database.
To create a database from a string, use
:func:`ZODB.config.databaseFromString`::
>>> import ZODB.config
>>> db = ZODB.config.databaseFromString(snippet)
To load databases from file names or URLs, use
:func:`ZODB.config.databaseFromURL`.
Using databases: connections
============================
Once you have a database, you need to get a database connection to to
much of anything. Connections take care of loading and saving objects
and manage object caches. Each connection has it's own cache
[#caches-are-expensive]_.
Getting connections
-------------------
Amongst [#amongst]_ the common ways of getting a connection:
db.open()
The database :meth:`~ZODB.DB.open` method opens a
connection, returning a connection object::
>>> conn = db.open()
It's up to the application to call
:meth:`~ZODB.Connection.Connection.close` when the application is
done using the connection.
If changes are made, the application :ref:`commits transactions
<commit-transactions>` to make them permanent.
db.transaction() The database :meth:`~ZODB.DB.transaction` method
returns a context manager that can be used with the `python with
statement
<https://docs.python.org/3/reference/compound_stmts.html#grammar-token-with_stmt>`_
to execute a block of code in a transaction::
with db.transaction() as connection:
connection.root.foo = 1
.. -> src
>>> exec(src)
>>> with db.transaction() as connection:
... print connection.root.foo
1
>>> _ = conn.transaction_manager.begin() # get updates on conn
In the example above, we used ``as connection`` to get the database
connection used in the variable ``connection``.
some_object._p_jar
For code that's already running in the context of an open
connection, you can get the current connection as the ``_p_jar``
attribute of some persistent object that was accessed via the
connection.
Getting objects
---------------
Once you have a connection, you access objects by traversing the
object graph form the root object.
The database root object is a mapping object that holds the top level
objects in the database. There should only be a small number of
top-level (often only one). You can get the root object by calling a
connection's ``root`` attribute::
>>> root = conn.root()
>>> root
{'foo': 1}
>>> root['foo']
1
For convenience [#root-convenience]_, you can also get top-level
objects by accessing attributes of the connection root object:
>>> conn.root.foo
1
Once you have a top-level object, you use it's methods, attributes, or
operations to access other objects and so on to get the objects you
need. Often indexing data structures like BTrees_ are used to
make it possible to search objects in large collections.
.. [#zlibstoragefn] `zc.zlibstorage
<https://pypi.python.org/pypi/zc.zlibstorage>`_ is an optional <https://pypi.python.org/pypi/zc.zlibstorage>`_ is an optional
package that you need to install separately. package that you need to install separately.
.. [#caches-are-expensive] ZODB can be very efficient at caching data
in memory, especially if your `working set
<https://en.wikipedia.org/wiki/Working_set>`_, because the cache is
simply an object tree and accessing a cached object typically
requires no database interaction. Because each connection has it's
own cache, connections can be expensive, depending on their cache
sizes. For this reason, you'll generally want to limit the number
of open connections you have at any one time. Connections are
pooled, so opening a connection is inexpensive.
.. [#amongst] https://www.youtube.com/watch?v=7WJXHY2OXGE
.. [#root-convenience] The ability to access top-level objects of the
database as root attributes is a recent convenience. Originally,
the ``root()`` method was used to access the root object which was
then accessed as a mapping. It's still potentially useful to
access top-level objects using the mapping interface if their names
aren't valid attribute names.
.. _BTrees: https://pythonhosted.org/BTrees/
...@@ -157,7 +157,7 @@ record from the book record and is managed by ZODB independent of the ...@@ -157,7 +157,7 @@ record from the book record and is managed by ZODB independent of the
management of the book. management of the book.
In addition to ``PersistentList`` and ``PersistentMapping``, general In addition to ``PersistentList`` and ``PersistentMapping``, general
persistent data structures are provided by the ``BTrees`` package, persistent data structures are provided by the BTrees_ package,
most notably ``BTree`` and ``TreeSet`` objects. Unlike most notably ``BTree`` and ``TreeSet`` objects. Unlike
``PersistentList`` and ``PersistentMapping``, ``BTree`` and ``PersistentList`` and ``PersistentMapping``, ``BTree`` and
``TreeSet`` objects are scalable and can easily hold millions of ``TreeSet`` objects are scalable and can easily hold millions of
...@@ -566,3 +566,5 @@ framework for managing schema-migration scripts. ...@@ -566,3 +566,5 @@ framework for managing schema-migration scripts.
<https://pypi.python.org/pypi/zope.cachedescriptors>`_ package <https://pypi.python.org/pypi/zope.cachedescriptors>`_ package
provides some descriptors that help implement attributes that cache provides some descriptors that help implement attributes that cache
data. data.
.. _BTrees: https://pythonhosted.org/BTrees/
...@@ -89,6 +89,8 @@ MappingStorage ...@@ -89,6 +89,8 @@ MappingStorage
.. autoclass:: ZODB.MappingStorage.MappingStorage .. autoclass:: ZODB.MappingStorage.MappingStorage
:members: __init__ :members: __init__
.. _mappingstorage-text-configuration:
MappingStorage text configuration MappingStorage text configuration
--------------------------------- ---------------------------------
......
...@@ -31,6 +31,8 @@ Databases ...@@ -31,6 +31,8 @@ Databases
supportsUndo, undoLog, undoInfo, undoMultiple, undo, supportsUndo, undoLog, undoInfo, undoMultiple, undo,
transaction, storage transaction, storage
.. _database-text-configuration:
Database text configuration Database text configuration
--------------------------- ---------------------------
...@@ -38,7 +40,7 @@ Databases are configured with ``zodb`` sections:: ...@@ -38,7 +40,7 @@ Databases are configured with ``zodb`` sections::
<zodb> <zodb>
cache-size-bytes 100MB cache-size-bytes 100MB
<mappingstorage <mappingstorage>
</mappingstorage> </mappingstorage>
</zodb> </zodb>
...@@ -47,6 +49,8 @@ storage and any of the following options: ...@@ -47,6 +49,8 @@ storage and any of the following options:
.. zconfigsectionkeys:: ZODB component.xml zodb .. zconfigsectionkeys:: ZODB component.xml zodb
.. _multidatabase-text-configuration:
For a multi-database configuration, use multiple ``zodb`` sections and For a multi-database configuration, use multiple ``zodb`` sections and
give the sections names:: give the sections names::
...@@ -136,3 +140,10 @@ TimeStamp (transaction ids) ...@@ -136,3 +140,10 @@ TimeStamp (transaction ids)
.. method:: year() .. method:: year()
Return the time stamp's year. Return the time stamp's year.
Loading configuration
=====================
.. automodule:: ZODB.config
:members: databaseFromString, databaseFromFile, databaseFromURL,
storageFromString, storageFromFile, storageFromURL
...@@ -40,6 +40,7 @@ def test_suite(): ...@@ -40,6 +40,7 @@ def test_suite():
manuel.testing.TestSuite( manuel.testing.TestSuite(
manuel.doctest.Manuel() + manuel.capture.Manuel(), manuel.doctest.Manuel() + manuel.capture.Manuel(),
join(guide, 'writing-persistent-objects.rst'), join(guide, 'writing-persistent-objects.rst'),
join(guide, 'install-and-run.rst'),
join(reference, 'zodb.rst'), join(reference, 'zodb.rst'),
join(reference, 'storages.rst'), join(reference, 'storages.rst'),
setUp=setUp, tearDown=tearDown, setUp=setUp, tearDown=tearDown,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment