mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-29 03:54:43 -04:00
- [feature] Can now provide class-bound attributes
that override columns which are of any
non-ORM type, not just descriptors.
[ticket:2535]
This commit is contained in:
@@ -185,6 +185,11 @@ underneath "0.7.xx".
|
||||
when dereferenced by a unit test.
|
||||
[ticket:2526]
|
||||
|
||||
- [feature] Can now provide class-bound attributes
|
||||
that override columns which are of any
|
||||
non-ORM type, not just descriptors.
|
||||
[ticket:2535]
|
||||
|
||||
- [feature] Added with_labels and
|
||||
reduce_columns keyword arguments to
|
||||
Query.subquery(), to provide two alternate
|
||||
|
||||
@@ -1630,18 +1630,12 @@ class Mapper(_InspectionAttr):
|
||||
|
||||
def _is_userland_descriptor(self, obj):
|
||||
if isinstance(obj, (MapperProperty,
|
||||
attributes.QueryableAttribute)):
|
||||
return False
|
||||
elif not hasattr(obj, '__get__'):
|
||||
attributes.QueryableAttribute,
|
||||
instrumentation.ClassManager,
|
||||
expression.ColumnElement)):
|
||||
return False
|
||||
else:
|
||||
obj = util.unbound_method_to_callable(obj)
|
||||
if isinstance(
|
||||
obj.__get__(None, obj),
|
||||
attributes.QueryableAttribute
|
||||
):
|
||||
return False
|
||||
return True
|
||||
return True
|
||||
|
||||
def _should_exclude(self, name, assigned_name, local, column):
|
||||
"""determine whether a particular property should be implicitly
|
||||
@@ -1652,8 +1646,8 @@ class Mapper(_InspectionAttr):
|
||||
|
||||
"""
|
||||
|
||||
# check for descriptors, either local or from
|
||||
# an inherited class
|
||||
# check for class-bound attributes and/or descriptors,
|
||||
# either local or from an inherited class
|
||||
if local:
|
||||
if self.class_.__dict__.get(assigned_name, None) is not None \
|
||||
and self._is_userland_descriptor(
|
||||
|
||||
+56
-2
@@ -12,7 +12,7 @@ from sqlalchemy.orm import mapper, relationship, backref, \
|
||||
column_property, composite, dynamic_loader, \
|
||||
comparable_property, Session
|
||||
from sqlalchemy.orm.persistence import _sort_states
|
||||
from test.lib.testing import eq_, AssertsCompiledSQL
|
||||
from test.lib.testing import eq_, AssertsCompiledSQL, is_
|
||||
from test.lib import fixtures
|
||||
from test.orm import _fixtures
|
||||
from test.lib.assertsql import CompiledSQL
|
||||
@@ -3098,6 +3098,61 @@ class RequirementsTest(fixtures.MappedTest):
|
||||
h2.value = "Asdf"
|
||||
h2.value = "asdf asdf" # ding
|
||||
|
||||
class IsUserlandTest(fixtures.MappedTest):
|
||||
@classmethod
|
||||
def define_tables(cls, metadata):
|
||||
Table('foo', metadata,
|
||||
Column('id', Integer, primary_key=True),
|
||||
Column('someprop', Integer)
|
||||
)
|
||||
|
||||
def _test(self, value, instancelevel=None):
|
||||
class Foo(object):
|
||||
someprop = value
|
||||
|
||||
m = mapper(Foo, self.tables.foo)
|
||||
eq_(Foo.someprop, value)
|
||||
f1 = Foo()
|
||||
if instancelevel is not None:
|
||||
eq_(f1.someprop, instancelevel)
|
||||
else:
|
||||
eq_(f1.someprop, value)
|
||||
assert self.tables.foo.c.someprop not in m._columntoproperty
|
||||
|
||||
def _test_not(self, value):
|
||||
class Foo(object):
|
||||
someprop = value
|
||||
|
||||
m = mapper(Foo, self.tables.foo)
|
||||
is_(Foo.someprop.property.columns[0], self.tables.foo.c.someprop)
|
||||
assert self.tables.foo.c.someprop in m._columntoproperty
|
||||
|
||||
def test_string(self):
|
||||
self._test("someprop")
|
||||
|
||||
def test_unicode(self):
|
||||
self._test(u"someprop")
|
||||
|
||||
def test_int(self):
|
||||
self._test(5)
|
||||
|
||||
def test_dict(self):
|
||||
self._test({"bar": "bat"})
|
||||
|
||||
def test_set(self):
|
||||
self._test(set([6]))
|
||||
|
||||
def test_column(self):
|
||||
self._test_not(self.tables.foo.c.someprop)
|
||||
|
||||
def test_relationship(self):
|
||||
self._test_not(relationship("bar"))
|
||||
|
||||
def test_descriptor(self):
|
||||
def somefunc(self):
|
||||
return "hi"
|
||||
self._test(property(somefunc), "hi")
|
||||
|
||||
class MagicNamesTest(fixtures.MappedTest):
|
||||
|
||||
@classmethod
|
||||
@@ -3157,7 +3212,6 @@ class MagicNamesTest(fixtures.MappedTest):
|
||||
Column(reserved, Integer))
|
||||
class T(object):
|
||||
pass
|
||||
|
||||
assert_raises_message(
|
||||
KeyError,
|
||||
('%r: requested attribute name conflicts with '
|
||||
|
||||
Reference in New Issue
Block a user