Oh yes, I am missing entire freight trains of stuff...

Here is what I understand now:


    def __getattr__(self, key):
        if ogetattr(self,'_lazy_tables') and \
                key in ogetattr(self,'_LAZY_TABLES'):
            tablename, fields, args = self._LAZY_TABLES.pop(key)
            return self.lazy_define_table(tablename,*fields,**args)
        return ogetattr(self, key)



   - The "hasattr" bug is not a bug at all.  It is supposed to call 
   _getattr_ and check for an exception, which it does.  Case closed.
   
   - I'm seeing the error as a result of the _getattr_ function calling 
   lazy_define_table().  It pops the table from the list of _LAZY_TABLES 
   and "processes" it.  But in the course of processing...
   
   - The table definition calls init() on Table class and builds a table. 
    In the course of building the table, the code calls sqlhtml_validators on 
   all fields, including those which reference other tables.  The validator 
   code calls for any table that was referenced.
   
   - The code above is re-entered, this time for the new table.  This new 
   table has a reference for the previous table (yes, circular references) 
    Now we are in trouble.
   
   - The code falls through the _getattr_ once more, this time looking for 
   the original table name.  It has been removed from _LAZY_TABLES because 
   it's been here before.  But it is now stuck in the middle of 
   lazy_define_table() and has not gotten to the step where the table is 
   added as an attribute to db.  This time thru we throw an exception.

I'm not sure how to fix this, other than to avoid circular references.  But 
the circular references may be verrrry long and this problem could still 
surface.  I hope someone a lot smarter can figure out how to break this.

Joe

On Tuesday, November 27, 2012 4:42:29 AM UTC-8, Joe Barnhart wrote:
>
> I'm running into a weird "lazy tables" bug.  I have about 32 tables 
> defined and I'm running into a error when I try to open a controller on a 
> table that references another.  The referenced table doesn't show up in the 
> DAL and web2py throws an error.
>
> I can see the table during "define_table" and I see it added to the 
> _LAZY_TABLES list.  But later, when the table is referenced, it does NOT 
> show up in the list when I am performing _getattr_ on the name of the table 
> in the DAL instance.  It's like it magically disappears between the 
> "define_table" and the time the controller is executed.
>
> It seems like the problem is here, in the dal.py file:
>  
>
>     def define_table(
>         self,
>         tablename,
>         *fields,
>         **args
>         ):
>         if not isinstance(tablename,str):
>             raise SyntaxError, "missing table name"
>         elif hasattr(self,tablename) or tablename in self.tables:
>             if not args.get('redefine',False):
>                 raise SyntaxError, 'table already defined: %s' % tablename
>      ...etc
>
>
> The call to "hasattr" is processed as a call to the routine "__getattr__" 
> shown below:
>  
>
>     def __getattr__(self, key):
>         if ogetattr(self,'_lazy_tables') and \
>                 key in ogetattr(self,'_LAZY_TABLES'):
>             tablename, fields, args = self._LAZY_TABLES.pop(key)
>             return self.lazy_define_table(tablename,*fields,**args)
>         return ogetattr(self, key)
>
>
> But __getattr__ throws an exception if the key is not present, yet the 
> define_table code which calls it does not look for or process the 
> exception.  Something is amiss in this code but I'm not in tune enough to 
> figure out the original intent of "hasattr" in this context.
>
> Am I missing something?  (probably)
>
> -- Joe B.
>
>
>

-- 



Reply via email to