On Feb 17, 2014, at 6:23 PM, Rob Crowell <robccrow...@gmail.com> wrote:

> I am having a bit of trouble getting DeferredReflection working the way I 
> want; not sure if I am overlooking something obvious or if I just don't 
> really understand how it's supposed to work. 
> 
> I'm trying to define my models before creating my engine (this does not work):
> 
> Base = declarative_base(cls=DeferredReflection)
> 
> class CityStats(Base):
>     __tablename__ = 'city_stats'
>     __table_args__ = {'schema': 'prod', 'autoload': True}
> 
> if __name__ == '__main__':
>     engine = create_engine('...')
>     Base.metadata.bind = engine
>     Base.prepare(engine)
> 
> 
> When I run this I get an error creating the CityStats class: 
> "sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's 
> MetaData. Pass an engine to the Table via autoload_with=<someengine>, or 
> associate the MetaData with an engine via metadata.bind=<someengine>”

its all about the stack trace, lets look:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    class CityStats(Base):
  File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/ext/declarative/api.py", 
line 53, in __init__
    _as_declarative(cls, classname, cls.__dict__)
  File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/ext/declarative/base.py", 
line 251, in _as_declarative
    **table_kw)
  File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/schema.py", line 350, 
in __new__
    table._init(name, metadata, *args, **kw)
  File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/schema.py", line 423, 
in _init
    self._autoload(metadata, autoload_with, include_columns)
  File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/schema.py", line 439, 
in _autoload
    msg="No engine is bound to this Table's MetaData. "
  File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/base.py", line 459, in 
_bind_or_error

what we see here is that this script doesn’t get to create_engine() at all, 
it’s trying to hit the database as soon as you say “CityStats(Base)”.  Why is 
that?  Because you have “autoload=True” in your table args, which means, 
“reflect this table *right now*”.  That is, you are defeating the purpose of 
using DeferredReflection.

The solution is just take out that autoload=True.  Any class which descends 
from the Base here is automatically part of the “classes to reflect” since you 
have DeferredReflection at the base.

Also, if you’re on 0.9 take a look at the new “automap” extension, I’ve been 
using it and it’s pretty keen.  There’s one fix for it in not-yet-released 
0.9.3 but it’s only needed if you’re dealing with inheritance structures.


Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to