]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Some improvements to the _CompileOnAttr mechanism which
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 19 Jul 2008 19:23:37 +0000 (19:23 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 19 Jul 2008 19:23:37 +0000 (19:23 +0000)
should reduce the probability of "Attribute x was
not replaced during compile" warnings. (this generally
applies to SQLA hackers, like Elixir devs).

CHANGES
lib/sqlalchemy/orm/mapper.py
test/ext/declarative.py

diff --git a/CHANGES b/CHANGES
index 4b3ec2ebe2323bdbe90b1f3b2ea4e694cd7c5890..1d34eedbea6623b0c8e7b701aef465fb4e27f051 100644 (file)
--- 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 
index 588bc359d308dfe900f24e1947b716f034d84304..e8bae46a4fe631f5cbea58bd0fee425453368d49 100644 (file)
@@ -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
index 0fafc599926dcaa4130c0b415197388b83ca5cdb..c7bde6802056b07237b7ce87cb6fc727573b78f0 100644 (file)
@@ -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()