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
,您会发现它填充在子对象上。好的,我明白了,非常感谢。