removed sphinx warnings

This commit is contained in:
Gregor Aisch 2013-04-03 00:51:33 +02:00
parent d240a45e77
commit e0b66510ab
6 changed files with 69 additions and 33 deletions

View File

@ -8,9 +8,11 @@ from dataset.persistence.table import Table
def connect(url): def connect(url):
""" Opens a new connection to a database. *url* can be any valid `SQLAlchemy engine URL`_. Returns """
Opens a new connection to a database. *url* can be any valid `SQLAlchemy engine URL`_. Returns
an instance of :py:class:`Database <dataset.Database>`. an instance of :py:class:`Database <dataset.Database>`.
:: ::
db = dataset.connect('sqlite:///factbook.db') db = dataset.connect('sqlite:///factbook.db')
.. _SQLAlchemy Engine URL: http://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine .. _SQLAlchemy Engine URL: http://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine

View File

@ -36,12 +36,13 @@ class Database(object):
return set(self.metadata.tables.keys() + self._tables.keys()) return set(self.metadata.tables.keys() + self._tables.keys())
def create_table(self, table_name): def create_table(self, table_name):
""" Creates a new table. The new table will automatically have """
an `id` column, which is set to be an auto-incrementing integer Creates a new table. The new table will automatically have an `id` column, which is
as the primary key of the table. set to be an auto-incrementing integer as the primary key of the table.
Returns a :py:class:`Table <dataset.Table>` instance. Returns a :py:class:`Table <dataset.Table>` instance.
:: ::
table = db.create_table('population') table = db.create_table('population')
""" """
with self.lock: with self.lock:
@ -54,14 +55,17 @@ class Database(object):
return Table(self, table) return Table(self, table)
def load_table(self, table_name): def load_table(self, table_name):
""" Loads a table. This will fail if the tables does not already """
Loads a table. This will fail if the tables does not already
exist in the database. If the table exists, its columns will be exist in the database. If the table exists, its columns will be
reflected and are available on the :py:class:`Table <dataset.Table>` reflected and are available on the :py:class:`Table <dataset.Table>`
object. object.
Returns a :py:class:`Table <dataset.Table>` instance. Returns a :py:class:`Table <dataset.Table>` instance.
:: ::
table = db.load_table('population')"""
table = db.load_table('population')
"""
with self.lock: with self.lock:
log.debug("Loading table: %s on %r" % (table_name, self)) log.debug("Loading table: %s on %r" % (table_name, self))
table = SQLATable(table_name, self.metadata, autoload=True) table = SQLATable(table_name, self.metadata, autoload=True)
@ -69,11 +73,13 @@ class Database(object):
return Table(self, table) return Table(self, table)
def get_table(self, table_name): def get_table(self, table_name):
""" Smart wrapper around *load_table* and *create_table*. Either loads a table """
Smart wrapper around *load_table* and *create_table*. Either loads a table
or creates it if it doesn't exist yet. or creates it if it doesn't exist yet.
Returns a :py:class:`Table <dataset.Table>` instance. Returns a :py:class:`Table <dataset.Table>` instance.
:: ::
table = db.get_table('population') table = db.get_table('population')
# you can also use the short-hand syntax: # you can also use the short-hand syntax:
table = db['population'] table = db['population']
@ -90,14 +96,16 @@ class Database(object):
return self.get_table(table_name) return self.get_table(table_name)
def query(self, query): def query(self, query):
""" Run a statement on the database directly, allowing for the """
Run a statement on the database directly, allowing for the
execution of arbitrary read/write queries. A query can either be execution of arbitrary read/write queries. A query can either be
a plain text string, or a SQLAlchemy expression. The returned a plain text string, or a `SQLAlchemy expression <http://docs.sqlalchemy.org/ru/latest/core/tutorial.html#selecting>`_. The returned
iterator will yield each result sequentially. iterator will yield each result sequentially.
:: ::
result = db.query('SELECT * FROM population WHERE population > 10000000')
for row in result: res = db.query('SELECT user, COUNT(*) c FROM photos GROUP BY user')
print row for row in res:
print row['user'], row['c']
""" """
return resultiter(self.engine.execute(query)) return resultiter(self.engine.execute(query))

