diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-10-03 15:25:47 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-10-03 15:25:47 -0400 |
commit | 88f345aa0ab05ac4d35ecf6048e7badc52ff80f7 (patch) | |
tree | 20f1f71f0af3c6ae12fad404d12516403499fcf2 | |
parent | 290064ab235b4ce30b84394db5219f74b69736ea (diff) | |
download | sqlalchemy-88f345aa0ab05ac4d35ecf6048e7badc52ff80f7.tar.gz |
- a CREATE TABLE will put the COLLATE option
after CHARSET, which appears to be part of
MySQL's arbitrary rules regarding if it will actually
work or not. [ticket:2225]
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mysql/base.py | 50 | ||||
-rw-r--r-- | test/dialect/test_mysql.py | 15 |
3 files changed, 50 insertions, 20 deletions
@@ -89,6 +89,11 @@ CHANGES quote symbol "'" for XA commands instead of '"'. [ticket:2186]. + - a CREATE TABLE will put the COLLATE option + after CHARSET, which appears to be part of + MySQL's arbitrary rules regarding if it will actually + work or not. [ticket:2225] + - oracle - Added ORA-00028 to disconnect codes, use cx_oracle _Error.code to get at the code, diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 740b4937d..b2d025bdd 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -174,7 +174,7 @@ from array import array as _array from sqlalchemy.engine import reflection from sqlalchemy.engine import base as engine_base, default from sqlalchemy import types as sqltypes - +from sqlalchemy import topological from sqlalchemy.types import DATE, DATETIME, BOOLEAN, TIME, \ BLOB, BINARY, VARBINARY @@ -1310,25 +1310,35 @@ class MySQLDDLCompiler(compiler.DDLCompiler): """Build table-level CREATE options like ENGINE and COLLATE.""" table_opts = [] - for k in table.kwargs: - if k.startswith('mysql_'): - opt = k[6:].upper() - - arg = table.kwargs[k] - if opt in _options_of_type_string: - arg = "'%s'" % arg.replace("\\", "\\\\").replace("'", "''") - - if opt in ('DATA_DIRECTORY', 'INDEX_DIRECTORY', - 'DEFAULT_CHARACTER_SET', 'CHARACTER_SET', 'DEFAULT_CHARSET', - 'DEFAULT_COLLATE'): - opt = opt.replace('_', ' ') - - joiner = '=' - if opt in ('TABLESPACE', 'DEFAULT CHARACTER SET', - 'CHARACTER SET', 'COLLATE'): - joiner = ' ' - - table_opts.append(joiner.join((opt, arg))) + opts = dict( + ( + k[len(self.dialect.name)+1:].upper(), + v + ) + for k, v in table.kwargs.items() + if k.startswith('%s_' % self.dialect.name) + ) + + for opt in topological.sort([ + ('DEFAULT_CHARSET', 'COLLATE'), + ('DEFAULT_CHARACTER_SET', 'COLLATE') + ], opts): + arg = opts[opt] + if opt in _options_of_type_string: + arg = "'%s'" % arg.replace("\\", "\\\\").replace("'", "''") + + if opt in ('DATA_DIRECTORY', 'INDEX_DIRECTORY', + 'DEFAULT_CHARACTER_SET', 'CHARACTER_SET', + 'DEFAULT_CHARSET', + 'DEFAULT_COLLATE'): + opt = opt.replace('_', ' ') + + joiner = '=' + if opt in ('TABLESPACE', 'DEFAULT CHARACTER SET', + 'CHARACTER SET', 'COLLATE'): + joiner = ' ' + + table_opts.append(joiner.join((opt, arg))) return ' '.join(table_opts) def visit_drop_index(self, drop): diff --git a/test/dialect/test_mysql.py b/test/dialect/test_mysql.py index f1601bbc1..1e4d19d9c 100644 --- a/test/dialect/test_mysql.py +++ b/test/dialect/test_mysql.py @@ -334,6 +334,21 @@ class TypesTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL): charset_table.drop() @testing.exclude('mysql', '<', (5, 0, 5), 'a 5.0+ feature') + @testing.provide_metadata + def test_charset_collate_table(self): + t = Table('foo', metadata, + Column('id', Integer), + mysql_default_charset='utf8', + mysql_collate='utf8_unicode_ci' + ) + t.create() + m2 = MetaData(testing.db) + t2 = Table('foo', m2, autoload=True) + eq_(t2.kwargs['mysql_collate'], 'utf8_unicode_ci') + # note we changed this to have an _ in 0.7.3 + eq_(t2.kwargs['mysql_default charset'], 'utf8') + + @testing.exclude('mysql', '<', (5, 0, 5), 'a 5.0+ feature') @testing.fails_on('mysql+oursql', 'some round trips fail, oursql bug ?') def test_bit_50(self): """Exercise BIT types on 5.0+ (not valid for all engine types)""" |