From: Jason Kirtland Date: Fri, 19 Oct 2007 07:02:48 +0000 (+0000) Subject: Fixed empty (zero column) sqlite inserts, allowing inserts on X-Git-Tag: rel_0_4_1~128 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=974f59f091d562bb0e141c6b4087160d16190c1c;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Fixed empty (zero column) sqlite inserts, allowing inserts on autoincrementing single column tables. --- diff --git a/CHANGES b/CHANGES index f86adc4c6c..eab3ec1374 100644 --- a/CHANGES +++ b/CHANGES @@ -1,13 +1,19 @@ ======= CHANGES ======= + 0.4.1 ----- -- added test coverage for unknown type reflection, fixed - sqlite/mysql handling of type reflection for unknown types + +- Added test coverage for unknown type reflection, fixed sqlite/mysql + handling of type reflection for unknown types. + +- Fixed empty (zero column) sqlite inserts, allowing inserts on + autoincrementing single column tables. 0.4.0 ----- + - (see 0.4.0beta1 for the start of major changes against 0.3, as well as http://www.sqlalchemy.org/trac/wiki/WhatsNewIn04 ) diff --git a/lib/sqlalchemy/databases/sqlite.py b/lib/sqlalchemy/databases/sqlite.py index 99a1d56503..6666f60669 100644 --- a/lib/sqlalchemy/databases/sqlite.py +++ b/lib/sqlalchemy/databases/sqlite.py @@ -362,6 +362,21 @@ 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: + 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/test/dialect/sqlite.py b/test/dialect/sqlite.py index 43ee9e6a35..e401859bc2 100644 --- a/test/dialect/sqlite.py +++ b/test/dialect/sqlite.py @@ -3,6 +3,7 @@ import testbase import datetime from sqlalchemy import * +from sqlalchemy import exceptions from sqlalchemy.databases import sqlite from testlib import * @@ -85,5 +86,67 @@ class DialectTest(AssertMixin): testbase.db.execute("drop table django_content_type") +class InsertTest(AssertMixin): + """Tests inserts and autoincrement.""" + + def _test_empty_insert(self, table, expect=1): + try: + table.create() + for wanted in (expect, expect * 2): + + table.insert().execute() + + rows = table.select().execute().fetchall() + print rows + self.assertEquals(len(rows), wanted) + finally: + table.drop() + + @testing.supported('sqlite') + def test_empty_insert_pk1(self): + self._test_empty_insert( + Table('a', MetaData(testbase.db), + Column('id', Integer, primary_key=True))) + + @testing.supported('sqlite') + def test_empty_insert_pk2(self): + self.assertRaises( + exceptions.DBAPIError, + self._test_empty_insert, + Table('b', MetaData(testbase.db), + Column('x', Integer, primary_key=True), + Column('y', Integer, primary_key=True))) + + @testing.supported('sqlite') + def test_empty_insert_pk3(self): + self.assertRaises( + exceptions.DBAPIError, + self._test_empty_insert, + Table('c', MetaData(testbase.db), + Column('x', Integer, primary_key=True), + Column('y', Integer, PassiveDefault('123'), + primary_key=True))) + + @testing.supported('sqlite') + def test_empty_insert_pk4(self): + self._test_empty_insert( + Table('d', MetaData(testbase.db), + Column('x', Integer, primary_key=True), + Column('y', Integer, PassiveDefault('123')))) + + @testing.supported('sqlite') + def test_empty_insert_nopk1(self): + self._test_empty_insert( + Table('e', MetaData(testbase.db), + Column('id', Integer))) + + @testing.supported('sqlite') + def test_empty_insert_nopk2(self): + self._test_empty_insert( + Table('f', MetaData(testbase.db), + Column('x', Integer), + Column('y', Integer))) + + if __name__ == "__main__": testbase.main()