]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add 'schema' parameter to table
authorDylan Modesitt <dmodesitt@sescollc.com>
Wed, 6 May 2020 18:17:23 +0000 (14:17 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 15 May 2020 15:22:03 +0000 (11:22 -0400)
Added a "schema" parameter to the :func:`_expression.table` construct,
allowing ad-hoc table expressions to also include a schema name.
Pull request courtesy Dylan Modesitt.

Fixes: #5309
Closes: #5310
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/5310
Pull-request-sha: ce85681050500186678131f948b6ea277a65dc17
Change-Id: I32015d593e1ee1121c7426fbffdcc565d025fad1
(cherry picked from commit 187a3a27cf8303ba332e011a482bd3b21cd3c01c)

doc/build/changelog/unreleased_13/5309.rst [new file with mode: 0644]
lib/sqlalchemy/sql/selectable.py
test/orm/test_transaction.py
test/sql/test_compiler.py

diff --git a/doc/build/changelog/unreleased_13/5309.rst b/doc/build/changelog/unreleased_13/5309.rst
new file mode 100644 (file)
index 0000000..89ab14b
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: usecase, sql
+    :tickets: 5309
+
+    Added a ".schema" parameter to the :func:`_expression.table` construct,
+    allowing ad-hoc table expressions to also include a schema name.
+    Pull request courtesy Dylan Modesitt.
index 014e6969af29a3a928e00f972340f9a918ab1484..740f870cb3f92fbc363402570d1f4f07c62b6389 100644 (file)
@@ -1895,9 +1895,9 @@ class FromGrouping(FromClause):
 class TableClause(Immutable, FromClause):
     """Represents a minimal "table" construct.
 
-    This is a lightweight table object that has only a name and a
+    This is a lightweight table object that has only a name, a
     collection of columns, which are typically produced
-    by the :func:`_expression.column` function::
+    by the :func:`_expression.column` function, and a schema::
 
         from sqlalchemy import table, column
 
@@ -1934,7 +1934,7 @@ class TableClause(Immutable, FromClause):
     _autoincrement_column = None
     """No PK or default support so no autoincrement column."""
 
-    def __init__(self, name, *columns):
+    def __init__(self, name, *columns, **kw):
         """Produce a new :class:`_expression.TableClause`.
 
         The object returned is an instance of :class:`_expression.TableClause`
@@ -1947,10 +1947,15 @@ class TableClause(Immutable, FromClause):
            be imported from the plain ``sqlalchemy`` namespace like any
            other SQL element.
 
+
         :param name: Name of the table.
 
         :param columns: A collection of :func:`_expression.column` constructs.
 
+        :param schema: The schema name for this table.
+
+            .. versionadded:: 1.3.17 :func:`_expression.table` can now
+               accept a ``schema`` argument.
         """
 
         super(TableClause, self).__init__()
@@ -1961,6 +1966,12 @@ class TableClause(Immutable, FromClause):
         for c in columns:
             self.append_column(c)
 
+        schema = kw.pop("schema", None)
+        if schema is not None:
+            self.schema = schema
+        if kw:
+            raise exc.ArgumentError("Unsupported argument(s): %s" % list(kw))
+
     def _init_collections(self):
         pass
 
index 33c511a37f9180281472d96f5ed475a95a3682e7..304c9e39a6cc999e21be7ce3450c725a7763cb1d 100644 (file)
@@ -475,7 +475,7 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest):
         x = [1]
 
         @event.listens_for(sess, "after_commit")  # noqa
-        def add_another_user(session):
+        def add_another_user(session):  # noqa
             x[0] += 1
 
         sess.add(to_flush.pop())
index 35d8de5720173e625aac804a69e515d129708a0e..00f7a976369fc91810f964f9d5faa72d66cc96ca 100644 (file)
@@ -3922,6 +3922,75 @@ class SchemaTest(fixtures.TestBase, AssertsCompiledSQL):
             "(:rem_id, :datatype_id, :value)",
         )
 
+    def test_schema_lowercase_select(self):
+        # test that "schema" works correctly when passed to table
+        t1 = table("foo", column("a"), column("b"), schema="bar")
+        self.assert_compile(
+            select([t1]).select_from(t1),
+            "SELECT bar.foo.a, bar.foo.b FROM bar.foo",
+        )
+
+    def test_schema_lowercase_select_alias(self):
+        # test alias behavior
+        t1 = table("foo", schema="bar")
+        self.assert_compile(
+            select(["*"]).select_from(t1.alias("t")),
+            "SELECT * FROM bar.foo AS t",
+        )
+
+    def test_schema_lowercase_select_labels(self):
+        # test "schema" with extended_labels
+        t1 = table(
+            "baz",
+            column("id", Integer),
+            column("name", String),
+            column("meta", String),
+            schema="here",
+        )
+
+        self.assert_compile(
+            select([t1]).select_from(t1).apply_labels(),
+            "SELECT here.baz.id AS here_baz_id, here.baz.name AS "
+            "here_baz_name, here.baz.meta AS here_baz_meta FROM here.baz",
+        )
+
+    def test_schema_lowercase_select_subquery(self):
+        # test schema plays well with subqueries
+        t1 = table(
+            "yetagain",
+            column("anotherid", Integer),
+            column("anothername", String),
+            schema="here",
+        )
+        s = (
+            text("select id, name from user")
+            .columns(id=Integer, name=String)
+            .alias()
+        )
+        stmt = select([t1.c.anotherid]).select_from(
+            t1.join(s, t1.c.anotherid == s.c.id)
+        )
+        compiled = stmt.compile()
+        eq_(
+            compiled._create_result_map(),
+            {
+                "anotherid": (
+                    "anotherid",
+                    (t1.c.anotherid, "anotherid", "anotherid",),
+                    t1.c.anotherid.type,
+                )
+            },
+        )
+
+    def test_schema_lowercase_invalid(self):
+        assert_raises_message(
+            exc.ArgumentError,
+            r"Unsupported argument\(s\): \['not_a_schema'\]",
+            table,
+            "foo",
+            not_a_schema="bar",
+        )
+
 
 class CorrelateTest(fixtures.TestBase, AssertsCompiledSQL):
     __dialect__ = "default"