Python数据库操作之pymysql模块和sqlalchemy模块

参考博客https://www.cnblogs.com/aylin/p/5770888.html

pymysql

  1. 下载安装
    pip install pymysql
  2. 操作数据库
import pymysql


class MysqlSearch(object):

    def __init__(self):
        self.get_conn()
    
    def get_conn(self):
        """ 获取连接 """
        try:
            self.conn = pymysql.connect(
                host='localhost',
                port=3306,
                user='root',
                passwd='',
                db='news',
                charset='utf8')
        except Exception as e:
            print('Error:%s' %e)

    def close_conn(self):
        try:
            # 关闭连接
            if self.conn:
                self.conn.close()
        except Exception as e:
            print('Error: %s' %e)

    def get_one(self):
        # 准备SQL
        sql = 'SELECT * FROM news;'
        # 找到cursor
        cursor = self.conn.cursor()
        # 执行SQL
        cursor.execute(sql)
        # print(dir(cursor))
        # print(cursor.description)
        # 拿到结果
        data = cursor.fetchone()
        # print(data)
        # 将列名和数据组合成字典形式方便查询
        data = dict(zip([k[0] for k in cursor.description], data))
        # 处理数据
        print(data)
        print(data['title'])
        # 关闭cursor/连接
        cursor.close()
        self.close_conn()
        return data

    def get_more(self, page, page_size):
        # 准备SQL
        offset = (page - 1) * page_size  # 利用LIMIT实现翻页
        sql = f'SELECT * FROM news ORDER BY id LIMIT {offset}, {page_size};'
        # 找到cursor
        cursor = self.conn.cursor()
        # 执行SQL
        cursor.execute(sql)
        # print(dir(cursor))
        # print(cursor.description)
        # 拿到结果
        data = cursor.fetchall()
        # print(data)
        # 将列名和每一条数据组合成字典形式
        data = [dict(zip([k[0] for k in cursor.description], row)) for row in data]
        # 处理数据
        # print(data)
        # print(data['title'])
        # 关闭cursor/连接
        cursor.close()
        self.close_conn()
        return data

    def add_one(self):
        try:
            # 准备SQL
            sql = (
                """
                INSERT INTO news(title, image, content, types, created_at, is_valid) VALUE
                (%s, %s, %s, %s, NOW(), %s);
                """
                )
            # 准备连接和cursor
            cursor = self.conn.cursor()
            # 执行SQL
            cursor.execute(sql, ('title0', 'image_url', '新闻内容', '类型', 0))
            cursor.execute(sql, ('title1', 'image_url', '新闻内容', '类型', 1))
            # 提交数据到数据库
            # 提交事务
            self.conn.commit()
            # 关闭cursor和连接
            cursor.close()
        except Exception as e:
            print("Error: %s" %e)
            self.conn.rollback()  # 若出现一条错误则都不提交成功
        self.close_conn()

    def delete_one(self):
        try:
            # 准备SQL
            sql = (
                """
                DELETE FROM news WHERE title='title0' or title = 'title1';
                """
                )
            # 准备连接和cursor
            cursor = self.conn.cursor()
            # 执行SQL
            cursor.execute(sql)
            # 提交事务
            self.conn.commit()
            # 关闭cursor和连接
            cursor.close()
        except Exception as e:
            print("Error: %s" %e)
            self.conn.rollback()
        self.close_conn()



def main():
    obj = MysqlSearch()
    # data = obj.get_one()
    # print(data)

    # obj.add_one()

    # obj.delete_one()

    # data = obj.get_more(1, 20)
    # for item in data:
    #   print('\n', item)
        # print('\n', item['title'])


if __name__ == '__main__':
    main()

下面是我创建的一张表:


data_news

下面分别演示各个方法的结果:

obj = MysqlSearch()
data = obj.get_one()
get_one
obj.add_one()
add_one

可以看到数据库中成功插入了两条我想要插入的数据

obj.delete_one()
delete_one

可以看到我刚刚插入的两条title0和title1数据已经被删除了

data = obj.get_more(2, 5)
for item in data:
    print('\n', item)
    print('\n', item['title'])