View File

@ -17,20 +17,28 @@ class Table(object):
self.database = database self.database = database
self.table = table self.table = table
@property
def columns(self):
""" Get a listing of all columns that exist in the table. """
return set(self.table.columns.keys())
def drop(self): def drop(self):
""" Drop the table from the database, deleting both the schema """
Drop the table from the database, deleting both the schema
and all the contents within it. and all the contents within it.
Note: the object will be in an unusable state after using this Note: the object will be in an unusable state after using this
command and should not be used again. If you want to re-create command and should not be used again. If you want to re-create
the table, make sure to get a fresh instance from the the table, make sure to get a fresh instance from the
:py:class:`Database <dataset.Database>`. """ :py:class:`Database <dataset.Database>`.
"""
with self.database.lock: with self.database.lock:
self.database.tables.pop(self.table.name, None) self.database.tables.pop(self.table.name, None)
self.table.drop(engine) self.table.drop(engine)
def insert(self, row, ensure=True, types={}): def insert(self, row, ensure=True, types={}):
""" Add a row (type: dict) by inserting it into the table. """
Add a row (type: dict) by inserting it into the table.
If ``ensure`` is set, any of the keys of the row are not If ``ensure`` is set, any of the keys of the row are not
table columns, they will be created automatically. table columns, they will be created automatically.
@ -40,6 +48,7 @@ class Table(object):
guessed from the row's value, defaulting to a simple unicode guessed from the row's value, defaulting to a simple unicode
field. field.
:: ::
data = dict(id=10, title='I am a banana!') data = dict(id=10, title='I am a banana!')
table.insert(data, ['id']) table.insert(data, ['id'])
""" """
@ -48,11 +57,13 @@ class Table(object):
self.database.engine.execute(self.table.insert(row)) self.database.engine.execute(self.table.insert(row))
def update(self, row, keys, ensure=True, types={}): def update(self, row, keys, ensure=True, types={}):
""" Update a row in the table. The update is managed via """
Update a row in the table. The update is managed via
the set of column names stated in ``keys``: they will be the set of column names stated in ``keys``: they will be
used as filters for the data to be updated, using the values used as filters for the data to be updated, using the values
in ``row``. in ``row``.
:: ::
# update all entries with id matching 10, setting their title columns # update all entries with id matching 10, setting their title columns
data = dict(id=10, title='I am a banana!') data = dict(id=10, title='I am a banana!')
table.update(data, ['id']) table.update(data, ['id'])
@ -75,9 +86,11 @@ class Table(object):
return False return False
def upsert(self, row, keys, ensure=True, types={}): def upsert(self, row, keys, ensure=True, types={}):
"""An UPSERT is a smart combination of insert and update. If rows with matching ``keys`` exist """
An UPSERT is a smart combination of insert and update. If rows with matching ``keys`` exist
they will be updated, otherwise a new row is inserted in the table. they will be updated, otherwise a new row is inserted in the table.
:: ::
data = dict(id=10, title='I am a banana!') data = dict(id=10, title='I am a banana!')
table.upsert(data, ['id']) table.upsert(data, ['id'])
""" """
@ -88,8 +101,10 @@ class Table(object):
self.insert(row, ensure=ensure, types=types) self.insert(row, ensure=ensure, types=types)
def delete(self, **filter): def delete(self, **filter):
"""Delete rows matching the ``filter`` arguments. """
Delete rows matching the ``filter`` arguments.
:: ::
table.delete(year=2010) table.delete(year=2010)
""" """
q = self._args_to_clause(filter) q = self._args_to_clause(filter)
@ -137,8 +152,10 @@ class Table(object):
return idx return idx
def find_one(self, **filter): def find_one(self, **filter):
"""Works just like :py:meth:`find() <dataset.Table.find>` but returns only one result. """
Works just like :py:meth:`find() <dataset.Table.find>` but returns only one result.
:: ::
row = table.find_one(country='United States') row = table.find_one(country='United States')
""" """
res = list(self.find(_limit=1, **filter)) res = list(self.find(_limit=1, **filter))
@ -154,17 +171,21 @@ class Table(object):
def find(self, _limit=None, _offset=0, _step=5000, def find(self, _limit=None, _offset=0, _step=5000,
order_by='id', **filter): order_by='id', **filter):
"""Performs a simple search on the table. Simply pass keyword arguments as ``filter``. """
Performs a simple search on the table. Simply pass keyword arguments as ``filter``.
:: ::
results = table.find(country='France') results = table.find(country='France')
results = table.find(country='France', year=1980) results = table.find(country='France', year=1980)
Using Using ``_limit``::
# just return the first 10 rows # just return the first 10 rows
results = table.find(country='France', _limit=10) results = table.find(country='France', _limit=10)
You can sort the results by single or multiple columns. Append a minus sign You can sort the results by single or multiple columns. Append a minus sign
to the column name for descending order:: to the column name for descending order::
# sort results by a column 'year' # sort results by a column 'year'
results = table.find(country='France', order_by='year') results = table.find(country='France', order_by='year')
# return all rows sorted by multiple columns (by year in descending order) # return all rows sorted by multiple columns (by year in descending order)
@ -197,9 +218,11 @@ class Table(object):
return d.values().pop() return d.values().pop()
def distinct(self, *columns, **filter): def distinct(self, *columns, **filter):
"""Returns all rows of a table, but removes rows in with duplicate values in ``columns`. """
Returns all rows of a table, but removes rows in with duplicate values in ``columns``.
Interally this creates a `DISTINCT statement <http://www.w3schools.com/sql/sql_distinct.asp>`_. Interally this creates a `DISTINCT statement <http://www.w3schools.com/sql/sql_distinct.asp>`_.
:: ::
# returns only one row per year, ignoring the rest # returns only one row per year, ignoring the rest
table.distinct('year') table.distinct('year')
# works with multiple columns, too # works with multiple columns, too
@ -221,8 +244,10 @@ class Table(object):
return self.database.query(q) return self.database.query(q)
def all(self): def all(self):
"""Returns all rows of the table as simple dictionaries. This is simply a shortcut """
Returns all rows of the table as simple dictionaries. This is simply a shortcut
to *find()* called with no arguments. to *find()* called with no arguments.
:: ::
rows = table.all()""" rows = table.all()"""
return self.find() return self.find()

