分类: LINUX
2011-12-22 16:02:15
下面走马观花式地看看基本的关联模式,下面这些是我们需要导入的一些模块和方法
>>> from sqlalchemy import Table, Column, Integer, ForeignKey >>> from sqlalchemy.orm import relationship, backref >>> from sqlalchemy.ext.declarative import declarative_base >>> Base = declarative_base() 一对多(One To Many)一个多对多的关系,是通过子类对父类的外键引用,然后在父类上使用 relationship() 来获得所有与之相关联的子类对象。
>>> class Parent(Base): ... __tablename__ = 'parent' ... id = Column(Integer, primary_key = True) ... children = relationship('Child') ... >>> class Child(Base): ... __tablename__ = 'child' ... id = Column(Integer, primary_key = True) ... parent_id = Column(Integer, ForeignKey('parent.id')) ...我们接着可以使用下面这样的方式来互相调用:
parent.children 来获得所有与 parent 相关联的 child 对象
多对一(Many To One)多对一的关系是将外键关联放在父表中, relationship() 在上一级表中使用:
>>> class Parent(Base): ... __tablename__ = 'parent' ... id = Column(Integer, primary_key = True) ... child_id = Column(Integer, ForeignKey('child.id')) ... child = relationship('Child') ... >>> class Child(Base): ... __tablename__ = 'child' ... id = Column(Integer, primary_key = True) ...或者 使用更简单的办法:
>>> class Parent(Base): ... __tablename__ = 'parent' ... id = Column(Integer, primary_key=True) ... child_id = Column(Integer, ForeignKey('child.id')) ... child = relationship("Child", backref="parents") 一对一(One To One)一对一其实很简单,看看多对一或者一对多,我们只需要把“多”的那一方设定成为“一”即可,在SQLAlchemy中,我们使用 uselist=False 即可:
>>> class Parent(Base): ... __tablename__ = 'parent' ... id = Column(Integer, primary_key = True) ... child = relationship('Child', uselist = False, backref = 'parent') ... >>> class Child(Base): ... __tablename__ = 'child' ... id = Column(Integer, primary_key = True) ... parent_id = Column(Integer, ForeignKey('parent.id')) ...或者我们将一对多转变为一对一也可,使用 backref() 函数:
>>> class Parent(Base): ... __tablename__ = 'parent' ... id = Column(Integer, primary_key = True) ... child_id = Column(Integer, ForeignKey('child.id')) ... child = relationship('Child', uselist = False, backref = 'parent', use list = False) ... >>> class Child(Base): ... __tablename__ = 'child' ... id = Column(Integer, primary_key = True) ... 多对多(Many To Many)我们需要使用除两个需要关联的表之外的另一张表专门来实现关联,这一张关联表是通过向 relationship() 方法中传递 secondary 参数来指定的:
>>> association_table = Table('association', Base.metadata, ... Column('left_id', Integer, ForeignKey('left.id')), ... Column('right_id', Integer, ForeignKey('right.id'))) >>> class Parent(Base): ... __tablename__ = 'left' ... id = Column(Integer, primary_key = True) ... children = relationship('Child', secondary=association_table) >>> class Child(Base): ... __tablename__ = 'right' ... id = Column(Integer, primary_key = True)一般情况下,我们都还需要让相关联的双方都能很方便地得到另一方的相关联的对象集,那么我们可以使用 backref 关键字:
>>> association_table = Table('association', Base.metadata, ... Column('left_id', Integer, ForeignKey('left.id')), ... Column('right_id', Integer, ForeignKey('right.id'))) >>> class Parent(Base): ... __tablename__ = 'left' ... id = Column(Integer, primary_key = True) ... children = relationship('Child', secondary=association_table, backref='parents') >>> class Child(Base): ... __tablename__ = 'right' ... id = Column(Integer, primary_key = True)secondary 参数还可以是一个可回调的变量,当只有在需要调用的时候被映射,使用这样的方法,我们可以在所有模块都已被初始化之后再创建相关联的表 association_table :
>>> class Parent(Base): ... __tablename__ = 'left' ... id = Column(Integer, primary_key=True) ... children = relationship("Child", ... secondary=lambda: association_table, ... backref="parents")