summaryrefslogtreecommitdiff
path: root/test/dialect/oracle/test_dialect.py
diff options
context:
space:
mode:
authorCaselIT <cfederico87@gmail.com>2019-11-04 17:11:21 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2019-11-08 15:40:25 -0500
commit3a0e0531c179e598c345e5be24e350c375ce7e22 (patch)
tree3b0675f216ced73f3d94f825f65ad19d2376e952 /test/dialect/oracle/test_dialect.py
parent4f5f953b5472790a5ec6c278ec188f9cea035437 (diff)
downloadsqlalchemy-3a0e0531c179e598c345e5be24e350c375ce7e22.tar.gz
Support for generated columns
Added DDL support for "computed columns"; these are DDL column specifications for columns that have a server-computed value, either upon SELECT (known as "virtual") or at the point of which they are INSERTed or UPDATEd (known as "stored"). Support is established for Postgresql, MySQL, Oracle SQL Server and Firebird. Thanks to Federico Caselli for lots of work on this one. ORM round trip tests included. The ORM makes use of existing FetchedValue support and no additional ORM logic is present for the basic feature. It has been observed that Oracle RETURNING does not return the new value of a computed column upon UPDATE; it returns the prior value. As this is very dangerous, a warning is emitted if a computed column is rendered into the RETURNING clause of an UPDATE statement. Fixes: #4894 Closes: #4928 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4928 Pull-request-sha: d39c521d5ac6ebfb4fb5b53846451de79752e64c Change-Id: I2610b2999a5b1b127ed927dcdaeee98b769643ce
Diffstat (limited to 'test/dialect/oracle/test_dialect.py')
-rw-r--r--test/dialect/oracle/test_dialect.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/test/dialect/oracle/test_dialect.py b/test/dialect/oracle/test_dialect.py
index 62926700e..20c6336b8 100644
--- a/test/dialect/oracle/test_dialect.py
+++ b/test/dialect/oracle/test_dialect.py
@@ -3,6 +3,7 @@
import re
from sqlalchemy import bindparam
+from sqlalchemy import Computed
from sqlalchemy import create_engine
from sqlalchemy import exc
from sqlalchemy import Float
@@ -258,6 +259,72 @@ class EncodingErrorsTest(fixtures.TestBase):
)
+class ComputedReturningTest(fixtures.TablesTest):
+ __only_on__ = "oracle"
+ __backend__ = True
+
+ @classmethod
+ def define_tables(cls, metadata):
+ Table(
+ "test",
+ metadata,
+ Column("id", Integer, primary_key=True),
+ Column("foo", Integer),
+ Column("bar", Integer, Computed("foo + 42")),
+ )
+
+ Table(
+ "test_no_returning",
+ metadata,
+ Column("id", Integer, primary_key=True),
+ Column("foo", Integer),
+ Column("bar", Integer, Computed("foo + 42")),
+ implicit_returning=False,
+ )
+
+ def test_computed_insert(self):
+ test = self.tables.test
+ with testing.db.connect() as conn:
+ result = conn.execute(
+ test.insert().return_defaults(), {"id": 1, "foo": 5}
+ )
+
+ eq_(result.returned_defaults, (47,))
+
+ eq_(conn.scalar(select([test.c.bar])), 47)
+
+ def test_computed_update_warning(self):
+ test = self.tables.test
+ with testing.db.connect() as conn:
+ conn.execute(test.insert(), {"id": 1, "foo": 5})
+
+ with testing.expect_warnings(
+ "Computed columns don't work with Oracle UPDATE"
+ ):
+ result = conn.execute(
+ test.update().values(foo=10).return_defaults()
+ )
+
+ # returns the *old* value
+ eq_(result.returned_defaults, (47,))
+
+ eq_(conn.scalar(select([test.c.bar])), 52)
+
+ def test_computed_update_no_warning(self):
+ test = self.tables.test_no_returning
+ with testing.db.connect() as conn:
+ conn.execute(test.insert(), {"id": 1, "foo": 5})
+
+ result = conn.execute(
+ test.update().values(foo=10).return_defaults()
+ )
+
+ # no returning
+ eq_(result.returned_defaults, None)
+
+ eq_(conn.scalar(select([test.c.bar])), 52)
+
+
class OutParamTest(fixtures.TestBase, AssertsExecutionResults):
__only_on__ = "oracle+cx_oracle"
__backend__ = True