]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add placeholder XML support
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 26 May 2017 15:24:25 +0000 (11:24 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 26 May 2017 15:24:25 +0000 (11:24 -0400)
Added a placeholder type :class:`.mssql.XML` to the SQL Server
dialect, so that a reflected table which includes this type can
be re-rendered as a CREATE TABLE.  The type has no special round-trip
behavior nor does it currently support additional qualifying
arguments.

Change-Id: I651fa729bd8e9b31a0b5effe0839aff077d77c46
Fixes: #3973
doc/build/changelog/changelog_11.rst
doc/build/dialects/mssql.rst
lib/sqlalchemy/dialects/mssql/base.py
test/dialect/mssql/test_reflection.py

index 66f6bb45ade286297e2c6e2da851afc08dfcb952..cde9b45ccebc5ece2557900ca42801893638f415 100644 (file)
         any case, and cx_Oracle 6.x has removed the connection-level "twophase"
         flag upon which this feature relied.
 
+    .. change:: 3973
+        :tags: bug, mssql
+        :tickets: 3973
+        :versions: 1.2.0b1
+
+        Added a placeholder type :class:`.mssql.XML` to the SQL Server
+        dialect, so that a reflected table which includes this type can
+        be re-rendered as a CREATE TABLE.  The type has no special round-trip
+        behavior nor does it currently support additional qualifying
+        arguments.
+
 .. changelog::
     :version: 1.1.10
     :released: Friday, May 19, 2017
index 490ecaccf55007786f61066380c5e21a1b48a6e0..acc9710e52dc8390935e13a70bccc8f3d12aa1ea 100644 (file)
@@ -26,75 +26,78 @@ construction arguments, are as follows:
 
 .. autoclass:: BIT
    :members: __init__
-    
+
 
 .. autoclass:: CHAR
    :members: __init__
-    
+
 
 .. autoclass:: DATETIME2
    :members: __init__
-    
+
 
 .. autoclass:: DATETIMEOFFSET
    :members: __init__
-    
+
 
 .. autoclass:: IMAGE
    :members: __init__
-    
+
 
 .. autoclass:: MONEY
    :members: __init__
-    
+
 
 .. autoclass:: NCHAR
    :members: __init__
-    
+
 
 .. autoclass:: NTEXT
    :members: __init__
-    
+
 
 .. autoclass:: NVARCHAR
    :members: __init__
-    
+
 
 .. autoclass:: REAL
    :members: __init__
-    
+
 
 .. autoclass:: SMALLDATETIME
    :members: __init__
-    
+
 
 .. autoclass:: SMALLMONEY
    :members: __init__
-    
+
 
 .. autoclass:: SQL_VARIANT
    :members: __init__
-    
+
 
 .. autoclass:: TEXT
    :members: __init__
-    
+
 
 .. autoclass:: TIME
    :members: __init__
-    
+
 
 .. autoclass:: TINYINT
    :members: __init__
-    
+
 
 .. autoclass:: UNIQUEIDENTIFIER
    :members: __init__
-    
+
 
 .. autoclass:: VARCHAR
    :members: __init__
-    
+
+
+.. autoclass:: XML
+   :members: __init__
 
 
 PyODBC
index 0399cbd90dc2a5f0059c69e057f66d3eef4b8ab9..00c43bba6a65a7ae6eb803362665a6db5c68a81a 100644 (file)
@@ -830,6 +830,20 @@ class IMAGE(sqltypes.LargeBinary):
     __visit_name__ = 'IMAGE'
 
 
+class XML(sqltypes.Text):
+    """MSSQL XML type.
+
+    This is a placeholder type for reflection purposes that does not include
+    any Python-side datatype support.   It also does not currently support
+    additional arguments, such as "CONTENT", "DOCUMENT",
+    "xml_schema_collection".
+
+    .. versionadded:: 1.1.11
+
+    """
+    __visit_name__ = 'XML'
+
+
 class BIT(sqltypes.TypeEngine):
     __visit_name__ = 'BIT'
 
@@ -898,6 +912,7 @@ ischema_names = {
     'bit': BIT,
     'real': REAL,
     'image': IMAGE,
+    'xml': XML,
     'timestamp': TIMESTAMP,
     'money': MONEY,
     'smallmoney': SMALLMONEY,
@@ -1014,6 +1029,9 @@ class MSTypeCompiler(compiler.GenericTypeCompiler):
     def visit_IMAGE(self, type_, **kw):
         return "IMAGE"
 
+    def visit_XML(self, type_, **kw):
+        return "XML"
+
     def visit_VARBINARY(self, type_, **kw):
         return self._extend(
             "VARBINARY",
index 5e17709b4e351b730b50cde1ed612685b8c77acb..2f705d8a3602e9cb22716bc20ad95f2cefce7494 100644 (file)
@@ -11,9 +11,9 @@ from sqlalchemy.engine.reflection import Inspector
 from sqlalchemy import util
 from sqlalchemy.dialects.mssql.information_schema import CoerceUnicode, tables
 from sqlalchemy.dialects.mssql import base
+from sqlalchemy.testing import mock
 
-
-class ReflectionTest(fixtures.TestBase, ComparesTables):
+class ReflectionTest(fixtures.TestBase, ComparesTables, AssertsCompiledSQL):
     __only_on__ = 'mssql'
     __backend__ = True
 
@@ -63,6 +63,32 @@ class ReflectionTest(fixtures.TestBase, ComparesTables):
         self.assert_tables_equal(users, reflected_users)
         self.assert_tables_equal(addresses, reflected_addresses)
 
+    @testing.provide_metadata
+    def _test_specific_type(self, type_obj, ddl):
+        metadata = self.metadata
+
+        table = Table(
+            'type_test', metadata,
+            Column('col1', type_obj)
+        )
+        table.create()
+
+        m2 = MetaData()
+        table2 = Table('type_test', m2, autoload_with=testing.db)
+        self.assert_compile(
+            schema.CreateTable(table2),
+            "CREATE TABLE type_test (col1 %s NULL)" % ddl
+        )
+
+    def test_xml_type(self):
+        self._test_specific_type(mssql.XML, "XML")
+
+    def test_image_type(self):
+        self._test_specific_type(mssql.IMAGE, "IMAGE")
+
+    def test_money_type(self):
+        self._test_specific_type(mssql.MONEY, "MONEY")
+
     @testing.provide_metadata
     def test_identity(self):
         metadata = self.metadata
@@ -86,7 +112,9 @@ class ReflectionTest(fixtures.TestBase, ComparesTables):
         testing.db.execute("""
             create table foo (id integer primary key, data xml)
         """)
-        t1 = Table('foo', metadata, autoload=True)
+        with mock.patch.object(
+                testing.db.dialect, "ischema_names", {"int": mssql.INTEGER}):
+            t1 = Table('foo', metadata, autoload=True)
         assert isinstance(t1.c.id.type, Integer)
         assert isinstance(t1.c.data.type, types.NullType)