2Python全栈之路系列之SQLAchemy
admin
2023-05-25 14:41:10
0

Python全栈之路系列之SQLAlchemy


SQLAlchemy的是Python SQL工具包和对象关系映射器,让应用程序开发者的全部功能和SQL的灵活性。

它提供了一套完整的众所周知的企业级持久性模式,专为高效率和高性能的数据库访问,改编成一个简单的Python化领域语言。


SQLAlchemy的哲学

SQL数据库的行为不像对象集合的较具规模和业绩开始关系; 对象集合表现得不像越抽象开始关系表和行。 SQLAlchemy的目的是满足这两个原则。

SQLAlchemy认为数据库是关系代数发动机,而不仅仅是一个表的集合,行可以不仅从表中选择,但也加入和其他select语句; 任何这些单元可被组合成一个较大的结构,SQLAlchemy的表达式语言基础上,从它的核心这个概念。

SQLAlchemy是最有名的对象关系映射器(ORM),提供数据映射模式 ,其中类可以在开放式的,多种方式被映射到数据库中的可选组件-允许对象模型和数据库模式中,以开发干净地分离从开始方式。

SQLAlchemy的对这些问题的总体思路是大多数其它SQL/ORM工具,根植于所谓的complimentarity-导向的方式完全不同; 而不是藏起来了SQL和关系对象的细节自动化墙后面,所有的进程都充分一系列组合的,透明的工具中暴露出来 。 该库发生在自动冗余任务的工作,而开发商仍然在数据库中是如何组织和SQL是如何构造的控制。

SQLAlchemy的主要目标是改变你对数据库和SQL的方式!

SQLAlchemy的使用

数据库的连接

MySQL-Python

mysql+mysqldb://:@[:]/

pymysql

mysql+pymysql://:@/[?]

MySQL-Connector

mysql+mysqlconnector://:@[:]/

查看版本

>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.0.14'

创建与删除表

单表创建

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Index, UniqueConstraint, ForeignKey
from sqlalchemy.orm import sessionmaker

engine = create_engine('mysql+pymysql://root:as@127.0.0.1:3306/tesql?charset=utf8', echo=True)  # echo=True输出生成的SQL语句

Base = declarative_base()  # 生成一个ORM基类

class UserInfo(Base):
    __tablename__ = 'UserInfo'  # 表名
    """
    创建字段
    index=True  普通索引
    unique=T  唯一索引
    """
    id = Column(Integer, primary_key=True, autoincrement=True)  # primary_key=主键,autoincrement=自增
    name = Column(String(32))
    password = Column(String(16))
    
    __table_args__ = (
        Index('id', 'name'),  # 联合索引
        UniqueConstraint('name', 'password', name='name_password')  # 联合唯一索引,name索引的名字
    )
    
    # 让查询出来的数据显示中文
    def __repr__(self):
        return self.name
        
Base.metadata.create_all(engine)  # 把所有集成Base类的类,创建表结构

上面的代码其实就是创建了一个UserInfo表,包含了三个字段,实际执行的SQL语句如下:

CREATE TABLE `UserInfo` (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    name VARCHAR(32), 
    password VARCHAR(16), 
    PRIMARY KEY (id), 
    CONSTRAINT name_password UNIQUE (name, password)
)

因为在创建引擎的时候加入了echo=True,所以执行的SQL会在控制台输出出来,以便于我们排查问题。

创建一对多表

class Favor(Base):
    __tablename__ = 'favor'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    caption = Column(String(50), default='red', unique=True)
    
class Person(Base):
    __tablename__ = 'person'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    favor_id = Column(Integer, ForeignKey("favor.nid"))

创建多对多表

# 组
class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)
    port = Column(Integer, default=22)
    
# 服务器
class Server(Base):
    __tablename__ = 'server'
    id = Column(Integer, primary_key=True, autoincrement=True)
    hostname = Column(String(64), unique=True, nullable=False)
    
# 服务器组,第三张表
class ServerToGroup(Base):
    __tablename__ = 'servertogroup'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    server_id = Column(Integer, ForeignKey('server.id'))
    group_id = Column(Integer, ForeignKey('group.id'))

删除表

Base.metadata.drop_all(engine)  # 把所有集成Base类的类,删除表

操作表

增加数据

添加单条数据

MySesion = sessionmaker(bind=engine)
session = MySesion()

# 创建一条数据
users = UserInfo(name='Hello', password='World')

# 把数据添加到表内
session.add(users)

# 提交生效
session.commit()

添加多少数据

session.add_all([
    UserInfo(name='A', password='1'),
    UserInfo(name='B', password='2')
])
# 提交
session.commit()
删除数据
session.query(UserInfo).filter(UserInfo.name == 'a').delete()
session.commit()
查询

获取某个表中的所有内容

result = session.query(UserInfo).all()
print(result)

修改数据

session.query(UserInfo).filter(UserInfo.id == 8).update({"name": "ffff"})
session.commit()

查询数据

获取所有

result = session.query(UserInfo).all()

获取指定字段

result = session.query(UserInfo.name, UserInfo.password).all()

获取指定的

result = session.query(UserInfo).filter_by(name='b').all()# 返回的是一个列表

获取第一条

result = session.query(UserInfo).filter_by(name='b').first()
# 获取值中的某个属性
result.name

获取数据出现的个数

