From: Mike Bayer Date: Wed, 16 Mar 2011 18:09:25 +0000 (-0400) Subject: - Rewrote the query used to get the definition of a view, X-Git-Tag: rel_0_6_7~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6e83ca0faf18c4e30d36b022b1454320f65bcb9;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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] --- diff --git a/CHANGES b/CHANGES index dcda1ccaa2..dd44030fbd 100644 --- a/CHANGES +++ b/CHANGES @@ -77,6 +77,13 @@ CHANGES - 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] diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index f544753381..8cf3c2ad58 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -130,14 +130,14 @@ which has triggers:: # ..., 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`. @@ -1217,14 +1217,25 @@ class MSDialect(default.DefaultDialect): @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 diff --git a/test/dialect/test_mssql.py b/test/dialect/test_mssql.py index 3ea3074fda..d0edb437b4 100644 --- a/test/dialect/test_mssql.py +++ b/test/dialect/test_mssql.py @@ -14,6 +14,7 @@ from sqlalchemy.engine import url from sqlalchemy.test import * from sqlalchemy.test.testing import eq_, emits_warning_on, \ assert_raises_message +from sqlalchemy.engine.reflection import Inspector class CompileTest(TestBase, AssertsCompiledSQL): __dialect__ = mssql.dialect() @@ -1622,3 +1623,36 @@ class BinaryTest(TestBase, AssertsExecutionResults): 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 + + DDL(view_str).execute_at('after-create', t) + DDL("DROP VIEW huge_named_view").execute_at('before-drop', t) + + 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) +