diff options
author | Javier Santacruz <javier.santacruz.lc@gmail.com> | 2013-10-17 17:24:28 +0200 |
---|---|---|
committer | Javier Santacruz <javier.santacruz.lc@gmail.com> | 2013-10-17 17:24:28 +0200 |
commit | 227f1404a4012c52f75b270f237c6c6bc0579cc3 (patch) | |
tree | 7a936083c8b84b97c0690e049d6da97076761f18 | |
parent | c84e3f1fd76a9fa7d8ee6221a21b7ed9188ba2f3 (diff) | |
download | alembic-227f1404a4012c52f75b270f237c6c6bc0579cc3.tar.gz |
Fixes stdout --sql output in python2
When output_encoding is set, wraps the output buffer into a io.TextIOWrapper class
This means that the output_buffer has to be a io.IOBase instance
in order to work along with the TextIOWrapper
Handles wrapping when the buffer is Python2 stdtout, which has 'file' type
Adds test for this situation
-rw-r--r-- | alembic/compat.py | 8 | ||||
-rw-r--r-- | alembic/migration.py | 11 | ||||
-rw-r--r-- | tests/test_offline_environment.py | 13 |
3 files changed, 27 insertions, 5 deletions
diff --git a/alembic/compat.py b/alembic/compat.py index 7d0357d..fc88933 100644 --- a/alembic/compat.py +++ b/alembic/compat.py @@ -1,3 +1,4 @@ +import io import sys from sqlalchemy import __version__ as sa_version @@ -78,3 +79,10 @@ def with_metaclass(meta, base=object): """Create a base class with a metaclass.""" return meta("%sBase" % meta.__name__, (base,), {}) ################################################ + +if py2k: + def writable_buffer(file): + return io.FileIO(file.fileno(), 'w') +else: + def writable_buffer(file): + return file diff --git a/alembic/migration.py b/alembic/migration.py index 2b47c91..657e60d 100644 --- a/alembic/migration.py +++ b/alembic/migration.py @@ -6,7 +6,7 @@ from sqlalchemy import MetaData, Table, Column, String, literal_column from sqlalchemy import create_engine from sqlalchemy.engine import url as sqla_url -from .compat import callable +from .compat import callable, writable_buffer from . import ddl, util log = logging.getLogger(__name__) @@ -71,13 +71,14 @@ class MigrationContext(object): self.connection = connection self._migrations_fn = opts.get('fn') self.as_sql = as_sql + self.output_buffer = opts.get("output_buffer", sys.stdout) - if opts.get('output_encoding'): + if "output_encoding" in opts: self.output_buffer = io.TextIOWrapper( - self.output_buffer, - opts['output_encoding'] - ) + opts.get("output_buffer") or writable_buffer(sys.stdout), + opts.get('output_encoding') + ) self._user_compare_type = opts.get('compare_type', False) self._user_compare_server_default = opts.get( diff --git a/tests/test_offline_environment.py b/tests/test_offline_environment.py index 4a727d3..da2589c 100644 --- a/tests/test_offline_environment.py +++ b/tests/test_offline_environment.py @@ -1,3 +1,4 @@ +import io from unittest import TestCase from alembic import command, util @@ -11,6 +12,7 @@ class OfflineEnvironmentTest(TestCase): def setUp(self): env = staging_env() self.cfg = _no_sql_testing_config() + self.cfg.output_buffer = io.StringIO() global a, b, c a, b, c = three_rev_fixture(self.cfg) @@ -41,6 +43,8 @@ assert context.get_starting_revision_argument() == 'x' command.upgrade(self.cfg, a, sql=True) command.downgrade(self.cfg, "%s:%s" % (b, a), sql=True) command.current(self.cfg) + # current seems to close the buffer (?) + self.cfg.output_buffer = io.StringIO() command.stamp(self.cfg, a) def test_starting_rev_pre_context(self): @@ -153,3 +157,12 @@ context.configure(dialect_name='sqlite') command.downgrade, self.cfg, b, sql=True ) + + def test_upgrade_with_output_encoding(self): + env_file_fixture(""" +url = config.get_main_option('sqlalchemy.url') +context.configure(url=url, output_encoding='utf-8') +assert not context.requires_connection() +""") + command.upgrade(self.cfg, a, sql=True) + command.downgrade(self.cfg, "%s:%s" % (b, a), sql=True) |