Re: [sqlalchemy] Help with DeferredReflection and setting up an engine at runtime?
Interesting, thanks Michael. I didn't realize autoload was implied when using DeferredReflection but that makes sense. Thanks! On Monday, February 17, 2014 7:17:34 PM UTC-5, Michael Bayer wrote: > > > On Feb 17, 2014, at 6:23 PM, Rob Crowell > > 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=, or associate the MetaData with an engine > via metadata.bind=” > > > its all about the stack trace, lets look: > > Traceback (most recent call last): > File "test.py", line 8, in > 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. > > > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.
Re: [sqlalchemy] Help with DeferredReflection and setting up an engine at runtime?
On Feb 17, 2014, at 6:23 PM, Rob Crowell 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=, or > associate the MetaData with an engine via metadata.bind=” its all about the stack trace, lets look: Traceback (most recent call last): File "test.py", line 8, in 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. signature.asc Description: Message signed with OpenPGP using GPGMail
[sqlalchemy] Help with DeferredReflection and setting up an engine at runtime?
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=, or associate the MetaData with an engine via metadata.bind=" Of course it does work if I create my engine and set Base.metadata.bind BEFORE I define the CityStats model (this works): engine = create_engine('...') Base.metadata.bind = engine class CityStats(Base): __tablename__ = 'city_stats' __table_args__ = {'schema': 'prod', *'autoload': True*} Base.prepare(engine) I'm trying to avoid some kind of model_init() function that everyone who imports my models.py file will have to remember to call before importing my models. Is this possible? -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.