【问题标题】:Can SQLAlchemy automatically create relationships from a database schema?SQLAlchemy 可以自动从数据库模式创建关系吗?
【发布时间】:2013-01-02 03:04:46
【问题描述】:

使用外键从现有的(SQLite)数据库开始,SQLAlchemy 是否可以自动构建relationships

SQLAlchemy 类是通过__table_args__ = {'autoload': True} 自动创建的。

目标是轻松访问相关表中的数据,而无需手动添加所有关系(即不使用sqlalchemy.orm.relationship()sqlalchemy.orm.backref)。

【问题讨论】:

    标签: python sqlite sqlalchemy relationship foreign-key-relationship


    【解决方案1】:

    [更新]从 SQLAlchemy 0.9.1 开始,Automap extension 可以做到这一点。

    对于 SQLAlchemy

    SQLAlchemy 反射加载表之间的外键/主键关系。但不会在映射类之间创建关系。实际上反射不会为您创建映射类 - 您必须指定映射类名称。

    其实我认为加载外键的反射支持是一个很好的帮手和节省时间的工具。使用它,您可以使用联接构建查询,而无需指定要用于联接的列。

    from sqlalchemy import *
    from sqlalchemy import create_engine, orm
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import relationship
    
    
    
    metadata = MetaData()
    Base = declarative_base()
    Base.metadata = metadata
    
    db = create_engine('<db connection URL>',echo=False)
    metadata.reflect(bind=db)
    
    cause_code_table = metadata.tables['cause_code']
    ndticket_table = metadata.tables['ndticket']
    
    sm = orm.sessionmaker(bind=db, autoflush=True, autocommit=True, expire_on_commit=True)
    session = orm.scoped_session(sm)
    
    q = session.query(ndticket_table,cause_code_table).join(cause_code_table)
    for r in q.limit(10):
        print r
    

    此外,当我使用反射对现有数据库运行查询时 - 我必须只定义映射的类名称、表绑定、关系,但不需要为这些关系定义表列。

    class CauseCode(Base):
        __tablename__ = "cause_code"
    
    class NDTicket(Base):
        __tablename__ = "ndticket"
        cause_code = relationship("CauseCode", backref = "ndticket")
    
    
    q = session.query(NDTicket)
    for r in q.limit(10):
        print r.ticket_id, r.cause_code.cause_code
    

    整体 SQLAlchemy 反射已经是强大的工具,可以节省我的时间,因此手动添加关系对我来说是一个很小的开销。

    如果我必须开发使用现有外键添加映射对象之间关系的功能,我将从使用reflection with inspector 开始。使用 get_foreign_keys() 方法提供了建立关系所需的所有信息——引用的表名、引用的列名和目标表中的列名。并将使用此信息将具有关系的属性添加到映射类中。

    insp = reflection.Inspector.from_engine(db)
    print insp.get_table_names()
    print insp.get_foreign_keys(NDTicket.__tablename__)
    >>>[{'referred_table': u'cause_code', 'referred_columns': [u'cause_code'], 'referred_schema': None, 'name': u'SYS_C00135367', 'constrained_columns': [u'cause_code_id']}]
    

    【讨论】:

      【解决方案2】:

      从 SQLAlchemy 0.9.1 开始,(目前是实验性的)Automap 扩展似乎就是这样做的:http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html

      【讨论】:

        猜你喜欢
        • 2014-10-06
        • 2011-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-06
        • 2016-01-29
        • 1970-01-01
        相关资源
        最近更新 更多