Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用关系时,SQLAlchemy不会自动填充外键字段_Python_Orm_Sqlalchemy - Fatal编程技术网

Python 使用关系时,SQLAlchemy不会自动填充外键字段

Python 使用关系时,SQLAlchemy不会自动填充外键字段,python,orm,sqlalchemy,Python,Orm,Sqlalchemy,我有一个简单的一对多关系。我有项目和设备课程。一个项目可以有多个设备s 当我使用关系将设备添加到项目中时,程序的行为与我预期的不同 完整的程序如下: from sqlalchemy import Column, String, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship Base = declarative_base()

我有一个简单的一对多关系。我有
项目
设备
课程。一个
项目
可以有多个
设备
s

当我使用关系将设备添加到项目中时,程序的行为与我预期的不同

完整的程序如下:

from sqlalchemy import Column, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

Base = declarative_base()


class Project(Base):
    __tablename__ = "Projects"

    name = Column('Name', String(50), primary_key=True)
    devices = relationship("Device", back_populates="project")


class Device(Base):
    __tablename__ = "Devices"

    serial_no = Column('SerialNo', String(50), primary_key=True)
    project_name = Column('ProjectName', String(50), ForeignKey("Projects.Name"))
    project = relationship("Project", back_populates="devices", foreign_keys=[project_name])


if __name__ == "__main__":
    p = Project(name="MyProject")
    d = Device()

    print("Before adding device:")
    print(f"p.devices: {p.devices}")
    print(f"d.project: {d.project}")
    print(f"d.project_name: {d.project_name}")

    p.devices.append(d)

    print("After adding device:")
    print(f"p.devices: {p.devices}")
    print(f"d.project: {d.project}")
    print(f"d.project_name: {d.project_name}")
以下是输出:

Before adding device:
p.devices: []
d.project: None
d.project_name: None
After adding device:
p.devices: [<__main__.Device object at 0x000001FF049B22B0>]
d.project: <__main__.Project object at 0x000001FF03DB0D30>
d.project_name: None
添加设备之前:
p、 设备:[]
d、 项目:无
d、 项目名称:无
添加设备后:
p、 设备:[]
d、 项目:
d、 项目名称:无
除最后一个
d.project\u name
外,所有输出均符合预期
d.project\u name
仍然返回
None
。由于
d.project
返回该项目对象,我希望它也被填充为
MyProject


我遗漏了什么?

我建议您花一点时间浏览本手册中的发动机配置和
会话
管理部分。
会话
是将对象与数据库同步的东西,您在这里的示例中没有使用它。将对象添加到
会话中
,并在对象的任何挂起更改“刷新”到数据库后,使用
Session.flush()
Session.commit()
@SuperShoot填充外键。我已经阅读了ORM教程,但我不清楚是否需要会话才能使此关系正常工作。我知道我的更改不会反映到我使用的数据库中,但我认为即使我没有提交到数据库中,对象也会反映更改。大多数情况下,主键是自动递增的,因此需要首先将父对象插入到数据库中,以获得分配给它的主键值,然后才能在任何子对象上更新外键。因此,您需要建立一个引擎,该引擎可以像
engine=create\u engine(“sqlite://”)一样简单,用于内存中的数据库,还有一个会话类,
Session=Session\u maker(bind=engine)
。然后创建会话实例,
s=session()
,将父对象添加到其中,
s.add(p)
,然后在
p.devices.append(d)
之后添加
s.commit()
。然后访问
d.project\u name
,您会发现它被填充在子对象上。好的,我明白了,非常感谢。我建议您花一点时间浏览。
会话
是将对象与数据库同步的东西,您在这里的示例中没有使用它。将对象添加到
会话中
,并在对象的任何挂起更改“刷新”到数据库后,使用
Session.flush()
Session.commit()
@SuperShoot填充外键。我已经阅读了ORM教程,但我不清楚是否需要会话才能使此关系正常工作。我知道我的更改不会反映到我使用的数据库中,但我认为即使我没有提交到数据库中,对象也会反映更改。大多数情况下,主键是自动递增的,因此需要首先将父对象插入到数据库中,以获得分配给它的主键值,然后才能在任何子对象上更新外键。因此,您需要建立一个引擎,该引擎可以像
engine=create\u engine(“sqlite://”)一样简单,用于内存中的数据库,还有一个会话类,
Session=Session\u maker(bind=engine)
。然后创建会话实例,
s=session()
,将父对象添加到其中,
s.add(p)
,然后在
p.devices.append(d)
之后添加
s.commit()
。然后访问
d.project\u name
,您会发现它填充在子对象上。好的,我明白了,非常感谢。