一个超方便使用SQL的Python神器!转载

原创
小哥 3年前 (2022-10-17) 阅读数 55 #大杂烩

检索来源:数据管道传输来源:数据管道转载来源:数据管道来源:数据管道

作者:严锦,一个喜欢编程的程序员。"言淦说"主理人

背景

其实一开始用的其实,一开始用的其实,一开始用的 pymysql 然而,它被发现维护起来比较麻烦,也存在代码注入的风险,所以直接使用ORM框架。

ORM即 Object Relational Mapper 这可以简单地理解为数据库表和Python类之间的映射通过操作类之间的映射来完成,通过操作Python类,它可以间接操作数据库。

Python的ORM框架更为人所知,因为框架更为人所知,因为框架更为人所知 SQLAlchemyPeewee 在这里我们不做比较,只是简单地解释一下我们个人对SQLAlchemy我们希望有一些使用,我们希望有一些使用

  • sqlalchemy版本: 1.3.15

  • pymysql版本: 0.9.3

  • mysql版本: 5.7

初始化工作初始化工作初始化工作

一般使用ORM框架,都会有一些初始化工作初始化工作初始化工作,比如数据库连接,定义基础映射等。

以MySQL例如,要创建数据库连接,只需传入DSN字符串就足够了。哪里 echo 指示是否输出对应的指示是否对应sql语句,这对调试更有帮助。

from sqlalchemy import create_engine

engine = create_engine(mysql+pymysql://$user:$password@$host:$port/$db?charset=utf8mb4, echo=True)

个人设计

对于我个人来说,介绍给我个人,为我个人介绍,介绍ORM框架,我的项目将引用框架,我的项目将引用框架时,我的项目将引用MVC该模型进行了以下设计。哪里 model 存储的是一些数据库模型,即Python类; model_op 存储每个模型对应的操作,即添加、删除、检查和更改;main.py)要执行数据库操作,只需调用)要执行数据库操作,只需调用model_op层,而不关心层,不必关心层,也不必关心model层,从而实现解耦。层,从而实现解耦。层,从而实现解耦。层,从而解耦。

├── main.py
├── model
│   ├── __init__.py
│   ├── base_model.py
│   ├── ddl.sql
│   └── py_orm_model.py
└── model_op
    ├── __init__.py
    └── py_orm_model_op.py

映射声明(Model介绍)

例如,如果我们有一张这样的测试表

create table py_orm (
    id int(11) NOT NULL AUTO_INCREMENT COMMENT 唯一id,
    name varchar(255) NOT NULL DEFAULT  COMMENT 名称,
    attr JSON NOT NULL COMMENT 属性,
    ct timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,
    ut timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP COMMENT 更新时间,
    PRIMARY KEY(id)
)ENGINE=InnoDB COMMENT 测试表;

在ORM在框架中,映射的结果如下所示Python类

# py_orm_model.py
from .base_model import Base
from sqlalchemy import Column, Integer, String, TIMESTAMP, text, JSON

class PyOrmModel(Base):
    __tablename__ = py_orm

    id = Column(Integer, autoincrement=True, primary_key=True, comment=唯一id)
    name = Column(String(255), nullable=False, default=, comment=名称)
    attr = Column(JSON, nullable=False, comment=属性)
    ct = Column(TIMESTAMP, nullable=False, server_default=text(CURRENT_TIMESTAMP), comment=创建时间)
    ut = Column(TIMESTAMP, nullable=False, server_default=text(CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP), comment=更新时间)

首先,我们可以看到首先,我们可以首先看到,我们可以首先看到,我们可以看到PyOrmModel继承了Base类,这是类,这是 sqlalchemy 提供了一个基类,它将对我们声明的Python类做一些检查,我把它放在课堂上做一些检查,我把它放在班上做一些检查,我把它放进去base_model中。

# base_model.py
# 一般base_model您所要做的只是一些初始化工作,所有的初始化工作都已完成

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:33306/orm_test?charset=utf8mb4", echo=False)