result = session.query(UserInfo).filter_by(name='b').count()

使用and_or_进行查询

导入and_or_模块

from sqlalchemy import and_, or_

and_

for row in session.query(UserInfo).filter(and_(UserInfo.name == 'A', UserInfo.password == 1)):
    print(row)

or_

for row in session.query(UserInfo).filter(or_(UserInfo.name == 'Hello', UserInfo.password == 1)):
    print(row)

关联查询

创建以下数据库

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, relationships
from sqlalchemy import Column, Integer, String, Index, UniqueConstraint, ForeignKey
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('mysql+pymysql://root:as@127.0.0.1:3306/tesql')

Base = declarative_base()

class Son(Base):
    __tablename__ = 'son'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    father = relationship('Father')
    # 创建外键
    father_id = Column(Integer, ForeignKey('father.id'))
    
class Father(Base):
    __tablename__ = 'father'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    son = relationship('Son')
    # son = relationship('Son', backref='Father') 相当于上面两个relationship
    
# 生成表
Base.metadata.create_all(engine)

往表里添加数据

Session = sessionmaker(bind=engine)
session = Session()

# 添加父亲的数据
F = Father(name='as')
session.add(F)
session.commit()

# 添加儿子的数据
S1 = Son(name='Son1', father_id=1)
S2 = Son(name='Son2', father_id=1)
session.add_all([S1, S2])
session.commit()

# 另外一种添加数据的方式
F = session.query(Father).filter_by(id=1).first()
S3 = Son(name='Son3')
# 要用追加的方式进行添加,F.son是一个列表,如果不用append将会把之前的数据对应的值进行删除
F.son.append(S3)
session.add(F)
session.commit()

通过父亲找到所有的儿子

result = session.query(Father).filter_by(name='as').first()
for n in result.son:
    print(n.name)

通过儿子找到父亲

result = session.query(Son).filter_by(name='Son2').first()
print(result.father.name, result.name)
# son = relationship('Son', backref='Father')
# print(result.father.name, result.name)

join

result = session.query(Father.name.label('kkk'), Son.name.label('ppp')).join(Son)
# label('kkk')相当于起了一个别名,等于sql中的as
print(result)
>>>>>
SELECT father.name AS kkk, son.name AS ppp 
FROM father JOIN son ON father.id = son.father_id

多对多实例

在上面的多对多的代码中的Server类加入一下代码:

g = relationship("Group", secondary=ServerToGroup.__table__, backref='s')
# secondary 如果有第三张表自动加进来

然后生成数据库表.

添加组与主机的数据

G1 = Group(name='G1', port=22)
G2 = Group(name='G2', port=22)

S1 = Server(hostname='Linux-node1')
S2 = Server(hostname='Linux-node2')

session.add_all([G1, G2, S1, S2])
session.commit()

往第三张表里面添加关联数据

GS1 = ServerToGroup(server_id=1, group_id=1)
GS2 = ServerToGroup(server_id=2, group_id=2)
session.add_all([GS1, GS2])
session.commit()

通过relationship进行数据的添加

# 获取ID=1的主机
S = session.query(Server).filter_by(id=1).first()
# 获取所有主机组
G = session.query(Group).all()

S.g = G
# 添加数据
session.add_all([S, ])
# 提交到数据库中
session.commit()

#Python全栈之路 #Sqlalchemy


相关内容

热门资讯

空调1.5p是什么意思 制冷量3200W的是1.2匹空调,也有人叫小1.5匹空调。制冷量3500W的空调是1.5匹空调,也有...
燃气灶噗呲噗呲的声音什么原因 风门调节不当。燃气灶风门缺口位置和燃烧器的进风口的孔连接处,如果连接有问题出现进气太多的情况或太少的...
老式居民楼,老式蹲便,水箱内总... 老式居民楼毕竟有这么多年了,家里的老式蹲便器也有这么多年了,所以说蹲便器如果是放水的时候出现这种声音...
中央空调传感器故障原因除方法 中央空调传感器是一种重要的电器元件,起到监测环境温度、湿度等数据并将其传输给控制系统的作用。然而,由...
凤凰探访俄军前线后勤厨房:配备... 据凤凰卫视报道,凤凰记者卢宇光8月4日走进顿巴斯前线俄军某指挥所后勤保障排的厨房,早晨7点,基地军官...
抄袭者请注意:沉睡25年的条例... 【文/芯科状元】七月末上海一个闷热的傍晚,浦东张江一家射频前端公司的产品总监老陈把电脑合上,又打开。...
时隔两年,美驻日大使再次缺席 据日本共同社8月4日报道,美国驻日本大使馆当地时间周二宣布,大使乔治·格拉斯将缺席6日举行的广岛市和...
伊朗、阿曼霍尔木兹海峡重开协议... 伊朗和美国官员近日均透露,伊朗与阿曼正接近达成一项协议,以恢复霍尔木兹海峡的船舶通行。与此同时,一艘...
脱下长衫3年后,孔乙己的皮质醇... 作者|谢明宏 编辑|李春晖有网友去查皮质醇,被医生告知“小红书看多了”。2026年的赛博确诊全面升级...
布局亚洲!泽连斯基提出外交新方... 据凤凰卫视援引乌克兰国家通讯社报道,乌克兰总统泽连斯基近日在一次会议上提出外交新方向,将加强与亚洲国...