当前位置: 首页 > article >正文

【python】sqlalchemy

SQLAlchemy

安装

pip install SQLAlchemy

查看版本号

import sqlalchemy
print(sqlalchemy.__version__)

建立连接Engine

from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://127.0.0.1:3306/wss_demmo?charset=utf8&user=root&password=123456',echo=True,  # 打印日志future=True  # 新版本接口格式
)

执行SQL

查询数据

from sqlalchemy import create_engine,text
with engine.connect() as conn:result = conn.execute(text("select * from test"))print(result.all())
逐行读取数据
with engine.begin() as conn:result = conn.execute(text("SELECT * FROM TEST"));for row in result:print(f"id:{row.id},name:{row.name}")

默认返回的是元组类型,可以通过索引和属性名称来获取每一组的数据

使用‎‎result.mappings()‎修饰符‎‎转换为‎‎MapingResult‎‎对象,这样一来集合的成员类型都是字典类型。

with engine.begin() as conn:result = conn.execute(text("SELECT * FROM TEST"));for row in result.mappings():print(row)  # {'id': '8', 'name': '赵六'}

传递参数

with engine.begin() as conn:result = conn.execute(text("SELECT * FROM TEST WHERE id > :id"),{"id":5});print(result.all())

参数使用:参数名来指定,并在后面的字典参数中来进行传值。如 :id与后面的字典就是对应关系。

当需要传递多组参数,执行多次语句时,可以传递字典列表来实现,如下面的保存示例。

提交更改

默认事务在执行以后会自动回滚,如果需要提交数据,需要调用conn.commit();

with engine.connect() as conn:result = conn.execute(text("INSERT INTO test (id, name) VALUES (:id, :name)"),[{"id": 5, "name": "赵六"}, {"id": 6, "name": "张七"}]);conn.commit()

还有另一种提交方法,使用begin来获取连接,这种会在事务结束时自动提交

with engine.begin() as conn:result = conn.execute(text("INSERT INTO test (id, name) VALUES (:id, :name)"),[{"id": 8, "name": "赵六"}, {"id": 7, "name": "张七"}]);

ORM

ORM会话执行SQL

from sqlalchemy.orm import Session
stmt = text("SELECT * FROM TEST WHERE id > :id").bindparams(id=3)
with Session(engine) as session:result = session.execute(stmt);print(result.all())

同connection一样,进行插入和修改操作时需要提交(session.commit())才可以生效。

with Session(engine) as session:result = session.execute(text("UPDATE TEST SET  name=:name where id=:id"), [{"name": "展招", "id": 5}, {"name": "包大人", "id": 6}]);session.commit()

元数据MetaData

创建元数据对象

from sqlalchemy import MetaData
metadata_obj = MetaData()
Table对象
from sqlalchemy import Table, Column, Integer, String
user_table = Table("user_account",metadata_obj,Column('id', Integer, primary_key=True),  # 主键约束Column('name', String(30)),Column('fullname', String(50))
)
简单约束
from sqlalchemy import ForeignKey
address_table = Table("address",metadata_obj,Column('id', Integer, primary_key=True),  # 主键约束Column('user_id', ForeignKey('user_account.id'), nullable=False),  # ForeignKey:外键约束   nullable:非空约束Column('email_address', String(100), nullable=False)
)

在‎‎列‎定义中使用‎‎ForeignKey‎对象时,我们可以省略该‎‎列‎‎的数据类型 ;它是从相关列的自动推断出来的,在上面的示例中,列的‎‎Integer‎数据类型。‎user_account.id

查看表对象的主键约束

print(user_table.primary_key)
DDL

元数据对象通过已经关联的table对象生成数据库表。

metadata_obj.create_all(engine)

MetaData‎‎对象还具有一个‎‎MetaData.drop_all()‎‎方法,该方法将删除所有元数据对象关联的数据库表。

新建ORM模型

通过注册获取元数据基类

from sqlalchemy.orm import registrymapper_registry = registry()
Base = mapper_registry.generate_base()

还提供了一个方法可以直接获取到基类

from sqlalchemy.orm import declarative_base
Base = declarative_base()

现在就可以根据基类来映射类了

from datetime import datetime
import pymysql
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String, DateTime, Enum, SmallInteger, Boolean
from enum import IntEnum
from sqlalchemy.dialects.mysql import TINYINT, CHARclass SexEnum(IntEnum):MAN = 1WOMAN = 0class Student(Base):__tablename__ = "student"id = Column(type_=Integer, primary_key=True, name="id", autoincrement=True)stu_no = Column(type_=Integer, nullable=False, comment="学号", doc="只在代码中能看到的注释", unique=True)stu_name = Column(CHAR(16), nullable=False, comment="姓名", default="默认值")sex = Column(Enum(SexEnum), default=None, comment="性别")age = Column(TINYINT(unsigned=True), default=0, comment="年龄")create_at = Column(type_=DateTime, default=datetime.now())is_vaild = Column(Boolean, default=True)

创建数据表

# 通过注册获取的元数据来创建表
mapper_registry.metadata.create_all(engine)
# 通过基类的元数据创建表
Base.metadata.create_all(engine)
表反射

通过表信息逆向生成Table对象,不需要创建具体的实体对象。Table对象的使用方法和上面的一样。

address = Table("address", metadata_obj, autoload_with=engine)

