add Table.create_column_by_example method

This adds a method to create a column by giving an example of
the data it will contain rather than by specifying its
SQLAlchemy type.  This extends the range of operations that
can be performed without reading the SQLAlchemy docs.
This commit is contained in:
Paul Fitzpatrick 2016-10-21 16:59:17 -04:00
parent 6fc8bfed51
commit 94bc6e09c0
2 changed files with 24 additions and 1 deletions

View File

@ -310,6 +310,17 @@ class Table(object):
finally: finally:
self.database._release() self.database._release()
def create_column_by_example(self, name, value):
"""
Explicitly create a new column ``name`` with a type that is appropriate to store
the given example ``value``. The type is guessed in the same way as for the
insert method with ``ensure=True``. If a column of the same name already exists,
no action is taken, even if it is not of the type we would have created.
table.create_column_by_example('length', 4.2)
"""
self._ensure_columns({name: value}, {})
def drop_column(self, name): def drop_column(self, name):
""" """
Drop the column ``name``. Drop the column ``name``.

View File

@ -7,6 +7,7 @@ try:
except ImportError: # pragma: no cover except ImportError: # pragma: no cover
from ordereddict import OrderedDict # Python < 2.7 drop-in from ordereddict import OrderedDict # Python < 2.7 drop-in
from sqlalchemy import FLOAT, INTEGER, TEXT
from sqlalchemy.exc import IntegrityError, SQLAlchemyError from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from dataset import connect from dataset import connect
@ -373,13 +374,24 @@ class TableTestCase(unittest.TestCase):
assert m['temperature'] == -10, 'new temp. should be -10 but is %d' % m['temperature'] assert m['temperature'] == -10, 'new temp. should be -10 but is %d' % m['temperature']
def test_create_column(self): def test_create_column(self):
from sqlalchemy import FLOAT
tbl = self.tbl tbl = self.tbl
tbl.create_column('foo', FLOAT) tbl.create_column('foo', FLOAT)
assert 'foo' in tbl.table.c, tbl.table.c assert 'foo' in tbl.table.c, tbl.table.c
assert isinstance(tbl.table.c['foo'].type, FLOAT), 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 assert 'foo' in tbl.columns, tbl.columns
def test_ensure_column(self):
tbl = self.tbl
tbl.create_column_by_example('foo', 0.1)
assert 'foo' in tbl.table.c, tbl.table.c
assert isinstance(tbl.table.c['foo'].type, FLOAT), tbl.table.c['bar'].type
tbl.create_column_by_example('bar', 1)
assert 'bar' in tbl.table.c, tbl.table.c
assert isinstance(tbl.table.c['bar'].type, INTEGER), tbl.table.c['bar'].type
tbl.create_column_by_example('pippo', 'test')
assert 'pippo' in tbl.table.c, tbl.table.c
assert isinstance(tbl.table.c['pippo'].type, TEXT), tbl.table.c['pippo'].type
def test_key_order(self): def test_key_order(self):
res = self.db.query('SELECT temperature, place FROM weather LIMIT 1') res = self.db.query('SELECT temperature, place FROM weather LIMIT 1')
keys = list(res.next().keys()) keys = list(res.next().keys())