【问题标题】:How to automatically reflect table relationships in SQLAlchemy or SqlSoup ORM?如何在 SQLAlchemy 或 SqlSoup ORM 中自动反映表关系?
【发布时间】:2011-10-10 06:56:20
【问题描述】:

如何告诉 SQLAlchemy 自动将基本外键引用反映为对其他 ORM 对象的引用而不是整数字段?

SQLAlchemySqlSoup 中,表格列会自动反映,关系可以手动定义:

class User(Base):
    __table__ = metadata.tables['users']
    loan = relation(Loans)

...

You can define relationships on SqlSoup classes:
>>> db.users.relate('loans', db.loans)

【问题讨论】:

    标签: sql orm foreign-keys sqlalchemy sqlsoup


    【解决方案1】:

    试试这个魔法) 适用于简单的 FK 关系,并且没有数据库方案

    from sqlalchemy import create_engine, MetaData
    from sqlalchemy.orm import mapper, relation
    
    engine = create_engine("sqlite://", echo=True)
    
    engine.execute('''
        create table foo (
            id integer not null primary key,
            x integer
        )''')
    
    engine.execute('''
        create table bar (
            id integer not null primary key,
            foo_id integer,
            FOREIGN KEY(foo_id) REFERENCES foo(id)
        )''')
    
    metadata = MetaData()
    metadata.reflect(bind=engine)
    
    
    MAPPERS = {
    }
    
    repr_name = lambda t: '%s%s' % (t[0].upper(), t[1:])
    
    for table in metadata.tables:
    
        cls = None
        # 1. create class object
        cls_name = repr_name(str(table))
        exec("""class %s(object): pass""" % cls_name)
        exec("""cls = %s""" % cls_name)
    
        # 2. collect relations by FK
        properties = {}
        for c in metadata.tables[table].columns:
            for fk in c.foreign_keys:
                name = str(fk.column).split('.')[0]
                properties.update({
                    name: relation(lambda: MAPPERS[repr_name(name)]),
                })
    
        # 3. map table to class object 
        mapper(cls, metadata.tables[table], properties=properties)
    
    
        MAPPERS.update({cls_name: cls})
    
    if __name__ == '__main__':
        from sqlalchemy.orm import sessionmaker
    
        print 'Mappers: '
        for m in MAPPERS.values():
            print m
    
        session = sessionmaker(bind=engine)()
    
        foo = Foo()
        foo.x = 1
        session.add(foo)
    
        session.commit()
    
        print session.query(Foo).all()
    
        bar = Bar()
        bar.foo = foo
        session.add(bar)
        session.commit()
    
        print session.query(Bar).all()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 2015-04-29
      • 2015-07-06
      • 2018-10-04
      • 1970-01-01
      • 2015-12-02
      相关资源
      最近更新 更多