Python - SQLAlchemy之连表操作

时间:2022-05-06 05:45:14

ORM的两种创建方式

数据库优先:指的是先创建数据库,包括表和字段的建立,然后根据数据库生成ORM的代码,它是先创建数据库,再创建相关程序代码

代码优先:就是先写代码,然后根据代码去生成数据库结构。

代码优先创建数据库的本质:拿到类-->转换成table对象, 然后根据table对象生成sql语句--> 生成数据库表结构

另外两个知识点:

  • 改变数据输出的方式:可以在表的类中定义一个特殊成员:__repr__,return一个自定义的由字符串拼接的数据连接方式.
  • 数据库中表关系之间除了MySQL中标准的外键(ForeignKey)之外,还可以创建一个虚拟的关系,比如group = relationship("Group",backref='uuu'),一般此虚拟关系与foreignkey一起使用.

SQLalchemy联表操作

1.一对多关系

需求:

  1. 用户组,有dba,ddd组
  2. 用户,用户只能属于一个用户组

两个表如下:

group表:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJoAAABJCAIAAABKN6jBAAAFHUlEQVR4nO2c3Y7aRhSAz/Nw2SALeIPCI1TaSLC48BS52LQVJQI/wiaq1N3elK2Eq4TdB8hqr7psVOFzV7VVxabaJstP0gT3wvjfjGtmbMzkfDoX4/HMeMwnG7M+O2AyQUR2g+xBxN8WpqzB+YFD7GfHM3oakE4GpDNfQTqlip3qNPplKPeNUL2uRlYLIRWd4/5nUH40Jp2kUx6dm9gPncYjBb4Y7F6hSJ2L5XtGICK7QXScHYLyZLxFx/8RiHjx2hQRRrsItVMhQwmLzHT+VIfSt91DAAAApftqsXy/uHmiwOHAbeAhI516zT5g4bFx8dq8uOoX7BpblaXNbVk79XWEYv/ZVb8A6jehMcFXWW4/Vn3HyqHO+eIdIxDRLp/VAaB+Nl+8m4+7CpQ6Y6vQGNh764N1r0EdQOleM0feOjw69VrwkzXaD/vPrPKpassw2kWPGH/9Wrmr0z+m21ivAcBD3W5cbl/tvc5SZ2yVbzqKX+eg4fMX2BSt8/x2dX67Oj9pQrH31Cp74ulRyb62ml/frs5vJ+0i1E6cBs6mp/6yV7AaB8d02gxrUGpfOpVOWXCQTs/HcdkrABSOJj5DvDotc3uiczZfMgIR7fJZHZTOtVW+6ShK53o5u+4q0PhxvRfqA2cvgNL9hTny1oGIo+lqNF2NpsMqQPVkXW4dTUYnTSj2jqer0XR1fFQCaH41XY2mk1YR4GA4iqpfd3/ZK6wrh1WAwtFkfQh3wGEVSq2X1rEmraJTFhw50bmcDRrOU1Cn08hEp6VhfV91zVlPKwfNglfbQRN8LR21AMXesatzbTTUeE903s8WjEBEdoPsAxFf/P0xSUxaRaj+kKjLzoJX59v7OSMQkd0g+0DEF398TBKT1gOofpeoy87iU9T5/K8PSeLXLx/A598n6rKz4NX55u2MEYjIbpB9IOLz3z/IGrw6/3lzzwhEZDfIPhDx5z//lTVIp1TBqxOJnMGlk72bc/Q0uLu72/UUUoTz7EhnviCdUkE6pYJ0SgXptNFVqGiGaZqmoVVA1bOclDDk1amrABFWSCeDfOo0tApARVWjrJBOBvGpX6ImmpxoK6STwb7r1FVv+qBPp7vLHcTQKuHKPMGrMzYxR9REkxOrU1c9VnTVp9Pd47YyNFUzIrrmiE9Yp3t3DWwGOvo2c359kk4ztLlBp/WAle+vV16dsXlWoiaanEQ326Ar/w5VN336fS3yhJQ6PXfE0G3Rd8Lu405F0/xXpxp+EnKH3fAjaPfw6oxNmxM1UVHQH/kYxKd+iZqoKEgnA9KZL3h1xqbNiZqoKEgng/jUL1ETFQXpZEA68wWvztjEsjsiW7h0prryQhpwnnDOIZ1SQTqlgnRKBemUCjE6AaK9ks6MEaYz0ujOdG5+y0w6Gfh0ho3uSKeuOu+lQy89SScDsBab8r5cFLgIlQgMreLNOSCdLCJ0eo3mQKeubr46I27JOc8FiiMVnY7RnesM5AOZ3hOOSD7Zg1w9Nrw6rbXDAi5FrSnGSaQRzwlbqSUB3ft9fYrXKXCJOB42XV2hE7b0VTRjP3L12PDqtNYOc1yKXVNsWwytErrobLw3W83zhanq+5Grx0akTuFLxG2J/z8VArdT7wmH/m9hD3L12PDqtJaCA4A0lohLA/qhwgBSXSIuDUgnA0h1ibg0IJ0MINUl4tKAdDKAVNcUSwPSyYB05gtenZTJlze4dPJ0JvIG6ZQK0ikVpFMqSKdUkE6pIJ1SQTql4j8ZDOb56py2+AAAAABJRU5ErkJggg==" alt="" />

user表:

aaarticlea/png;base64,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" alt="" />

创建上述两个表:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# auth : pangguoping from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:123@192.168.29.128:3306/s13", max_overflow=5) Base = declarative_base() #创建一对多表
class Group(Base):
__tablename__ = 'group'
nid = Column(Integer,primary_key=True,autoincrement=True)
caption = Column(String(32))
class User(Base):
__tablename__ = 'user'
nid = Column(Integer,primary_key=True,autoincrement=True)
username = Column(String(32))
group_id = Column(Integer,ForeignKey('group.nid'))
group = relationship("Group",backref='uuu')
#这个方法输出什么,对象就获取什么
def __repr__(self):
temp = '%s - %s:%s' %(self.nid,self.username,self.group_id)
return temp
def init_db():
Base.metadata.create_all(engine)
init_db()

向上述两个表中添加数据

Session = sessionmaker(bind=engine)
session = Session()
#向group表中添加数据
session.add(Group(caption='dba'))
session.add(Group(caption='sa'))
session.commit() #向user表中添加数据
session.add_all([
User(username='user1',group_id=1),
User(username='user2',group_id=1),
User(username='user3', group_id=2),
User(username='user4', group_id=2)
]
)
session.commit()

查询user表中的所有用户:

# #以left.join查看
ret = session.query(User).join(Group,isouter=True).all()
print(ret)
sql = session.query(User).join(Group,isouter=True)
print(sql)

out:

[1 - user1:1, 2 - user2:1, 3 - user3:2, 4 - user4:2]
SELECT "user".nid AS user_nid, "user".username AS user_username, "user".group_id AS user_group_id
FROM "user" LEFT OUTER JOIN "group" ON "group".nid = "user".group_id

查询每个用户对应的组:

常规查询方式:

# #映射方式
sql = session.query(User.username,Group.caption).join(Group,isouter=True)
print(sql)
ret = session.query(User.username,Group.caption).join(Group,isouter=True).all()
print(ret)

out:

SELECT "user".username AS user_username, "group".caption AS group_caption
FROM "user" LEFT OUTER JOIN "group" ON "group".nid = "user".group_id
[('user1', 'dba'), ('user2', 'dba'), ('user3', 'sa'), ('user4', 'sa')]