关联

一对多关联
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Column, Integer, String, DateTime, Enum, SmallInteger, Boolean, ForeignKey
class Address:__tablename__ = "address"stu_id = Column(Integer, ForeignKey(Student.id))  # 外键user = relationship("User", backref="address")  # 一对多
一对一关联
user = relationship("User", backref="address",uselist=False)  # 一对一

ORM数据操作

创建Session

from sqlalchemy.orm import Session
session = Session(bind=engine, future=True)

执行的sql都需要使用session的execute方法或者engine.connect()来执行,如果对数据进行了操作,还需要commit才可以生效。

插入

插入单行

使用Insert.values()

from sqlalchemy.orm import Session
from sqlalchemy import insert
session = Session(bind=engine, future=True)
stmt = insert(User).values(name='spongebob', fullname="Spongebob Squarepants")
with session:session.execute(stmt)session.commit()

使用compile()方法可以获取到执行sql的相关信息

compiled = stmt.compile()
print(compiled)#INSERT INTO user_account (name, fullname) VALUES (:name, :fullname)
print(compiled.params#{'name': 'spongebob', 'fullname': 'Spongebob Squarepants'}

如果需要获取插入后生成的主键,可以这样获取

result = session.execute(stmt)
session.commit()
print(result.inserted_primary_key)#(3,)

返回元组,因为主键可能包含多个列。这称为‎‎复合主键‎‎。

使用session.add()

from sqlalchemy.orm import Session
session = Session(bind=engine, future=True)
print("连接")
with session:stu = Student(id=3, stu_no=3, stu_name="李四", sex=SexEnum.MAN)Address(user=stu)session.add(stu)session.commit()
插入多行
with engine.connect() as conn:result = conn.execute(insert(User),[{"name": "sandy", "fullname": "Sandy Cheeks"},{"name": "patrick", "fullname": "Patrick Star"}])conn.commit()
    print("连接")with session:stu_list = []addrs = []for i in range(10):stu = Student(stu_no=i, stu_name="李四", sex=SexEnum.MAN)addrs.append(Address(user=stu))stu_list.append(stu)session.add_all(addrs)session.add_all(stu_list)session.commit()
将查询结果直接保存到另一张表
select_stmt = select(User.id,User.name+"的地址")
insert_stmt = insert(Address).from_select(["user_id", "email_address"], select_stmt
)
print(insert_stmt)
插入的同时并返回所需数据

mysql数据库好像不行,可以在其他数据库上试试;

‎UPDATE 和 DELETE 语句也支持 RETURNING 功能

insert_stmt = insert(address_table).returning(address_table.c.id, address_table.c.email_address)
print(insert_stmt)
#INSERT INTO address (id, user_id, email_address)
#VALUES (:id, :user_id, :email_address)
#RETURNING address.id, address.email_address

也可以在insert_statement中结合使用

print(insert_stmt.returning(address_table.c.id, address_table.c.email_address))

查询

主键查询
session.get(Entity,key);
select查询
stmt = select(Student.id,Student.sex)
rows = session.execute(stmt).fetchall()
for row in rows:print(row)

条件查询

stmt = select(User).where(User.name == '张三')
print(stmt) #SELECT user_account.id, user_account.name, user_account.fullname #FROM user_account #WHERE user_account.name = :name_1
with engine.connect() as conn:result = conn.execute(stmt)for row in result:print(row)
http://www.lryc.cn/news/2419363.html

相关文章:

  • VC++6.0 MSDN下载地址
  • DotNetTextBox V3.0 所见即所得编辑器控件Ver3.3.3 Free(免费版)
  • 高质量C++/C编程指南(林锐)
  • 四、六级考试的标准分计算方法-“710分转换表”
  • 移花接木!轻松搞定暴风影音2关联暴风影音1图标
  • 简单了解一下博弈论
  • Label换行
  • 内网信息收集与上传下载
  • 几个免费的国外php空间
  • 苹果最新系统ios7_手机资讯:你绝对不知道的iOS7隐藏功能
  • Scratch软件编程等级考试一级——20220320
  • Kali-登录暴力破解器工具-medusa使用
  • 基于flex的三层架构特效之效果介绍
  • 免费发布一个网站(保姆级图文教程)
  • Sqlserver 之 SequenceNumber(序列)
  • 转PDP-11时代 美国的大跃进运动
  • 老毛桃winpe优盘启动系统个性修改全攻略.(全)
  • WEP/WPA/WPA2/WPA3初识
  • 中华黑豹计算机病毒,关于中华黑豹病毒...-爱毒霸交流论坛
  • mplayer在CLI下收听网络广播和网络电视
  • Terminal Service License Server
  • 中兴V880 ROOT、刷Recovery刷机教程全解
  • 【历史上的今天】11 月 8 日:为开源献身的互联网之子;卷积神经网络 LeNet-5 问世;特斯拉发明遥控器
  • [SceneKit专题]14-Motion-Control运动控制
  • 织梦CMS企业官网模版源码 淋浴卫浴产品官网源码 卫浴行业模版源码 家居卫浴设计
  • 如何搭建个人博客网站【图/文教程】
  • Quartus-II入门
  • wordpress一些常用代码
  • MFC 刷新失效的Picture控件
  • Gensim做中文主题模型(LDA)