第二,每一秒,每一秒,每一下一个,每一个Python类必须全部包含类必须全部包含 __tablename__ 属性,否则找不到对应的表。

第三,有两种创建数据表的方法,第一种当然是在MySQL在您的中创建的是在您的中创建的在Python类定义很好,它将正常运行;第二个是通过orm框架创建,如下面创建的框架,例如,下面创建的框架,如下所示

# main.py
# 请注意此处的导入路径。请注意此处的导入路径,请注意此处的导入路径。Base如果路径不正确,则不会成功创建表。

from sqlachlemy_lab import Base, engine

if __name__ == __main__:
    Base.metadata.create_all(engine)

创造效果。创建效果。创造效果。

...
2020-04-04 10:12:53,974 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE py_orm (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    name VARCHAR(255) NOT NULL DEFAULT  COMMENT 名称, 
    attr JSON NOT NULL COMMENT 属性, 
    ct TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    ut TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (id)
)

第四,关于字段属性第四,关于字段属性

  • 1.primary_key和autoincrement相对较好的理解是,更好地理解,最好理解为MySQL主键和增量属性的。主键和增量属性。的主键和增量属性

  • 2.如果是int类型,则不需要指定长度,而如果是varchar类型,则必须指定它。类型,则必须指定它。必须指定类型。

  • 3.nullable对应的是对应的对应的是MySQL中的 NULLNOT NULL

  • 4.关于 defaultserver_default : default代表的是ORM框架级缺省值,即如果在插入时没有为该字段赋值,将使用我们定义的缺省值。server_default表示数据库级别的默认值DDL语句中的default关键字。

Session介绍

在SQLAlchemy文档中提到,数据库的添加、删除和更改是通过session去表演。去执行。以执行。将会被执行。

>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)

>>> session = Session()

>>> orm = PyOrmModel(id=1, name=test, attr={})
>>> session.add(orm)

>>> session.commit()

>>> session.close()

如上所述,我们可以看到,对于每个操作,我们需要更改session这是获取、提交和释放的一种多余且繁琐的方式。这太多余和繁琐了,所以我们通常会做一层包装。

1.使用上下文管理器方法,该处理使用上下文管理器方法,处理session在异常回滚和关闭中,这一部分与参考文章几乎完全相同。

# base_model.py
from contextlib import contextmanager
from sqlalchemy.orm import sessionmaker, scoped_session

def _get_session():
    """获取session"""
    return scoped_session(sessionmaker(bind=engine, expire_on_commit=False))()

# 在这里对session统一管理,包括抓取、提交、回滚、关闭
@contextmanager
def db_session(commit=True):
    session = _get_session()
    try:
        yield session
        if commit:
            session.commit()
    except Exception as e:
        session.rollback()
        raise e
    finally:
        if session:
            session.close()

2.在PyOrmModel将两个方法添加到Add Two方法添加两个方法到Add Two方法model和dict转换之间的转换切换之间的转换

class PyOrmModel(Base):
    ...

    @staticmethod
    def fields():
        return [id, name, attr]

    @staticmethod
    def to_json(model):
        fields = PyOrmModel.fields()
        json_data = {}
        for field in fields:
            json_data[field] = model.__getattribute__(field)
        return json_data

    @staticmethod
    def from_json(data: dict):
        fields = PyOrmModel.fields()

        model = PyOrmModel()
        for field in fields:
            if field in data:
                model.__setattr__(field, data[field])
        return model

3.数据库操作的封装,与引用的文章不同,我直接调用session这样调用方就不需要注意model层次分明,减少耦合。层,减少耦合。层,以减少耦合。层,以减少耦合。

# py_orm_model_op.py
from sqlachlemy_lab.model import db_session
from sqlachlemy_lab.model import PyOrmModel

