Merge branch 'master' into fix-table-cache

This commit is contained in:
Grzegorz Niewisiewicz 2014-01-27 08:56:28 +01:00
commit a4d676f325
13 changed files with 65 additions and 61 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
*.pyc
*.egg-info
dist/*
build/*
.DS_Store
.watchr

11
.travis.yml Normal file
View File

@ -0,0 +1,11 @@
---
language: python
python:
- '3.3'
- '2.7'
- '2.6'
install:
- pip install flake8
script:
- flake8 --ignore=E501,E123,E124,E126,E127,E128 dataset test
- python setup.py test

View File

@ -8,7 +8,6 @@ from dataset.persistence.util import sqlite_datetime_fix
from dataset.persistence.database import Database
from dataset.persistence.table import Table
from dataset.freeze.app import freeze
from sqlalchemy import Integer, Text
__all__ = ['Database', 'Table', 'freeze', 'connect']

View File

@ -86,4 +86,3 @@ class Export(object):
@property
def name(self):
return self.get('name', self.get('query'))

View File

@ -1,5 +1,4 @@
import os
import logging
import re
import locale
@ -69,8 +68,7 @@ class Serializer(object):
@property
def wrap(self):
return self.export.get_bool('wrap',
default=self.mode=='list')
return self.export.get_bool('wrap', default=self.mode == 'list')
def serialize(self):
self.init()

View File

@ -21,4 +21,3 @@ class TabsonSerializer(JSONSerializer):
if meta is not None:
result['meta'] = meta
return result

View File

@ -11,9 +11,9 @@ except ImportError:
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
from sqlalchemy.schema import MetaData, Column, Index
from sqlalchemy.schema import MetaData, Column
from sqlalchemy.schema import Table as SQLATable
from sqlalchemy import Integer, Text, String
from sqlalchemy import Integer, String
from alembic.migration import MigrationContext
from alembic.operations import Operations
@ -107,10 +107,8 @@ class Database(object):
@property
def tables(self):
""" Get a listing of all tables that exist in the database.
>>> print db.tables
set([u'user', u'action'])
"""
Get a listing of all tables that exist in the database.
"""
return list(
set(self.metadata.tables.keys()) | set(self._tables.keys())

View File

@ -1,9 +1,5 @@
import logging
from itertools import count
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict # Python < 2.7 drop-in
from sqlalchemy.sql import and_, expression
from sqlalchemy.schema import Column, Index
@ -28,9 +24,6 @@ class Table(object):
def columns(self):
"""
Get a listing of all columns that exist in the table.
>>> print 'age' in table.columns
True
"""
return set(self.table.columns.keys())
@ -105,7 +98,6 @@ class Table(object):
if chunk:
_process_chunk(chunk)
def update(self, row, keys, ensure=True, types={}):
"""
Update a row in the table. The update is managed via
@ -288,7 +280,7 @@ class Table(object):
rp = self.database.executable.execute(query)
data = rp.fetchone()
if data is not None:
return OrderedDict(zip(rp.keys(), data))
return data
def _args_to_order_by(self, order_by):
if order_by[0] == '-':
@ -337,6 +329,9 @@ class Table(object):
rp = self.database.executable.execute(count_query)
total_row_count = rp.fetchone()[0]
if _limit is None:
_limit = total_row_count
if _step is None or _step is False or _step == 0:
_step = total_row_count
@ -348,8 +343,6 @@ class Table(object):
for i in count():
qoffset = _offset + (_step * i)
qlimit = _step
if _limit is not None:
qlimit = min(_limit - (_step * i), _step)
if qlimit <= 0:
break

View File

@ -1,9 +1,5 @@
from datetime import datetime, timedelta
from inspect import isgenerator
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict # Python < 2.7 drop-in
from sqlalchemy import Integer, UnicodeText, Float, DateTime, Boolean, types, Table, event
@ -50,7 +46,7 @@ class ResultIter(object):
else:
# stop here
raise StopIteration
return OrderedDict(zip(self.keys, row))
return row
next = __next__
@ -64,6 +60,8 @@ def sqlite_datetime_fix():
epoch = datetime(1970, 1, 1, 0, 0, 0)
def process_bind_param(self, value, dialect):
if isinstance(value, datetime):
return value
return (value / 1000 - self.epoch).total_seconds()
def process_result_value(self, value, dialect):

View File

@ -1,12 +1,12 @@
#coding: utf-8
import re
from unicodedata import normalize as ucnorm, category
SLUG_REMOVE = re.compile(r'[,\s\.\(\)/\\;:]*')
class DatasetException(Exception):
pass
class FreezeException(DatasetException):
pass

View File

@ -25,17 +25,18 @@ setup(
author_email='info@okfn.org',
url='http://github.com/pudo/dataset',
license='MIT',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
packages=find_packages(exclude=['ez_setup', 'examples', 'test']),
namespace_packages=[],
include_package_data=False,
zip_safe=False,
install_requires=[
'sqlalchemy >= 0.8.1',
'alembic >= 0.6.1',
'sqlalchemy >= 0.9.1',
'alembic >= 0.6.2',
'python-slugify >= 0.0.6',
"PyYAML >= 3.10"
] + py26_dependency,
tests_require=[],
test_suite='test',
entry_points={
'console_scripts': [
'datafreeze = dataset.freeze.app:main',

View File

@ -2,15 +2,18 @@ import os
import unittest
from datetime import datetime
from sqlalchemy.exc import IntegrityError
from dataset import connect
from dataset.util import DatasetException
from .sample_data import TEST_DATA, TEST_CITY_1
from sqlalchemy.exc import IntegrityError
class DatabaseTestCase(unittest.TestCase):
def setUp(self):
self.old_db_url = os.environ.get('DATABASE_URL')
os.environ['DATABASE_URL'] = 'sqlite:///:memory:'
self.db = connect('sqlite:///:memory:')
self.tbl = self.db['weather']
@ -19,7 +22,10 @@ class DatabaseTestCase(unittest.TestCase):
def tearDown(self):
# ensure env variable was unset
if self.old_db_url is None:
del os.environ['DATABASE_URL']
else:
os.environ['DATABASE_URL'] = self.old_db_url
def test_valid_database_url(self):
assert self.db.url, os.environ['DATABASE_URL']
@ -187,6 +193,10 @@ class TableTestCase(unittest.TestCase):
assert len(ds) == 3, ds
ds = list(self.tbl.find(place=TEST_CITY_1, _limit=2))
assert len(ds) == 2, ds
ds = list(self.tbl.find(place=TEST_CITY_1, _limit=2, _step=1))
assert len(ds) == 2, ds
ds = list(self.tbl.find(place=TEST_CITY_1, _limit=1, _step=2))
assert len(ds) == 1, ds
def test_distinct(self):
x = list(self.tbl.distinct('place'))
@ -195,8 +205,8 @@ class TableTestCase(unittest.TestCase):
assert len(x) == 6, x
def test_insert_many(self):
data = TEST_DATA * 5000
self.tbl.insert_many(data)
data = TEST_DATA * 100
self.tbl.insert_many(data, chunk_size=13)
assert len(self.tbl) == len(data) + 6
def test_drop_warning(self):
@ -239,7 +249,7 @@ class TableTestCase(unittest.TestCase):
tbl = self.tbl
tbl.create_column('foo', FLOAT)
assert 'foo' in tbl.table.c, tbl.table.c
assert FLOAT == type(tbl.table.c['foo'].type), tbl.table.c['foo'].type
assert isinstance(tbl.table.c['foo'].type, FLOAT), tbl.table.c['foo'].type
assert 'foo' in tbl.columns, tbl.columns
def test_key_order(self):
@ -247,6 +257,3 @@ class TableTestCase(unittest.TestCase):
keys = list(res.next().keys())
assert keys[0] == 'temperature'
assert keys[1] == 'place'
if __name__ == '__main__':
unittest.main()