summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/engine/test_reflection.py42
-rw-r--r--test/engine/test_transaction.py1
-rw-r--r--test/ext/test_declarative.py47
-rw-r--r--test/orm/test_collection.py23
-rw-r--r--test/orm/test_dynamic.py14
-rw-r--r--test/orm/test_eager_relations.py29
-rw-r--r--test/orm/test_query.py16
-rw-r--r--test/orm/test_subquery_relations.py25
-rw-r--r--test/sql/test_case_statement.py22
-rw-r--r--test/sql/test_query.py39
-rw-r--r--test/sql/test_selectable.py30
11 files changed, 259 insertions, 29 deletions
diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py
index 1cbc9ab59..a82f1ec52 100644
--- a/test/engine/test_reflection.py
+++ b/test/engine/test_reflection.py
@@ -326,7 +326,44 @@ class ReflectionTest(TestBase, ComparesTables):
assert len(a4.constraints) == 2
finally:
meta.drop_all()
+
+ @testing.provide_metadata
+ def test_override_composite_fk(self):
+ """Test double-remove of composite foreign key, when replaced."""
+
+ a = Table('a',
+ metadata,
+ Column('x', sa.Integer, primary_key=True),
+ Column('y', sa.Integer, primary_key=True),
+ )
+
+ b = Table('b',
+ metadata,
+ Column('x', sa.Integer, primary_key=True),
+ Column('y', sa.Integer, primary_key=True),
+ sa.ForeignKeyConstraint(['x', 'y'], ['a.x', 'a.y'])
+ )
+
+ metadata.create_all()
+ meta2 = MetaData()
+
+ c1 = Column('x', sa.Integer, primary_key=True)
+ c2 = Column('y', sa.Integer, primary_key=True)
+ f1 = sa.ForeignKeyConstraint(['x', 'y'], ['a.x', 'a.y'])
+ b1 = Table('b',
+ meta2, c1, c2, f1,
+ autoload=True,
+ autoload_with=testing.db
+ )
+
+ assert b1.c.x is c1
+ assert b1.c.y is c2
+ assert f1 in b1.constraints
+ assert len(b1.constraints) == 2
+
+
+
def test_override_keys(self):
"""test that columns can be overridden with a 'key',
and that ForeignKey targeting during reflection still works."""
@@ -510,8 +547,9 @@ class ReflectionTest(TestBase, ComparesTables):
)
assert_raises_message(sa.exc.InvalidRequestError,
- "Could not find table 'pkgs' with which "
- "to generate a foreign key",
+ "Foreign key assocated with column 'slots.pkg_id' "
+ "could not find table 'pkgs' with which to generate "
+ "a foreign key to target column 'pkg_id'",
metadata.create_all)
def test_composite_pks(self):
diff --git a/test/engine/test_transaction.py b/test/engine/test_transaction.py
index bc0985bec..e7e2fe1b8 100644
--- a/test/engine/test_transaction.py
+++ b/test/engine/test_transaction.py
@@ -868,6 +868,7 @@ class TLTransactionTest(TestBase):
assert r2.connection.closed
assert tlengine.closed
+ @testing.crashes('oracle+cx_oracle', 'intermittent failures on the buildbot')
def test_dispose(self):
eng = create_engine(testing.db.url, strategy='threadlocal')
result = eng.execute(select([1]))
diff --git a/test/ext/test_declarative.py b/test/ext/test_declarative.py
index 4da826d38..71e31233b 100644
--- a/test/ext/test_declarative.py
+++ b/test/ext/test_declarative.py
@@ -690,6 +690,40 @@ class DeclarativeTest(DeclarativeTestBase):
eq_(sess.query(User).all(), [User(name='u1', address_count=2,
addresses=[Address(email='one'), Address(email='two')])])
+ def test_useless_classproperty(self):
+ class Address(Base, ComparableEntity):
+
+ __tablename__ = 'addresses'
+ id = Column('id', Integer, primary_key=True,
+ test_needs_autoincrement=True)
+ email = Column('email', String(50))
+ user_id = Column('user_id', Integer, ForeignKey('users.id'))
+
+ class User(Base, ComparableEntity):
+
+ __tablename__ = 'users'
+ id = Column('id', Integer, primary_key=True,
+ test_needs_autoincrement=True)
+ name = Column('name', String(50))
+ addresses = relationship('Address', backref='user')
+
+ @classproperty
+ def address_count(cls):
+ # this doesn't really gain us anything. but if
+ # one is used, lets have it function as expected...
+ return sa.orm.column_property(sa.select([sa.func.count(Address.id)]).
+ where(Address.user_id == cls.id))
+
+ Base.metadata.create_all()
+ u1 = User(name='u1', addresses=[Address(email='one'),
+ Address(email='two')])
+ sess = create_session()
+ sess.add(u1)
+ sess.flush()
+ sess.expunge_all()
+ eq_(sess.query(User).all(), [User(name='u1', address_count=2,
+ addresses=[Address(email='one'), Address(email='two')])])
+
def test_column(self):
class User(Base, ComparableEntity):
@@ -2585,17 +2619,18 @@ class DeclarativeMixinTest(DeclarativeTestBase):
def test_table_in_model_and_different_named_column_in_mixin(self):
class ColumnMixin:
-
tada = Column(Integer)
-
+
+
def go():
class Model(Base, ColumnMixin):
- __table__ = Table('foo', Base.metadata, Column('data',
- Integer), Column('id', Integer,
- primary_key=True))
-
+ __table__ = Table('foo', Base.metadata,
+ Column('data',Integer),
+ Column('id', Integer,primary_key=True))
+ foo = relationship("Dest")
+
assert_raises_message(sa.exc.ArgumentError,
"Can't add additional column 'tada' when "
"specifying __table__", go)
diff --git a/test/orm/test_collection.py b/test/orm/test_collection.py
index 7dcc5c56f..405829f74 100644
--- a/test/orm/test_collection.py
+++ b/test/orm/test_collection.py
@@ -7,12 +7,12 @@ from sqlalchemy.orm.collections import collection
import sqlalchemy as sa
from sqlalchemy.test import testing
-from sqlalchemy import Integer, String, ForeignKey
+from sqlalchemy import Integer, String, ForeignKey, text
from sqlalchemy.test.schema import Table, Column
from sqlalchemy import util, exc as sa_exc
from sqlalchemy.orm import create_session, mapper, relationship, attributes
from test.orm import _base
-from sqlalchemy.test.testing import eq_, assert_raises
+from sqlalchemy.test.testing import eq_, assert_raises, assert_raises_message
class Canary(sa.orm.interfaces.AttributeExtension):
def __init__(self):
@@ -1561,6 +1561,25 @@ class DictHelpersTest(_base.MappedTest):
eq_(Bar.foos.property.collection_class().keyfunc(Foo(id=3)), 3)
eq_(Bar.foos2.property.collection_class().keyfunc(Foo(id=3, bar_id=12)), (3, 12))
+
+ @testing.resolve_artifact_names
+ def test_column_mapped_assertions(self):
+ assert_raises_message(
+ sa_exc.ArgumentError,
+ "Column-based expression object expected; got: 'a'",
+ collections.column_mapped_collection, "a",
+ )
+ assert_raises_message(
+ sa_exc.ArgumentError,
+ "Column-based expression object expected; got",
+ collections.column_mapped_collection, text("a"),
+ )
+ assert_raises_message(
+ sa_exc.ArgumentError,
+ "Column-based expression object expected; got",
+ collections.column_mapped_collection, text("a"),
+ )
+
@testing.resolve_artifact_names
def test_column_mapped_collection(self):
diff --git a/test/orm/test_dynamic.py b/test/orm/test_dynamic.py
index b2fac6005..5d822fa3d 100644
--- a/test/orm/test_dynamic.py
+++ b/test/orm/test_dynamic.py
@@ -6,7 +6,7 @@ from sqlalchemy import Integer, String, ForeignKey, desc, select, func
from sqlalchemy.test.schema import Table, Column
from sqlalchemy.orm import mapper, relationship, create_session, Query, attributes
from sqlalchemy.orm.dynamic import AppenderMixin
-from sqlalchemy.test.testing import eq_, AssertsCompiledSQL
+from sqlalchemy.test.testing import eq_, AssertsCompiledSQL, assert_raises_message
from sqlalchemy.util import function_named
from test.orm import _base, _fixtures
@@ -123,6 +123,18 @@ class DynamicTest(_fixtures.FixtureTest, AssertsCompiledSQL):
self.assert_sql_count(testing.db, go, 2)
@testing.resolve_artifact_names
+ def test_no_populate(self):
+ mapper(User, users, properties={
+ 'addresses':dynamic_loader(mapper(Address, addresses))
+ })
+ u1 = User()
+ assert_raises_message(
+ NotImplementedError,
+ "Dynamic attributes don't support collection population.",
+ attributes.set_committed_value, u1, 'addresses', []
+ )
+
+ @testing.resolve_artifact_names
def test_m2m(self):
mapper(Order, orders, properties={
'items':relationship(Item, secondary=order_items, lazy="dynamic",
diff --git a/test/orm/test_eager_relations.py b/test/orm/test_eager_relations.py
index de397f47b..b96014a57 100644
--- a/test/orm/test_eager_relations.py
+++ b/test/orm/test_eager_relations.py
@@ -1,13 +1,17 @@
-"""basic tests of eager loaded attributes"""
+"""tests of joined-eager loaded attributes"""
from sqlalchemy.test.testing import eq_, is_, is_not_
import sqlalchemy as sa
from sqlalchemy.test import testing
-from sqlalchemy.orm import joinedload, deferred, undefer, joinedload_all, backref
-from sqlalchemy import Integer, String, Date, ForeignKey, and_, select, func
+from sqlalchemy.orm import joinedload, deferred, undefer, \
+ joinedload_all, backref
+from sqlalchemy import Integer, String, Date, ForeignKey, and_, select, \
+ func
from sqlalchemy.test.schema import Table, Column
-from sqlalchemy.orm import mapper, relationship, create_session, lazyload, aliased
-from sqlalchemy.test.testing import eq_, assert_raises
+from sqlalchemy.orm import mapper, relationship, create_session, \
+ lazyload, aliased
+from sqlalchemy.test.testing import eq_, assert_raises, \
+ assert_raises_message
from sqlalchemy.test.assertsql import CompiledSQL
from test.orm import _base, _fixtures
from sqlalchemy.util import OrderedDict as odict
@@ -283,7 +287,20 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
)
self.assert_sql_count(testing.db, go, count)
-
+ @testing.resolve_artifact_names
+ def test_disable_dynamic(self):
+ """test no joined option on a dynamic."""
+
+ mapper(User, users, properties={
+ 'addresses':relationship(Address, lazy="dynamic")
+ })
+ mapper(Address, addresses)
+ sess = create_session()
+ assert_raises_message(
+ sa.exc.InvalidRequestError,
+ "User.addresses' does not support object population - eager loading cannot be applied.",
+ sess.query(User).options(joinedload(User.addresses)).first,
+ )
@testing.resolve_artifact_names
def test_many_to_many(self):
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index ebe72b565..cc2f046cd 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -1132,6 +1132,22 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
(User(id=10, name=u'chuck'), u'y')
]
)
+
+ c1, c2 = column('c1'), column('c2')
+ q1 = s.query(User, c1.label('foo'), c1.label('bar'))
+ q2 = s.query(User, c1.label('foo'), c2.label('bar'))
+ q3 = q1.union(q2)
+ self.assert_compile(
+ q3,
+ "SELECT anon_1.users_id AS anon_1_users_id, "
+ "anon_1.users_name AS anon_1_users_name, "
+ "anon_1.foo AS anon_1_foo, anon_1.bar AS anon_1_bar "
+ "FROM (SELECT users.id AS users_id, users.name AS users_name, "
+ "c1 AS foo, c1 AS bar FROM users UNION SELECT users.id AS "
+ "users_id, users.name AS users_name, c1 AS foo, c2 AS bar "
+ "FROM users) AS anon_1",
+ use_default_dialect=True
+ )
@testing.fails_on('mysql', "mysql doesn't support intersect")
def test_intersect(self):
diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py
index 827630c3d..71f87a726 100644
--- a/test/orm/test_subquery_relations.py
+++ b/test/orm/test_subquery_relations.py
@@ -3,10 +3,10 @@ from sqlalchemy.test import testing
from sqlalchemy.test.schema import Table, Column
from sqlalchemy import Integer, String, ForeignKey, bindparam
from sqlalchemy.orm import backref, subqueryload, subqueryload_all, \
- mapper, relationship, clear_mappers,\
- create_session, lazyload, aliased, joinedload,\
- deferred, undefer
-from sqlalchemy.test.testing import eq_, assert_raises
+ mapper, relationship, clear_mappers, create_session, lazyload, \
+ aliased, joinedload, deferred, undefer
+from sqlalchemy.test.testing import eq_, assert_raises, \
+ assert_raises_message
from sqlalchemy.test.assertsql import CompiledSQL
from test.orm import _base, _fixtures
import sqlalchemy as sa
@@ -80,6 +80,23 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
self.assert_sql_count(testing.db, go, 2)
+ @testing.resolve_artifact_names
+ def test_disable_dynamic(self):
+ """test no subquery option on a dynamic."""
+
+ mapper(User, users, properties={
+ 'addresses':relationship(Address, lazy="dynamic")
+ })
+ mapper(Address, addresses)
+ sess = create_session()
+
+ # previously this would not raise, but would emit
+ # the query needlessly and put the result nowhere.
+ assert_raises_message(
+ sa.exc.InvalidRequestError,
+ "User.addresses' does not support object population - eager loading cannot be applied.",
+ sess.query(User).options(subqueryload(User.addresses)).first,
+ )
@testing.resolve_artifact_names
def test_many_to_many(self):
diff --git a/test/sql/test_case_statement.py b/test/sql/test_case_statement.py
index 3f3abe7e1..645822fa7 100644
--- a/test/sql/test_case_statement.py
+++ b/test/sql/test_case_statement.py
@@ -1,4 +1,4 @@
-from sqlalchemy.test.testing import assert_raises, assert_raises_message
+from sqlalchemy.test.testing import assert_raises, assert_raises_message, eq_
import sys
from sqlalchemy import *
from sqlalchemy.test import *
@@ -99,7 +99,25 @@ class CaseTest(TestBase, AssertsCompiledSQL):
self.assert_compile(case([("x", "y")], value=t.c.col1), "CASE test.col1 WHEN :param_1 THEN :param_2 END")
self.assert_compile(case([(t.c.col1==7, "y")], else_="z"), "CASE WHEN (test.col1 = :col1_1) THEN :param_1 ELSE :param_2 END")
-
+
+ def test_text_doesnt_explode(self):
+
+ for s in [
+ select([case([(info_table.c.info == 'pk_4_data',
+ text("'yes'"))], else_=text("'no'"
+ ))]).order_by(info_table.c.info),
+
+ select([case([(info_table.c.info == 'pk_4_data',
+ literal_column("'yes'"))], else_=literal_column("'no'"
+ ))]).order_by(info_table.c.info),
+
+ ]:
+ eq_(s.execute().fetchall(), [
+ (u'no', ), (u'no', ), (u'no', ), (u'yes', ),
+ (u'no', ), (u'no', ),
+ ])
+
+
@testing.fails_on('firebird', 'FIXME: unknown')
@testing.fails_on('maxdb', 'FIXME: unknown')
diff --git a/test/sql/test_query.py b/test/sql/test_query.py
index e8f9d118b..0a496906d 100644
--- a/test/sql/test_query.py
+++ b/test/sql/test_query.py
@@ -16,15 +16,19 @@ class QueryTest(TestBase):
users = Table('query_users', metadata,
Column('user_id', INT, primary_key=True, test_needs_autoincrement=True),
Column('user_name', VARCHAR(20)),
+ test_needs_acid=True
)
addresses = Table('query_addresses', metadata,
Column('address_id', Integer, primary_key=True, test_needs_autoincrement=True),
Column('user_id', Integer, ForeignKey('query_users.user_id')),
- Column('address', String(30)))
+ Column('address', String(30)),
+ test_needs_acid=True
+ )
users2 = Table('u2', metadata,
Column('user_id', INT, primary_key = True),
Column('user_name', VARCHAR(20)),
+ test_needs_acid=True
)
metadata.create_all()
@@ -615,6 +619,39 @@ class QueryTest(TestBase):
eq_(r[users.c.user_name], 'jack')
eq_(r.user_name, 'jack')
+ def test_graceful_fetch_on_non_rows(self):
+ """test that calling fetchone() etc. on a result that doesn't
+ return rows fails gracefully.
+
+ """
+
+ # these proxies don't work with no cursor.description present.
+ # so they don't apply to this test at the moment.
+ # base.FullyBufferedResultProxy,
+ # base.BufferedRowResultProxy,
+ # base.BufferedColumnResultProxy
+
+ conn = testing.db.connect()
+ for meth in ('fetchone', 'fetchall', 'first', 'scalar', 'fetchmany'):
+ trans = conn.begin()
+ result = conn.execute(users.insert(), user_id=1)
+ assert_raises_message(
+ exc.ResourceClosedError,
+ "This result object does not return rows. "
+ "It has been closed automatically.",
+ getattr(result, meth),
+ )
+ trans.rollback()
+
+ def test_fetchone_til_end(self):
+ result = testing.db.execute("select * from query_users")
+ eq_(result.fetchone(), None)
+ assert_raises_message(
+ exc.ResourceClosedError,
+ "This result object is closed.",
+ result.fetchone
+ )
+
def test_result_case_sensitivity(self):
"""test name normalization for result sets."""
diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py
index 062ed5f1b..5bebbe05f 100644
--- a/test/sql/test_selectable.py
+++ b/test/sql/test_selectable.py
@@ -28,20 +28,40 @@ table2 = Table('table2', metadata,
class SelectableTest(TestBase, AssertsExecutionResults):
- def test_distance_on_labels(self):
-
+ def test_indirect_correspondence_on_labels(self):
+ # this test depends upon 'distance' to
+ # get the right result
+
# same column three times
s = select([table1.c.col1.label('c2'), table1.c.col1,
table1.c.col1.label('c1')])
- # didnt do this yet...col.label().make_proxy() has same
- # "distance" as col.make_proxy() so far assert
- # s.corresponding_column(table1.c.col1) is s.c.col1
+ # this tests the same thing as
+ # test_direct_correspondence_on_labels below -
+ # that the presence of label() affects the 'distance'
+ assert s.corresponding_column(table1.c.col1) is s.c.col1
assert s.corresponding_column(s.c.col1) is s.c.col1
assert s.corresponding_column(s.c.c1) is s.c.c1
+ def test_direct_correspondence_on_labels(self):
+ # this test depends on labels being part
+ # of the proxy set to get the right result
+
+ l1, l2 = table1.c.col1.label('foo'), table1.c.col1.label('bar')
+ sel = select([l1, l2])
+
+ sel2 = sel.alias()
+ assert sel2.corresponding_column(l1) is sel2.c.foo
+ assert sel2.corresponding_column(l2) is sel2.c.bar
+
+ sel2 = select([table1.c.col1.label('foo'), table1.c.col2.label('bar')])
+
+ sel3 = sel.union(sel2).alias()
+ assert sel3.corresponding_column(l1) is sel3.c.foo
+ assert sel3.corresponding_column(l2) is sel3.c.bar
+
def test_distance_on_aliases(self):
a1 = table1.alias('a1')
for s in (select([a1, table1], use_labels=True),