from sqlalchemy import Column from sqlalchemy import Computed from sqlalchemy import Integer from sqlalchemy import MetaData from sqlalchemy import Table from sqlalchemy.exc import ArgumentError from sqlalchemy.schema import CreateTable from sqlalchemy.testing import assert_raises_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import combinations from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import is_not class DDLComputedTest(fixtures.TestBase, AssertsCompiledSQL): __dialect__ = "default" @combinations( ("no_persisted", "", "ignore"), ("persisted_none", "", None), ("persisted_true", " STORED", True), ("persisted_false", " VIRTUAL", False), id_="iaa", ) def test_column_computed(self, text, persisted): m = MetaData() kwargs = {"persisted": persisted} if persisted != "ignore" else {} t = Table( "t", m, Column("x", Integer), Column("y", Integer, Computed("x + 2", **kwargs)), ) self.assert_compile( CreateTable(t), "CREATE TABLE t (x INTEGER, y INTEGER GENERATED " "ALWAYS AS (x + 2)%s)" % text, ) def test_other_options(self): t = Table( "t", MetaData(), Column( "y", Integer, Computed("x + 2"), nullable=False, unique=True ), ) self.assert_compile( CreateTable(t), "CREATE TABLE t (" "y INTEGER GENERATED ALWAYS AS (x + 2) NOT NULL, UNIQUE (y))", ) def test_server_default_onupdate(self): text = ( "A generated column cannot specify a server_default or a " "server_onupdate argument" ) def fn(**kwargs): m = MetaData() Table( "t", m, Column("x", Integer), Column("y", Integer, Computed("x + 2"), **kwargs), ) assert_raises_message(ArgumentError, text, fn, server_default="42") assert_raises_message(ArgumentError, text, fn, server_onupdate="42") def test_to_metadata(self): comp1 = Computed("x + 2") m = MetaData() t = Table("t", m, Column("x", Integer), Column("y", Integer, comp1)) is_(comp1.column, t.c.y) is_(t.c.y.server_onupdate, comp1) is_(t.c.y.server_default, comp1) m2 = MetaData() t2 = t.to_metadata(m2) comp2 = t2.c.y.server_default is_not(comp1, comp2) is_(comp1.column, t.c.y) is_(t.c.y.server_onupdate, comp1) is_(t.c.y.server_default, comp1) is_(comp2.column, t2.c.y) is_(t2.c.y.server_onupdate, comp2) is_(t2.c.y.server_default, comp2)