Flask-SQLAlchemy(MySQL)之一对多、一对一、多对多关系

一对多

  1. 创建两个模型
class Person(db.Model):
    __tablename__ = 'person'
    name = db.Column(db.String(20), primary_key=True)
    age = db.Column(db.Integer)
    birth = db.Column(db.Date)
    phone = db.Column(db.String(11), unique=True)

    # 使用关系函数定义关系属性
    cars = db.relationship('Car')

    def __repr__(self):
        return '姓名:{name} 年龄:{age} 生日:{birth} 电话:{phone}'.format(name=self.name, age=self.age, birth=self.birth,
                                                                 phone=self.phone)


class Car(db.Model):
    name = db.Column(db.String(10), primary_key=True)
    price = db.Column(db.Float)
    # 定义外键(表明.字段名)
    course_phone = db.Column(db.String(11), db.ForeignKey('person.phone'))

    def __repr__(self):
        return '汽车类型:{name} 总价:{price}'.format(name=self.name, price=self.price)
  1. 通过设置外键建立关系
@app.cli.command()
def insertpc():
    person = Person(name='老赵', age=27, birth=datetime.datetime.now(), phone='17777777777')
    car1 = Car(name='五菱宏光', price=55000.00, course_phone='17777777777')
    car2 = Car(name='吉利自由舰', price=43000.00, course_phone='17777777777')
    db.session.add(person)
    db.session.add(car1)
    db.session.add(car2)
    db.session.commit()
    click.echo('insert')

或者通过关系属性cars调用append建立关系

@app.cli.command()
def insertpc():
    person = Person(name='老赵', age=27, birth=datetime.datetime.now(), phone='17777777777')
    car1 = Car(name='五菱宏光', price=55000.00)
    car2 = Car(name='吉利自由舰', price=43000.00)
    db.session.add(person)
    person.cars.append(car1)
    person.cars.append(car2)
    db.session.commit()
    click.echo('insert')

通过remove解绑关系

person.cars.remove(car1)
db.session.commit()
  1. 查询
@app.cli.command()
def querypc():
    person = Person.query.first()
    click.echo(person.cars)

查询结果如下:

[汽车类型:五菱宏光 总价:55000.0, 汽车类型:吉利自由舰 总价:43000.0]

建立双向关系

  1. 创建两个模型
class Person(db.Model):
    __tablename__ = 'person'
    name = db.Column(db.String(20), primary_key=True)
    age = db.Column(db.Integer)
    birth = db.Column(db.Date)
    phone = db.Column(db.String(11), unique=True)

    # 使用关系函数定义关系属性
    cars = db.relationship('Car', back_populates='person')

    def __repr__(self):
        return '姓名:{name} 年龄:{age} 生日:{birth} 电话:{phone}'.format(name=self.name, age=self.age, birth=self.birth,
                                                                 phone=self.phone)


class Car(db.Model):
    name = db.Column(db.String(10), primary_key=True)
    price = db.Column(db.Float)
    # 定义外键(表明.字段名)
    course_phone = db.Column(db.String(11), db.ForeignKey('person.phone'))

    person = db.relationship('Person', back_populates='cars')

    def __repr__(self):
        return '汽车类型:{name} 总价:{price}'.format(name=self.name, price=self.price)
  1. 建立关系
@app.cli.command()
def insertpc():
    person = Person(name='老赵', age=27, birth=datetime.datetime.now(), phone='17777777777')
    car1 = Car(name='五菱宏光', price=55000.00)
    car2 = Car(name='吉利自由舰', price=43000.00)
    db.session.add(person)
    person.cars.append(car1)
    person.cars.append(car2)
    db.session.commit()
    click.echo('insert')
  1. 查询
@app.cli.command()
def queryc():
    car = Car.query.first()
    click.echo('{person} {car} '.format(person=car.person, car=car))

查询结果如下:

姓名:老赵 年龄:27 生日:2018-10-24 电话:17777777777 汽车类型:五菱宏光 总价:55000.0

一对一关系

  1. 创建两个模型,注意:创建一对一关系是通过将uselist设为False
class Husband(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(10))
    age = db.Column(db.Integer)

    wife = db.relationship('Wife', uselist=False)

    def __repr__(self):
        return '老公:{name} 年齡:{age}'.format(name=self.name, age=self.age)


class Wife(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(10))
    age = db.Column(db.Integer)
    husband_id = db.Column(db.Integer, db.ForeignKey('husband.id'))

    husband = db.relationship('Husband')

    def __repr__(self):
        return '老婆:{name} 年齡:{age}'.format(name=self.name, age=self.age)
  1. 建立关系,注意:一对一关系不能使用append,因为是单个记录,所以使用=
@app.cli.command()
def inserthw():
    husband = Husband(name='老王', age=24)
    wife = Wife(name='小红', age=18)
    db.session.add(husband)
    husband.wife = wife
    db.session.commit()
    click.echo('insert')
  1. 查询
@app.cli.command()
def queryhw():
    husband = Husband.query.first()
    click.echo('{husband} {wife}'.format(husband=husband, wife=husband.wife))

查询结果如下:

老公:老王 年齡:24 老婆:小红 年齡:18

多对多关系

  1. 建立存储多对多模型的外键对应关系的关联表
association_table = db.Table('association', db.Column('customer_id', db.Integer, db.ForeignKey('customer.id')),
                             db.Column('product_id', db.Integer, db.ForeignKey('product.id')))
  1. 建立两个模型,secondary设为关联表的名称,具体可查看relationship
class Customer(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(10))
    work = db.Column(db.String(20))
    products = db.relationship('Product', secondary=association_table, back_populates='customers')

    def __repr__(self):
        return '姓名:{name} 公司:{work}'.format(name=self.name, work=self.work)


class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(10))
    price = db.Column(db.Float)
    customers = db.relationship('Customer', secondary=association_table, back_populates='products')

    def __repr__(self):
        return '产品类型:{name} 单价:{price}'.format(name=self.name, price=self.price)
  1. 建立关系
@app.cli.command()
def insertcp():
    customer1 = Customer(name='程老板', work='大兴有限公司')
    customer2 = Customer(name='李老板', work='弘成科技')
    customer3 = Customer(name='司马老板', work='小马加油有限公司')
    product1 = Product(name='丝绸', price=35.12)
    product2 = Product(name='铝合金', price=54.45)
    product3 = Product(name='盐', price=3.00)
    db.session.add(customer1)
    customer1.products.append(product1)
    customer1.products.append(product2)
    customer2.products.append(product2)
    customer3.products.append(product1)
    customer3.products.append(product3)
    product1.customers.append(customer1)
    product1.customers.append(customer3)
    product2.customers.append(customer2)
    product2.customers.append(customer1)
    product3.customers.append(customer3)
    db.session.commit()
    click.echo('insert')
  1. 查询
@app.cli.command()
def querycp():
    customer = Customer.query.first()
    click.echo('{customer}  购买了  {products}'.format(customer=customer, products=customer.products))

查询结果:

姓名:程老板 公司:大兴有限公司  购买了  [产品类型:铝合金 单价:54.45, 产品类型:丝绸 单价:35.12]

参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容