class PyOrmModelOp:
    def __init__(self):
        pass

    @staticmethod
    def save_data(data: dict):
        with db_session() as session:
            model = PyOrmModel.from_json(data)
            session.add(model)

    # 没有查询操作的查询操作,没有查询操作的查询操作commit
    @staticmethod
    def query_data(pid: int):
        data_list = []
        with db_session(commit=False) as session:
            data = session.query(PyOrmModel).filter(PyOrmModel.id == pid)
            for d in data:
                data_list.append(PyOrmModel.to_json(d))

            return data_list

4.调用方

# main.py
from sqlachlemy_lab.model_op import PyOrmModelOp

if __name__ == __main__:
    PyOrmModelOp.save_data({id: 1, name: test, attr: {}})

有关完整代码,请参见。有关完整代码,请参见。

https://github.com/yangancode/python\_lab/tree/master/sqlachlemy\_lab

这是我开发的一个小型机器人公共,目前添加了天气查询955公司名单,注意时间查询;稍后还会增加图片和每日送书抽奖活动,以及猥亵功能,欢迎体验、举办

机器人公众号已经上线,欢迎来到骚扰

推荐阅读:
入门: 最完整的零基学习最全面的零基学习最完整的零基学习Python的问题  | 从零开始学习从零基础学习从零基础学习8个月的Python  | 实战项目 |学Python这是捷径,这是捷径,这是捷径
干货:爬行豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析最佳球员分析 |   从万众期待到口碑惨败!唐探3令人失望  | 笑新伊田图龙记笑新伊田图龙记笑新伊田图龙记 | 谜语之王回答灯谜之王灯谜之王谜语之王 |用Python人山人海素描图人山人海素描图人山人海 Dishonor太火了,我用机器学习做了一个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python日常酷跑游戏日常酷跑游戏日常酷跑游戏!
AI: 会写诗的机器人会写诗的机器人会写诗的机器人 | 给图片上色给图片上色给图片上色 | 预测收入 | 《耻辱》太火了,我用机器学习做了一部迷你推荐系统电影
小工具: Pdf转Word易于修复表单和水印!易于处理的表单和水印!轻松修复桌子和水印!易于修复的形式和水印! | 一键把html将页面另存为网页另存为网页另存为pdf!|  再见PDF提款费!提款费!提款费!提款费用! | 用90构建最强大的代码行构建最强大的代码行构建最强大的代码行PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一个固定的低成本机票提醒!制作一张别针的低价机票提醒! |60代码行做了一个语音墙纸切换,天天见女士!

年度弹出文案年度弹出文案年度爆炸性文案

  • 1). 卧槽!Pdf转Word用Python轻松搞定 !

  • 2).学Python闻起来好香!我用100一行代码做了一个网站,帮助人们做了一行代码,做了一个网站,帮助了人们做了一行代码,帮助了人们PS旅行图片赚鸡腿吃旅行图片赚鸡腿

  • 3).第一次播放量过亿,火爆全网,我分析了《波妹》,发现了这些秘密

  • 4). 80一行行代码!使用Python让救济金做正确的事做做的人做好事的人A梦分身

  • 5).你必须掌握的东西你必须掌握20个python代码,简短而紧凑,永无止境的有用代码,简短而甜蜜,永无止境的有用的代码,简短而紧凑,永无止境的使用代码,简短而甜蜜,永无止境的用途

  • 6). 30个Python古怪技能集古怪小贴士收藏古怪技能集

  • 7). 我总结的80《菜鸟学习专页》《菜鸟学习专页》《菜鸟学习》Python精选干货.pdf》,都是干货

  • 8). 再见Python!我要学Go了!2500词深度分析词深度分析词深度分析 !

  • 9).发现了一只舔狗的福利!这Python爬虫神器太酷了,不能自动下载女孩的照片

点击阅读原文点击查看点击点击阅读点击阅读原文点击查看B放我鸽子看录像!站在我的录像带上!在视频里放我鸽子!站在我的录像带上!

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门