Commits

Anonymous committed f8c3501

- Rewrote the query used to get the definition of a view,
typically when using the Inspector interface, to
use sys.sql_modules instead of the information schema,
thereby allowing views definitions longer than 4000
characters to be fully returned. [ticket:2071]

Comments (0)

Files changed (3)

 
   - Added RESERVED_WORDS informix dialect. [ticket:2092]
 
+- mssql
+  - Rewrote the query used to get the definition of a view,
+    typically when using the Inspector interface, to
+    use sys.sql_modules instead of the information schema,
+    thereby allowing views definitions longer than 4000 
+    characters to be fully returned.  [ticket:2071]
+
 - mysql
   - oursql dialect accepts the same "ssl" arguments in 
     create_engine() as that of MySQLdb.  [ticket:2047]

lib/sqlalchemy/dialects/mssql/base.py

         # ...,
         implicit_returning=False
     )
-    
+
 Declarative form::
 
     class MyClass(Base):
         # ...
         __table_args__ = {'implicit_returning':False}
-        
-        
+
+
 This option can also be specified engine-wide using the
 ``implicit_returning=False`` argument on :func:`.create_engine`.
 
     @reflection.cache
     def get_view_definition(self, connection, viewname, schema=None, **kw):
         current_schema = schema or self.default_schema_name
-        views = ischema.views
-        s = sql.select([views.c.view_definition],
-            sql.and_(
-                views.c.table_schema == current_schema,
-                views.c.table_name == viewname
-            ),
+
+        rp = connection.execute(
+            sql.text(
+                "select definition from sys.sql_modules as mod, "
+                "sys.views as views, "
+                "sys.schemas as sch"
+                " where "
+                "mod.object_id=views.object_id and "
+                "views.schema_id=sch.schema_id and "
+                "views.name=:viewname and sch.name=:schname",
+                bindparams=[
+                    sql.bindparam('viewname', viewname, 
+                            sqltypes.String(convert_unicode=True)),
+                    sql.bindparam('schname', current_schema, 
+                            sqltypes.String(convert_unicode=True))
+                ]
+            )
         )
-        rp = connection.execute(s)
+
         if rp:
             view_def = rp.scalar()
             return view_def

test/dialect/test_mssql.py

 import re
 import warnings
 from sqlalchemy import *
-from sqlalchemy import types, exc, schema
+from sqlalchemy import types, exc, schema, event
 from sqlalchemy.orm import *
 from sqlalchemy.sql import table, column
 from sqlalchemy.databases import mssql
 from test.lib.testing import eq_, emits_warning_on, \
     assert_raises_message
 from sqlalchemy.util.compat import decimal
+from sqlalchemy.engine.reflection import Inspector
 
 class CompileTest(TestBase, AssertsCompiledSQL):
     __dialect__ = mssql.dialect()
         stream = fp.read(len)
         fp.close()
         return stream
+
+
+class ReflectHugeViewTest(TestBase):
+    def setup(self):
+        self.col_num = 150
+
+        self.metadata = MetaData(testing.db)
+        t = Table('base_table', self.metadata,
+                *[
+                    Column("long_named_column_number_%d" % i, Integer)
+                    for i in xrange(self.col_num)
+                ]
+        )
+        self.view_str = view_str = \
+            "CREATE VIEW huge_named_view AS SELECT %s FROM base_table" % (
+            ",".join("long_named_column_number_%d" % i 
+                        for i in xrange(self.col_num))
+            )
+        assert len(view_str) > 4000
+
+        event.listen(t, 'after_create', DDL(view_str) )
+        event.listen(t, 'before_drop', DDL("DROP VIEW huge_named_view") )
+
+        self.metadata.create_all()
+
+    def teardown(self):
+        self.metadata.drop_all()
+
+    def test_inspect_view_definition(self):
+        inspector = Inspector.from_engine(testing.db)
+        view_def = inspector.get_view_definition("huge_named_view")
+        eq_(view_def, self.view_str)
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.