get_more

可以看到如期输入了id为6-10的第二页数据,并在每一条数据下面输出了title信息


sqlalchemy简介

SQLAlchemy是Python编程语言下的一款开源软件。提供了SQL工具包及对象关系映射(ORM)工具,使用MIT许可证发行。

SQLAlchemy“采用简单的Python语言,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型”。SQLAlchemy的理念是,SQL数据库的量级和性能重要于对象集合;而对象集合的抽象又重要于表和行。因此,SQLAlchmey采用了类似于JavaHibernate的数据映射模型,而不是其他ORM框架采用的Active Record模型。不过,Elixir和declarative等可选插件可以让用户使用声明语法。

SQLAlchemy与数据库关系图如下:


image

sqlalchemy基本操作

  1. 安装sqlalchemy
    ==> 本文用的是mysql案例,所以需要一台有安装mysql数据库的机器
    ==> 使用Python的pip安装pip install sqlalchemy(如果既有Python2又有Python3的用pip3 install sqlalchemy)
    安装完后查看版本信息
import sqlalchemy
sqlalchemy.__version__
  1. 操作数据库
# ORM: Object Relational Mapping  对象关系映射
# https://bugs.mysql.com/bug.php?id=82414  Bug report  // Warning
# Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 481")
# result = self._query(query)

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, DateTime, Boolean

engine = create_engine('mysql+pymysql://username:passwd@localhost:port/db?charset=utf8', max_overflow=5) # max_overflow 最多多几个连接
Base = declarative_base()

Session = sessionmaker(bind=engine)

class News(Base):
    __tablename__ = 'news'
    id = Column(Integer, primary_key=True)
    title = Column(String(200), nullable=False)
    content = Column(String(2000), nullable=False)
    types = Column(String(10), nullable=False)
    created_at = Column(DateTime)
    image = Column(String(300), )
    author = Column(String(20), )
    view_count = Column(Integer)
    is_valid = Column(Boolean)


class OrmTest(object):

    def __init__(self):
        self.session = Session()

    def add_one(self):
        ''' 添加数据 '''
        new_obj = News(
            title='ORM标题',
            content='content',
            types='技术'
            )
        new_obj2 = News(
            title='title',
            content='content',
            types='types'
            )
        self.session.add(new_obj)
        self.session.add(new_obj2)
        self.session.commit()
        return new_obj

    def get_one(self):
        ''' 查询一条数据 '''
        return self.session.query(News).get(3)

    def get_more(self):
        ''' 查询多条数据 '''
        return self.session.query(News).filter_by(is_valid=True)

    def update_data(self, pk):
        ''' 修改数据 '''
        # 修改多条数据
        data_list = self.session.query(News).filter(News.id>2)
        # data_list = self.session.query(News).filter_by(is_valid=False)
        for item in data_list:
            item.is_valid = 1
            self.session.add(item)
        self.session.commit()
        # 修改单条数据
        new_obj = self.session.query(News).get(pk)
        if new_obj:
            new_obj.is_valid = 0
            self.session.add(new_obj)
            self.session.commit()
            return True
        return False

    def delete_data(self, pk):
        ''' 删除数据 '''
        # 获取要删除的数据
        new_obj = self.session.query(News).get(pk)
        if new_obj:
            self.session.delete(new_obj)
            self.session.commit()



def main():
    obj = OrmTest()
    # test = obj.add_one()
    # print(test.id)

    # test = obj.get_one()
    # if test:
    #   print(f'ID:{test.id} => title:{test.title}')
    # else:
    #   print('Not exist.')

    # result = obj.get_more()
    # print(result.count())
    # for new_obj in result:
    #   print(f'ID:{new_obj.id} => title:{new_obj.title}')

    # print(obj.update_data(3))
    # print(obj.delete_data(1))

if __name__ == '__main__':
    main()

我电脑里的MySQL是5.7版本,这里有一个不影响使用但会报Warning的BUG,Bug report:https://bugs.mysql.com/bug.php?id=82414
更多详细的可以参考官方文档
以及这篇邹业盛的中文博客

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

推荐阅读更多精彩内容