From 9561321d0328df270c4ff0360dc7a035db627949 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 17 Dec 2014 17:24:23 -0500 Subject: - squash-merge the improve_toc branch, which moves all the Sphinx styling and extensions into an external library, and also reorganizes most large documentation pages into many small areas to reduce scrolling and better present the context into a more fine-grained hierarchy. --- lib/sqlalchemy/dialects/sqlite/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/sqlalchemy/dialects/sqlite/base.py') diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index e79299527..e0b2875e8 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -108,7 +108,7 @@ file-based architecture and additionally will usually require workarounds to work when using the pysqlite driver. Transaction Isolation Level -=========================== +---------------------------- SQLite supports "transaction isolation" in a non-standard way, along two axes. One is that of the `PRAGMA read_uncommitted `_ @@ -141,7 +141,7 @@ by *not even emitting BEGIN* until the first write operation. for techniques to work around this behavior. SAVEPOINT Support -================= +---------------------------- SQLite supports SAVEPOINTs, which only function once a transaction is begun. SQLAlchemy's SAVEPOINT support is available using the @@ -157,7 +157,7 @@ won't work at all with pysqlite unless workarounds are taken. for techniques to work around this behavior. Transactional DDL -================= +---------------------------- The SQLite database supports transactional :term:`DDL` as well. In this case, the pysqlite driver is not only failing to start transactions, -- cgit v1.2.1 From 21f47124ab433cc74fa0a72efcc8a6c1e9c37db5 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 1 Jan 2015 13:47:08 -0500 Subject: - restate sort_tables in terms of a more fine grained sort_tables_and_constraints function. - The DDL generation system of :meth:`.MetaData.create_all` and :meth:`.Metadata.drop_all` has been enhanced to in most cases automatically handle the case of mutually dependent foreign key constraints; the need for the :paramref:`.ForeignKeyConstraint.use_alter` flag is greatly reduced. The system also works for constraints which aren't given a name up front; only in the case of DROP is a name required for at least one of the constraints involved in the cycle. fixes #3282 --- lib/sqlalchemy/dialects/sqlite/base.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib/sqlalchemy/dialects/sqlite/base.py') diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index e0b2875e8..3d7b0788b 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -201,6 +201,15 @@ new connections through the usage of events:: cursor.execute("PRAGMA foreign_keys=ON") cursor.close() +.. warning:: + + When SQLite foreign keys are enabled, it is **not possible** + to emit CREATE or DROP statements for tables that contain + mutually-dependent foreign key constraints; + to emit the DDL for these tables requires that ALTER TABLE be used to + create or drop these constraints separately, for which SQLite has + no support. + .. seealso:: `SQLite Foreign Key Support `_ @@ -208,6 +217,9 @@ new connections through the usage of events:: :ref:`event_toplevel` - SQLAlchemy event API. + :ref:`use_alter` - more information on SQLAlchemy's facilities for handling + mutually-dependent foreign key constraints. + .. _sqlite_type_reflection: Type Reflection -- cgit v1.2.1 From f3a892a3ef666e299107a990bf4eae7ed9a953ae Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 16 Jan 2015 20:03:33 -0500 Subject: - Custom dialects that implement :class:`.GenericTypeCompiler` can now be constructed such that the visit methods receive an indication of the owning expression object, if any. Any visit method that accepts keyword arguments (e.g. ``**kw``) will in most cases receive a keyword argument ``type_expression``, referring to the expression object that the type is contained within. For columns in DDL, the dialect's compiler class may need to alter its ``get_column_specification()`` method to support this as well. The ``UserDefinedType.get_col_spec()`` method will also receive ``type_expression`` if it provides ``**kw`` in its argument signature. fixes #3074 --- lib/sqlalchemy/dialects/sqlite/base.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'lib/sqlalchemy/dialects/sqlite/base.py') diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 3d7b0788b..f74421967 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -660,7 +660,8 @@ class SQLiteCompiler(compiler.SQLCompiler): class SQLiteDDLCompiler(compiler.DDLCompiler): def get_column_specification(self, column, **kwargs): - coltype = self.dialect.type_compiler.process(column.type) + coltype = self.dialect.type_compiler.process( + column.type, type_expression=column) colspec = self.preparer.format_column(column) + " " + coltype default = self.get_column_default_string(column) if default is not None: @@ -716,24 +717,24 @@ class SQLiteDDLCompiler(compiler.DDLCompiler): class SQLiteTypeCompiler(compiler.GenericTypeCompiler): - def visit_large_binary(self, type_): + def visit_large_binary(self, type_, **kw): return self.visit_BLOB(type_) - def visit_DATETIME(self, type_): + def visit_DATETIME(self, type_, **kw): if not isinstance(type_, _DateTimeMixin) or \ type_.format_is_text_affinity: return super(SQLiteTypeCompiler, self).visit_DATETIME(type_) else: return "DATETIME_CHAR" - def visit_DATE(self, type_): + def visit_DATE(self, type_, **kw): if not isinstance(type_, _DateTimeMixin) or \ type_.format_is_text_affinity: return super(SQLiteTypeCompiler, self).visit_DATE(type_) else: return "DATE_CHAR" - def visit_TIME(self, type_): + def visit_TIME(self, type_, **kw): if not isinstance(type_, _DateTimeMixin) or \ type_.format_is_text_affinity: return super(SQLiteTypeCompiler, self).visit_TIME(type_) -- cgit v1.2.1 From c3d898e8d06c7e549bb273fc8654f5d24fab2204 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 20 Jan 2015 11:37:13 -0500 Subject: - Added new user-space accessors for viewing transaction isolation levels; :meth:`.Connection.get_isolation_level`, :attr:`.Connection.default_isolation_level`. - enhance documentation inter-linkage between new accessors, existing isolation_level parameters, as well as in the dialect-level methods which should be fully covered by Engine/Connection level APIs now. --- lib/sqlalchemy/dialects/sqlite/base.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/sqlalchemy/dialects/sqlite/base.py') diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index f74421967..1ed89bacb 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -107,6 +107,8 @@ The following subsections introduce areas that are impacted by SQLite's file-based architecture and additionally will usually require workarounds to work when using the pysqlite driver. +.. _sqlite_isolation_level: + Transaction Isolation Level ---------------------------- -- cgit v1.2.1 From 30ce7e93f4068b00ced0db785fdd578dc8a45975 Mon Sep 17 00:00:00 2001 From: Kai Groner Date: Mon, 26 Jan 2015 14:49:40 -0500 Subject: Partial index support with sqlite dialects. From https://www.sqlite.org/partialindex.html > Partial indexes have been supported in SQLite since version 3.8.0. Reflection does not expose the predicate of partial indexes. The postgresql dialect does detect such indexes and issue a warning. I looked into matching this level of support, but the sqlite pragma index_info does not expose the predicate. Getting this data would probably require parsing the CREATE INDEX statement from sqlite_master. --- lib/sqlalchemy/dialects/sqlite/base.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'lib/sqlalchemy/dialects/sqlite/base.py') diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 1ed89bacb..437a7794a 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -714,9 +714,20 @@ class SQLiteDDLCompiler(compiler.DDLCompiler): return preparer.format_table(table, use_schema=False) def visit_create_index(self, create): - return super(SQLiteDDLCompiler, self).visit_create_index( + index = create.element + + text = super(SQLiteDDLCompiler, self).visit_create_index( create, include_table_schema=False) + whereclause = index.dialect_options["sqlite"]["where"] + if whereclause is not None: + where_compiled = self.sql_compiler.process( + whereclause, include_table=False, + literal_binds=True) + text += " WHERE " + where_compiled + + return text + class SQLiteTypeCompiler(compiler.GenericTypeCompiler): def visit_large_binary(self, type_, **kw): @@ -823,7 +834,10 @@ class SQLiteDialect(default.DefaultDialect): construct_arguments = [ (sa_schema.Table, { "autoincrement": False - }) + }), + (sa_schema.Index, { + "where": None, + }), ] _broken_fk_pragma_quotes = False -- cgit v1.2.1