2011-07-21 40 views
6

如何告訴SQLAlchemy自動將基本外鍵引用作爲對其他ORM對象的引用而不是整數字段?如何在SQLAlchemy或SqlSoup ORM中自動反映表關係?

在這兩個SQLAlchemy和它的SqlSoup,表列會自動反映和關係可以手動進行定義:

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

...

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

回答

0

試試這個魔法) 可以用於簡單FK關係,沒有db方案

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() 
相關問題