【Flask】ORM一对一关联关系

导读:本篇文章讲解 【Flask】ORM一对一关联关系,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

在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://{}:{}@{}:{}/{}?charset=utf8mb4'.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))

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/74177.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!