代码之家  ›  专栏  ›  技术社区  ›  uberrebu

使用sqlalchemy和postgresql创建一对多关系的问题

  •  0
  • uberrebu  · 技术社区  · 5 年前

    当我尝试以下指南中的SQLAlchemy关系示例时: Basic Relationship Patterns

    #!/usr/bin/env python
    # encoding: utf-8
    from sqlalchemy import create_engine
    from sqlalchemy import Table, Column, Integer, ForeignKey
    from sqlalchemy.orm import relationship, sessionmaker
    from sqlalchemy.ext.declarative import declarative_base
    
    engine = create_engine('sqlite:///:memory:', echo=True)
    Session = sessionmaker(bind=engine)
    session = Session()
    Base = declarative_base(bind=engine)
    
    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 = relationship("Parent")
    
    Base.metadata.create_all()
    
    p = Parent()
    session.add(p)
    session.commit()
    c = Child(parent_id=p.id)
    session.add(c)
    session.commit()
    print "children: {}".format(p.children[0].id)
    print "parent: {}".format(c.parent.id)
    

    它工作得很好,但在指南中,它说模型应该是:

    class Parent(Base):
        __tablename__ = 'parent'
        id = Column(Integer, primary_key=True)
        **children = relationship("Child", back_populates="parent")**
    
    class Child(Base):
        __tablename__ = 'child'
        id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('parent.id'))
        **parent = relationship("Parent", back_populates="children")**
    

    back_populates 或 backref

    0 回复  |  直到 9 年前
        1
  •  195
  •   Brendan Abel    6 年前

    如果你使用 backref

    class Parent(Base):
        __tablename__ = 'parent'
        id = Column(Integer, primary_key=True)
        children = relationship("Child", backref="parent")
    
    class Child(Base):
        __tablename__ = 'child'
        id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('parent.id'))
    

    不 回溯 ,以及界定 relationship 如果您不使用 back_populates ,sqlalchemy将不知道如何连接关系,因此修改一个关系也会修改另一个关系。

    在您的示例中,您定义了 是单独的,但没有提供 后人 参数,修改一个字段不会自动更新事务中的另一个字段。

    >>> parent = Parent()
    >>> child = Child()
    >>> child.parent = parent
    >>> print(parent.children)
    []
    

    看看它是如何不自动填写 children 领域

    后人 参数,sqlalchemy将连接字段。

    class Parent(Base):
        __tablename__ = 'parent'
        id = Column(Integer, primary_key=True)
        children = relationship("Child", back_populates="parent")
    
    class Child(Base):
        __tablename__ = 'child'
        id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('parent.id'))
        parent = relationship("Parent", back_populates="children")
    

    所以现在我们得到

    >>> parent = Parent()
    >>> child = Child()
    >>> child.parent = parent
    >>> print(parent.children)
    [Child(...)]
    

    回溯 我也会这样做。使用 后人