Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind engine when I want, when using declarative_base in SQLAlchemy?

Here's my code:

from sqlalchemy import create_engine, Column, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

database_url = 'mysql://some_path'
engine = create_engine(database_url)
Base = declarative_base(engine)

class Users(Base):
    __tablename__ = 'Users'
    __table_args__ = {'autoload':True}

metadata = Base.metadata
Session = sessionmaker(bind=engine)
session = Session()

It works, but...
Is it possible to bind engine when I want, not only at import time? So I can wrap this implementation into class.

For now, I get

    class Users(Base):
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.6.5-py2.5.egg/sqlalchemy/ext/declarative.py", line 1231, in __init__
    _as_declarative(cls, classname, cls.__dict__)
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.6.5-py2.5.egg/sqlalchemy/ext/declarative.py", line 1122, in _as_declarative
    **table_kw)
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.6.5-py2.5.egg/sqlalchemy/schema.py", line 209, in __new__
    table._init(name, metadata, *args, **kw)
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.6.5-py2.5.egg/sqlalchemy/schema.py", line 260, in _init
    msg="No engine is bound to this Table's MetaData. "
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.6.5-py2.5.egg/sqlalchemy/schema.py", line 2598, in _bind_or_error
    raise exc.UnboundExecutionError(msg)
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>

when engine is not specified: Base = declarative_base()

like image 710
kolobos Avatar asked Nov 18 '10 14:11

kolobos


People also ask

What is declarative_base in SQLAlchemy?

The declarative_base() base class contains a MetaData object where newly defined Table objects are collected. This object is intended to be accessed directly for MetaData -specific operations. Such as, to issue CREATE statements for all tables: engine = create_engine('sqlite://') Base.

What does SQLAlchemy create engine do?

The create_engine() method of sqlalchemy library takes in the connection URL and returns a sqlalchemy engine that references both a Dialect and a Pool, which together interpret the DBAPI's module functions as well as the behavior of the database.

What is an engine in SQLAlchemy?

The Engine is the starting point for any SQLAlchemy application. It's “home base” for the actual database and its DBAPI, delivered to the SQLAlchemy application through a connection pool and a Dialect , which describes how to talk to a specific kind of database/DBAPI combination.

What is Declared_attr in SQLAlchemy?

declarative_base() class sqlalchemy.ext.declarative. declared_attr(fget, cascading=False) Mark a class-level method as representing the definition of a mapped property or special declarative member name. @declared_attr turns the attribute into a scalar-like property that can be invoked from the uninstantiated class.


1 Answers

At least with SQLAlchemy 0.9 you can defer the binding by using DeferredReflection. See the example in the Using Reflection with Declarative section of the manual.

There, you can find the following example (simplified):

from sqlalchemy.ext.declarative import declarative_base, DeferredReflection

Base = declarative_base(cls=DeferredReflection)

class Foo(Base):
    __tablename__ = 'foo'
    bars = relationship("Bar")

class Bar(Base):
    __tablename__ = 'bar'

Base.prepare(e)

e is the engine.

like image 125
jgbarah Avatar answered Nov 14 '22 22:11

jgbarah