【Flask】ORM一对一关联关系

您所在的位置:网站首页 false是1 【Flask】ORM一对一关联关系

【Flask】ORM一对一关联关系

2023-01-21 21:39| 来源: 网络整理| 查看: 265

在sqlalchemy中,如果想要将两个模型映射成一对一的关系,那么应该在父模型中,指定引用的时候,要传递一个uselist=False这个参数进去。就是告诉父模型,以后引用这个从模型的时候,不再是一个列表了,而是一个对象了。

方法一:参照一对多关联,把uselist=false,加在没有外键的对象中,其他的和前面一对多关联是一样的 配置数据库、创建数据库引擎、创建基类 from sqlalchemy import create_engine, Column, Integer, ForeignKey, String, TEXT, Boolean, DATE, DECIMAL from sqlalchemy.ext.declarative import declarative_base from datetime import date from sqlalchemy.orm import sessionmaker,relationship,backref # 数据库的配置变量 HOSTNAME = '127.0.0.1' PORT = '3306' DATABASE = 'test' USERNAME = 'root' PASSWORD = 'root' DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE) #创建数据库引擎 engine=create_engine(DB_URI) #创建模型类基类 Base=declarative_base(engine) #创建session对象 session=sessionmaker(engine)() 创建模型类 class Person(Base): __tablename__='t_person' #创建表名,最好是t_开头 id=Column(name='id',type_=Integer,primary_key=True,autoincrement=True) name=Column(name='name',type_=String(255)) age=Column(name='age',type_=Integer) address=Column(name='address',type_=String(255)) country=Column(name='country',type_=String(50)) city=Column(name='city',type_=String(50)) # 当前人对应的身份证 id_card=relationship('ID_Card') def __str__(self): return f'Person-编号{self.id}姓名{self.name}年领{self.age} class ID_Card(Base): __tablename__ = 't_id_card' card_number = Column(name='card_number', type_=String(18), primary_key=True) p_id=Column(Integer,ForeignKey('t_person.id')) # 表示该身份证对应的人 person=relationship('Person') def __str__(self): return f"ID_Card-身份证号{self.card_number}" 查询数据

1、查询名字叫python的身份证号:

def select(): p1=session.query(Person).filter(Person.name=='python').first() print(p1) #名字叫python的人物信息 print(p1.id_card) #名字叫python的身份证信息 print(p1.id_card.card_number) #名字叫python的身份证号 Person-编号1姓名python年领18 ID_Card-身份证号112121212 112121212

2、查询身份证号112121212是谁?

def select(): #查询身份证号112121212是谁? id1=session.query(ID_Card).filter(ID_Card.card_number=='112121212').first() print(id1) #身份证是112121212的身份证信息 print(id1.person) #身份证是112121212的人物信息 print(id1.person.name) #身份证是112121212的人物名字 ID_Card-身份证号112121212 Person-编号1姓名python年领18 python

方法二:推荐使用 特别注意:uselist=False:告诉id_card不是一个列表

人的信息表 class Person(Base): __tablename__='t_person' #创建表名,最好是t_开头 id=Column(name='id',type_=Integer,primary_key=True,autoincrement=True) name=Column(name='name',type_=String(255)) age=Column(name='age',type_=Integer) phone = Column(name='phone', type_=String(11), unique=True) address=Column(name='address',type_=String(255)) country=Column(name='country',type_=String(50)) city=Column(name='city',type_=String(50)) # 当前人对应的身份证,uselist=False:告诉id_card不是一个列表 #id_card=relationship('ID_Card',uselist=False) def __str__(self): return f'Person-编号{self.id}姓名{self.name}年领{self.age}' 身份证表 class ID_Card(Base): __tablename__ = 't_id_card' card_number = Column(name='card_number', type_=String(18), primary_key=True) p_id=Column(Integer,ForeignKey('t_person.id')) # 表示该身份证对应的人, person=relationship('Person',backref=backref('id_card',uselist=False)) def __str__(self): return f"ID_Card-身份证号{self.card_number}"

特别注意2:person=relationship(‘Person’,backref=backref(‘id_card’,uselist=False))的写法

查询数据

1、查询名字叫python的身份证号:

def select(): p1=session.query(Person).filter(Person.name=='python').first() print(p1) #名字叫python的人物信息 print(p1.id_card) #名字叫python的身份证信息 print(p1.id_card.card_number) #名字叫python的身份证号 Person-编号1姓名python年领18 ID_Card-身份证号112121212 112121212

2、查询身份证号112121212是谁?

def select(): id1=session.query(ID_Card).filter(ID_Card.card_number=='112121212').first() print(id1) #身份证是112121212的身份证信息 print(id1.person) #身份证是112121212的人物信息 print(id1.person.name) #身份证是112121212的人物名字 ID_Card-身份证号112121212 Person-编号1姓名python年领18 python 更新数据

3、将手机号为13888888888的人物的身份证号改为“666666666”

def update(): res=session.query(Person).filter(Person.phone=='13888888888').first() res.id_card.card_number='666666666' session.commit()

4、将身份证编号为3的信息,人物姓名改为zhilong

def update(): res1=session.query(ID_Card).filter(ID_Card.card_id==3).first() print(res1.person) res1.person.p_name='zhilong' session.commit() 删除数据

5、将手机号为13111118的人物信息删除

def delete(): res2=session.query(Person).filter(Person.phone=='1311118').first() session.delete(res2) session.commit()

6、将手机号为1311115的人物信息的身份证信息删除

def delete(): res2 = session.query(Person).filter(Person.phone == '1311115').first() print(res2.id_card) session.delete(res2.id_card) session.commit()

7、将身份证编号为2的人物信息删除

def delete(): res3=session.query(ID_Card).filter(ID_Card.card_id==2).first() session.delete(res3.person) session.commit()

建表的时候可能会出现的问题:

sqlalchemy.exc.InvalidRequestError: On relationship ID_Card.person, ‘dynamic’ loaders cannot be used with many-to-one/one-to-one relationships and/or uselist=False.

是因为在模型类中加了懒加载,而一对一模式不需要懒加载 错误的:

id_card=relationship('ID_Card',backref=backref('person',lazy='dynamic',uselist=False))

正确的是

id_card=relationship('ID_Card',backref=backref('person',uselist=False))


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3