From 8c05a3bf6599f92bbf8d2246123597e8966f3a52 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 18 Jan 2012 12:42:54 -0500 Subject: [PATCH] - [feature] Added "false()" and "true()" expression constructs to sqlalchemy.sql namespace, though not part of __all__ as of yet. - [bug] sql.false() and sql.true() compile to 0 and 1, respectively in sqlite [ticket:2368] --- CHANGES | 8 ++++++++ lib/sqlalchemy/dialects/sqlite/base.py | 6 ++++++ lib/sqlalchemy/sql/__init__.py | 2 ++ test/dialect/test_sqlite.py | 21 +++++++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/CHANGES b/CHANGES index 5df9001990..37b06a1108 100644 --- a/CHANGES +++ b/CHANGES @@ -32,6 +32,11 @@ CHANGES - [bug] ensure pickleability of all ORM exceptions for multiprocessing compatibility. [ticket:2371] +- sql + - [feature] Added "false()" and "true()" expression + constructs to sqlalchemy.sql namespace, though + not part of __all__ as of yet. + - engine - [bug] Added __reduce__ to StatementError, DBAPIError, column errors so that exceptions @@ -47,6 +52,9 @@ CHANGES SQLite does not appear to support constraint naming in any case. + - [bug] sql.false() and sql.true() compile to + 0 and 1, respectively in sqlite [ticket:2368] + - mysql - [bug] fixed regexp that filters out warnings for non-reflected "PARTITION" directives, diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index aea1448523..06c41b2eef 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -302,6 +302,12 @@ class SQLiteCompiler(compiler.SQLCompiler): def visit_now_func(self, fn, **kw): return "CURRENT_TIMESTAMP" + def visit_true(self, expr, **kw): + return '1' + + def visit_false(self, expr, **kw): + return '0' + def visit_char_length_func(self, fn, **kw): return "length%s" % self.function_argspec(fn) diff --git a/lib/sqlalchemy/sql/__init__.py b/lib/sqlalchemy/sql/__init__.py index e82d072c11..eac845dcdb 100644 --- a/lib/sqlalchemy/sql/__init__.py +++ b/lib/sqlalchemy/sql/__init__.py @@ -34,6 +34,7 @@ from sqlalchemy.sql.expression import ( except_all, exists, extract, + false, func, insert, intersect, @@ -53,6 +54,7 @@ from sqlalchemy.sql.expression import ( subquery, table, text, + true, tuple_, type_coerce, union, diff --git a/test/dialect/test_sqlite.py b/test/dialect/test_sqlite.py index 7a5953654d..4fe67fd2ea 100644 --- a/test/dialect/test_sqlite.py +++ b/test/dialect/test_sqlite.py @@ -259,6 +259,18 @@ class DefaultsTest(fixtures.TestBase, AssertsCompiledSQL): finally: db.execute("DROP TABLE r_defaults") + @testing.provide_metadata + def test_boolean_default(self): + t= Table("t", self.metadata, + Column("x", Boolean, server_default=sql.false())) + t.create(testing.db) + testing.db.execute(t.insert()) + testing.db.execute(t.insert().values(x=True)) + eq_( + testing.db.execute(t.select().order_by(t.c.x)).fetchall(), + [(False,), (True,)] + ) + class DialectTest(fixtures.TestBase, AssertsExecutionResults): @@ -440,6 +452,15 @@ class SQLTest(fixtures.TestBase, AssertsCompiledSQL): "SELECT CAST(STRFTIME('%s', t.col1) AS " "INTEGER) AS anon_1 FROM t" % subst) + def test_true_false(self): + self.assert_compile( + sql.false(), "0" + ) + self.assert_compile( + sql.true(), + "1" + ) + def test_constraints_with_schemas(self): metadata = MetaData() t1 = Table('t1', metadata, -- 2.47.2