View File

@ -9,11 +9,11 @@ this guide:
1. put this folder as _themes into your docs folder. Alternatively 1. put this folder as _themes into your docs folder. Alternatively
you can also use git submodules to check out the contents there. you can also use git submodules to check out the contents there.
2. add this to your conf.py: :: 2. add this to your conf.py:
sys.path.append(os.path.abspath('_themes')) sys.path.append(os.path.abspath('_themes'))
html_theme_path = ['_themes'] html_theme_path = ['_themes']
html_theme = 'flask' html_theme = 'kr'
The following themes exist: The following themes exist:

View File

@ -8,12 +8,13 @@ Database
-------- --------
.. autoclass:: dataset.Database .. autoclass:: dataset.Database
:members: get_table, create_table, load_table, query :members: get_table, create_table, load_table, query, tables
:undoc-members: :special-members:
Table Table
----- -----
.. autoclass:: dataset.Table .. autoclass:: dataset.Table
:members: :members: columns, drop, insert, update, upsert, find, find_one, distinct, create_column, create_index, all
:undoc-members: :special-members:

View File

@ -74,9 +74,9 @@ Running custom SQL queries
Of course the main reason you're using a database is that you want to use the full power of SQL queries. Here's how you run them using dataset:: Of course the main reason you're using a database is that you want to use the full power of SQL queries. Here's how you run them using dataset::
result = db.query('SELECT country, COUNT(*) cnt FROM population GROUP BY year') result = db.query('SELECT user, COUNT(*) c FROM photos GROUP BY user ORDER BY c DESC')
for row in res: for row in result:
print row.country, row.cnt print row['user'], row['c']
Freezing your data Freezing your data
------------------ ------------------