SQLAlchemy declarative syntax with autoload (reflection) in Pylons

后端 未结 4 1717
日久生厌
日久生厌 2020-12-16 01:57

I would like to use autoload to use an existings database. I know how to do it without declarative syntax (model/_init_.py):

def init_model(engine):         


        
相关标签:
4条回答
  • 2020-12-16 02:17

    Check out the Using SQLAlchemy with Pylons tutorial on how to bind metadata to the engine in the init_model function.

    If the meta.Base.metadata.bind(engine) statement successfully binds your model metadata to the engine, you should be able to perform this initialization in your own init_model function. I guess you didn't mean to skip the metadata binding in this function, did you?

    0 讨论(0)
  • 2020-12-16 02:21

    I just tried this using orm module.

    Base = declarative_base(bind=engine)
    
    Base.metadata.reflect(bind=engine)
    

    Accessing tables manually or through loop or whatever:

    Base.metadata.sorted_tables
    

    Might be useful.

    0 讨论(0)
  • 2020-12-16 02:28
    from sqlalchemy import MetaData,create_engine,Table
    engine = create_engine('postgresql://postgres:********@localhost/db_name')
    
    metadata = MetaData(bind=engine)
    
    rivers = Table('rivers',metadata,autoload=True,auto_load_with=engine)
    
    from sqlalchemy import select
    
    s = select([rivers]).limit(5)
    engine.execute(s).fetchall()
    

    worked for me. I was getting the error because of not specifying bind when creating MetaData() object.

    0 讨论(0)
  • 2020-12-16 02:32

    OK, I think I figured it out. The solution is to declare the model objects outside the model/__init__.py. I concluded that __init__.py gets imported as the first file when importing something from a module (in this case model) and this causes problems because the model objects are declared before init_model() is called.

    To avoid this I created a new file in the model module, e.g. objects.py. I then declared all my model objects (like Event) in this file.

    Then, I can import my models like this:

    from PRJ.model.objects import Event
    

    Furthermore, to avoid specifying autoload-with for each table, I added this line at the end of init_model():

    Base.metadata.bind = engine
    

    This way I can declare my model objects with no boilerplate code, like this:

    class Event(Base):
        __tablename__ = 'events'
        __table_args__ = {'schema': 'events', 'autoload': True}
    
        event_identifiers = relationship(EventIdentifier)
    
        def __repr__(self):
            return "<Event(%s)>" % self.id
    
    0 讨论(0)
提交回复
热议问题