Merge remote-tracking branch 'upstream/master'

This commit is contained in:
xrotwang 2014-11-06 10:13:04 +01:00
commit 4bf19159c6
6 changed files with 15 additions and 7 deletions

View File

@ -18,12 +18,14 @@ def connect(url=None, schema=None, reflectMetadata=True, engine_kwargs=None):
If *url* is not defined it will try to use *DATABASE_URL* from environment variable. If *url* is not defined it will try to use *DATABASE_URL* from environment variable.
Returns an instance of :py:class:`Database <dataset.Database>`. Set *reflectMetadata* to False if you Returns an instance of :py:class:`Database <dataset.Database>`. Set *reflectMetadata* to False if you
don't want the entire database schema to be pre-loaded. This significantly speeds up don't want the entire database schema to be pre-loaded. This significantly speeds up
connecting to large databases with lots of tables. connecting to large databases with lots of tables. Additionally, *engine_kwargs* will be directly passed to
SQLAlchemy, e.g. set *engine_kwargs={'pool_recycle': 3600}* will avoid `DB connection timeout`_.
:: ::
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
.. _DB connection timeout: http://docs.sqlalchemy.org/en/latest/core/pooling.html#setting-pool-recycle
""" """
if url is None: if url is None:
url = os.environ.get('DATABASE_URL', url) url = os.environ.get('DATABASE_URL', url)

View File

@ -80,7 +80,7 @@ class Database(object):
self.local.must_release = True self.local.must_release = True
def _release_internal(self): def _release_internal(self):
if not hasattr(self.local, 'must_release') and self.local.must_release: if getattr(self.local, 'must_release', None):
self.lock.release() self.lock.release()
self.local.must_release = False self.local.must_release = False
@ -141,6 +141,9 @@ class Database(object):
set(self.metadata.tables.keys()) | set(self._tables.keys()) set(self.metadata.tables.keys()) | set(self._tables.keys())
) )
def __contains__(self, member):
return member in self.tables
def create_table(self, table_name, primary_id='id', primary_type='Integer'): def create_table(self, table_name, primary_id='id', primary_type='Integer'):
""" """
Creates a new table. The new table will automatically have an `id` column Creates a new table. The new table will automatically have an `id` column
@ -253,7 +256,7 @@ class Database(object):
""" """
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 <http://docs.sqlalchemy.org/ru/latest/core/tutorial.html#selecting>`_. The returned a plain text string, or a `SQLAlchemy expression <http://docs.sqlalchemy.org/en/latest/core/tutorial.html#selecting>`_. The returned
iterator will yield each result sequentially. iterator will yield each result sequentially.
Any keyword arguments will be passed into the query to perform Any keyword arguments will be passed into the query to perform

View File

@ -1,4 +1,4 @@
<a style="border:0" href="index.html"><img src="_static/dataset-logo.png" alt="dataset" /></a> <a style="border:0" href="index.html"><img src="{{ pathto('_static/dataset-logo.png', 1) }}" alt="dataset" /></a>
<p style="font-style:italic;font-size:0.9em; text-align:center; margin-bottom:1.5em">Because managing databases in Python should be as simple as reading and writing JSON files.</p> <p style="font-style:italic;font-size:0.9em; text-align:center; margin-bottom:1.5em">Because managing databases in Python should be as simple as reading and writing JSON files.</p>

View File

@ -75,7 +75,7 @@ statement::
with dataset.connect() as tx: with dataset.connect() as tx:
tx['user'].insert(dict(name='John Doe', age=46, country='China')) tx['user'].insert(dict(name='John Doe', age=46, country='China'))
You can get same functionality by invocing the methods :py:meth:`begin() <dataset.Table.begin>`, You can get same functionality by invoking the methods :py:meth:`begin() <dataset.Table.begin>`,
:py:meth:`commit() <dataset.Table.commit>` and :py:meth:`rollback() <dataset.Table.rollback>` :py:meth:`commit() <dataset.Table.commit>` and :py:meth:`rollback() <dataset.Table.rollback>`
explicitly:: explicitly::
@ -92,7 +92,7 @@ Nested transactions are supported too::
db = dataset.connect() db = dataset.connect()
with db as tx1: with db as tx1:
tx1['user'].insert(dict(name='John Doe', age=46, country='China')) tx1['user'].insert(dict(name='John Doe', age=46, country='China'))
with db sa tx2: with db as tx2:
tx2['user'].insert(dict(name='Jane Doe', age=37, country='France', gender='female')) tx2['user'].insert(dict(name='Jane Doe', age=37, country='France', gender='female'))

View File

@ -8,7 +8,7 @@ if sys.version_info[:2] <= (2, 6):
setup( setup(
name='dataset', name='dataset',
version='0.5.4', version='0.5.5',
description="Toolkit for Python-based data processing.", description="Toolkit for Python-based data processing.",
long_description="", long_description="",
classifiers=[ classifiers=[

View File

@ -38,6 +38,9 @@ class DatabaseTestCase(unittest.TestCase):
def test_tables(self): def test_tables(self):
assert self.db.tables == ['weather'], self.db.tables assert self.db.tables == ['weather'], self.db.tables
def test_contains(self):
assert 'weather' in self.db, self.db.tables
def test_create_table(self): def test_create_table(self):
table = self.db['foo'] table = self.db['foo']
assert table.table.exists() assert table.table.exists()