diff options
-rw-r--r-- | lib/sqlalchemy/databases/mssql.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/postgres.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/sqlite.py | 21 | ||||
-rw-r--r-- | lib/sqlalchemy/engine/default.py | 3 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 15 | ||||
-rw-r--r-- | test/sql/defaults.py | 18 |
6 files changed, 36 insertions, 25 deletions
diff --git a/lib/sqlalchemy/databases/mssql.py b/lib/sqlalchemy/databases/mssql.py index 1ff482cf5..4bbc2caf7 100644 --- a/lib/sqlalchemy/databases/mssql.py +++ b/lib/sqlalchemy/databases/mssql.py @@ -361,6 +361,8 @@ class MSSQLExecutionContext_pyodbc (MSSQLExecutionContext): class MSSQLDialect(default.DefaultDialect): name = 'mssql' + supports_default_values = True + supports_empty_insert = False colspecs = { sqltypes.Unicode : MSNVarchar, diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py index 1c410af53..c8abeb6db 100644 --- a/lib/sqlalchemy/databases/postgres.py +++ b/lib/sqlalchemy/databases/postgres.py @@ -302,6 +302,8 @@ class PGDialect(default.DefaultDialect): preexecute_pk_sequences = True supports_pk_autoincrement = False default_paramstyle = 'pyformat' + supports_default_values = True + supports_empty_insert = False def __init__(self, server_side_cursors=False, **kwargs): default.DefaultDialect.__init__(self, **kwargs) diff --git a/lib/sqlalchemy/databases/sqlite.py b/lib/sqlalchemy/databases/sqlite.py index 70c3f74ec..b3de98100 100644 --- a/lib/sqlalchemy/databases/sqlite.py +++ b/lib/sqlalchemy/databases/sqlite.py @@ -242,6 +242,8 @@ class SQLiteDialect(default.DefaultDialect): supports_alter = False supports_unicode_statements = True default_paramstyle = 'qmark' + supports_default_values = True + supports_empty_insert = False def __init__(self, **kwargs): default.DefaultDialect.__init__(self, **kwargs) @@ -465,25 +467,6 @@ class SQLiteCompiler(compiler.DefaultCompiler): # sqlite has no "FOR UPDATE" AFAICT return '' - def visit_insert(self, insert_stmt): - self.isinsert = True - colparams = self._get_colparams(insert_stmt) - preparer = self.preparer - - if not colparams: - if not self.dialect.supports_default_values: - raise exc.NotSupportedError( - "The version of SQLite you are using, %s, does not support DEFAULT VALUES." % (self.dialect.dbapi.sqlite_version)) - - return ("INSERT INTO %s DEFAULT VALUES" % ( - (preparer.format_table(insert_stmt.table),))) - else: - return ("INSERT INTO %s (%s) VALUES (%s)" % - (preparer.format_table(insert_stmt.table), - ', '.join([preparer.format_column(c[0]) - for c in colparams]), - ', '.join([c[1] for c in colparams]))) - class SQLiteSchemaGenerator(compiler.SchemaGenerator): diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index a90142702..96dadd045 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -39,7 +39,8 @@ class DefaultDialect(base.Dialect): supports_pk_autoincrement = True dbapi_type_map = {} default_paramstyle = 'named' - supports_default_values = True + supports_default_values = False + supports_empty_insert = True def __init__(self, convert_unicode=False, assert_unicode=False, encoding='utf-8', paramstyle=None, dbapi=None, **kwargs): self.convert_unicode = convert_unicode diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 0117b96ff..2072d5a27 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -570,11 +570,18 @@ class DefaultCompiler(engine.Compiled): insert = ' '.join(["INSERT"] + [self.process(x) for x in insert_stmt._prefixes]) - return (insert + " INTO %s (%s) VALUES (%s)" % + if not colparams and not self.dialect.supports_default_values and not self.dialect.supports_empty_insert: + raise exc.NotSupportedError( + "The version of %s you are using does not support empty inserts." % self.dialect.name) + elif not colparams and self.dialect.supports_default_values: + return (insert + " INTO %s DEFAULT VALUES" % ( + (preparer.format_table(insert_stmt.table),))) + else: + return (insert + " INTO %s (%s) VALUES (%s)" % (preparer.format_table(insert_stmt.table), - ', '.join(preparer.quote(c[0].name, c[0].quote) - for c in colparams), - ', '.join(c[1] for c in colparams))) + ', '.join([preparer.format_column(c[0]) + for c in colparams]), + ', '.join([c[1] for c in colparams]))) def visit_update(self, update_stmt): self.stack.append({'from': set([update_stmt.table])}) diff --git a/test/sql/defaults.py b/test/sql/defaults.py index 4f0f929f1..169d60c67 100644 --- a/test/sql/defaults.py +++ b/test/sql/defaults.py @@ -1,8 +1,9 @@ import testenv; testenv.configure_for_tests() import datetime from sqlalchemy import Sequence, Column, func +from sqlalchemy.sql import select, text from testlib import sa, testing -from testlib.sa import MetaData, Table, Integer, String, ForeignKey +from testlib.sa import MetaData, Table, Integer, String, ForeignKey, Boolean from testlib.testing import eq_ from sql import _base @@ -472,6 +473,21 @@ class PKIncrementTest(_base.TablesTest): con.close() +class EmptyInsertTest(testing.TestBase): + @testing.exclude('sqlite', '<', (3, 3, 8), 'no empty insert support') + def test_empty_insert(self): + metadata = MetaData(testing.db) + t1 = Table('t1', metadata, + Column('is_true', Boolean, server_default=('1'))) + metadata.create_all() + + try: + result = t1.insert().execute() + self.assertEquals(1, select([func.count(text('*'))], from_obj=t1).scalar()) + self.assertEquals(True, t1.select().scalar()) + finally: + metadata.drop_all() + class AutoIncrementTest(_base.TablesTest): __requires__ = ('identity',) run_define_tables = 'each' |