summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-07-19 19:23:37 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-07-19 19:23:37 +0000
commitd56862cbca1796edafab8845fd1852f6183512f8 (patch)
tree61217e5cefc4e0dc1b25ef8554d6361a80bd5dac
parentc5141f2981a69c18338ccabc97067d1d563d43a9 (diff)
downloadsqlalchemy-d56862cbca1796edafab8845fd1852f6183512f8.tar.gz
- Some improvements to the _CompileOnAttr mechanism which
should reduce the probability of "Attribute x was not replaced during compile" warnings. (this generally applies to SQLA hackers, like Elixir devs).
-rw-r--r--CHANGES5
-rw-r--r--lib/sqlalchemy/orm/mapper.py3
-rw-r--r--test/ext/declarative.py19
3 files changed, 21 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index 4b3ec2ebe..1d34eedbe 100644
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,11 @@ CHANGES
present in a list of items to be processed, typically
during session.expunge_all() and dependent methods.
+ - Some improvements to the _CompileOnAttr mechanism which
+ should reduce the probability of "Attribute x was
+ not replaced during compile" warnings. (this generally
+ applies to SQLA hackers, like Elixir devs).
+
- ext
- Class-bound attributes sent as arguments to
relation()'s remote_side and foreign_keys parameters
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 588bc359d..e8bae46a4 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -355,6 +355,7 @@ class Mapper(object):
# re-entrance to compile() occurs rarely, when a class-mapped construct is
# used within a ForeignKey, something that is possible
# when using the declarative layer
+ self.__initialize_properties()
return
_already_compiling = True
try:
@@ -385,8 +386,8 @@ class Mapper(object):
self.__log("__initialize_properties() started")
l = [(key, prop) for key, prop in self.__props.iteritems()]
for key, prop in l:
- self.__log("initialize prop " + key)
if not getattr(prop, '_compiled', False):
+ self.__log("initialize prop " + key)
prop.init(key, self)
self.__log("__initialize_properties() complete")
self.compiled = True
diff --git a/test/ext/declarative.py b/test/ext/declarative.py
index 0fafc5999..c7bde6802 100644
--- a/test/ext/declarative.py
+++ b/test/ext/declarative.py
@@ -3,7 +3,7 @@ import testenv; testenv.configure_for_tests()
from sqlalchemy.ext import declarative as decl
from testlib import sa, testing
from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey, ForeignKeyConstraint
-from testlib.sa.orm import relation, create_session
+from testlib.sa.orm import relation, create_session, class_mapper
from testlib.testing import eq_
from orm._base import ComparableEntity
@@ -113,17 +113,26 @@ class DeclarativeTest(testing.TestBase, testing.AssertsExecutionResults):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email = Column(String(50))
- user_id = Column(Integer) # note no foreign key
+ user_id = Column(Integer, ForeignKey('users.id'))
class User(Base, ComparableEntity):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
addresses = relation("Address", order_by=Address.email,
- foreign_keys=Address.user_id, remote_side=Address.user_id,
- primaryjoin=id==Address.user_id,
+ foreign_keys=Address.user_id,
+ remote_side=Address.user_id,
)
-
+
+ # get the mapper for User. User mapper will compile,
+ # "addresses" relation will call upon Address.user_id for
+ # its clause element. Address.user_id is a _CompileOnAttr,
+ # which then calls class_mapper(Address). But ! We're already
+ # "in compilation", but class_mapper(Address) needs to initialize
+ # regardless, or COA's assertion fails
+ # and things generally go downhill from there.
+ class_mapper(User)
+
Base.metadata.create_all()
sess = create_session()