数据库mariadb的连接

一 数据库的连接
数据库的连接同上下文管理with 一样,需要先开启,再操作,最后关闭
1) 开启连接数据库

import pymysql
conn = pymysql.connect(host='172.25.254.69', user='root',
                password='redhat', charset='utf8')

表示连接的是69这台主机,以root的身份,密码为redhat,其中编码格式为utf8
如果你不设置host这项的话,默认连接的是本地的数据库
当然,官方定义了很多的参数,看情况而定你的参数为哪些,上面的为必要参数而已

def __init__(self, host=None, user=None, password="",
                 database=None, port=0, unix_socket=None,
                 charset='', sql_mode=None,
                 read_default_file=None, conv=None, use_unicode=None,
                 client_flag=0, cursorclass=Cursor, init_command=None,
                 connect_timeout=10, ssl=None, read_default_group=None,
                 compress=None, named_pipe=None, no_delay=None,
                 autocommit=False, db=None, passwd=None, local_infile=False,
                 max_allowed_packet=16*1024*1024, defer_connect=False,
                 auth_plugin_map={}, read_timeout=None, write_timeout=None,
                 bind_address=None, binary_prefix=False)

2) 操作数据库
1> 数据库首先是需要建立一个游标的,来对数据库发送sql语句的
建立游标:

cur = conn.cursor()

2> 对数据库进行增删改查的操作
首先选择需要操作的数据库,这里选择westos作为操作对象

conn.select_db('westos')

这一项连接的时候是可以直接指定的

db="数据库名称"

在数据库westos中,建立一个表myuser

create_sql = 'create table myuser (name varchar(30), age int );'
cur.execute(create_sql)

在表中填入数据

insert_sqli1 = 'insert into myuser VALUES ("user1", 100);'
insert_sqli2 = 'insert into myuser VALUES ("user2", 100);'
cur.execute(insert_sqli1)
cur.execute(insert_sqli2)

删除表中的数据

delete_sqli = 'delete from myuser where name="user2";'
cur.execute(delete_sqli)

实现批量的增删改

users = [('user'+str(i), i) for i in range(100)]
insert_sqli = 'insert into myuser VALUES (%s, %s);'
cur.executemany(insert_sqli, users)

excutemany函数(命令,数组)可以实现批量操作
查看表中的内容

select_sqli = 'select * from myuser;'
res = cur.execute(select_sqli)
print("查看语句的返回结果:", res)

也可以逐条查看表中的内容

扫描二维码关注公众号,回复: 3083043 查看本文章
print(cur.fetchone())

cur.fetchone类似与文件的操作f.readline, 每次只读取一条记录
也可以查看多条的内容

print(cur.fetchmany(5))

cur.fetchmany, 类似于f.readlines, 返回的是一个元组
显示表的具体描述

desc = cur.description
print("表的描述:",desc )

从表的描述中获取表头

print("表头",[item[0] for item in desc])

当然数据库的查看是需要游标的帮助的
游标的移动,分为(absolute和relative)两种

cur.scroll(0, mode='absolute')

移动游标的位置, 到记录的最开始(绝对移动)

cur.scroll(-10, mode='relative')

移动游标的位置,到当前记录的前10位(相对移动)
最后需要对数据库的操作进行提交

conn.commit()

当然这个也是在你连接的时候就可以解决了autocommit=False,系统默认是关闭的,当

autocommit=True

就可以自动提交了

3) 关闭数据库
但是关闭数据库之前,需要先关掉游标,再去关掉数据库

cur.close()
conn.close()

这就是一系列对数据库的操作流程
二 银行转账操作
要求用数据库实现A给B转账之后,A拥有的金额减小,B拥有的金额增加,若出现意外,转账作废

import pymysql


class TransferMoney(object):
    def __init__(self, conn):
        self.conn = conn
        self.cursor = conn.cursor()

    def transfer(self, source_accid, target_accid, money):
        """
        转账方法:
            # 1. source_accid帐号是否存在;
            # 2. target_accid帐号是否存在;
            # 3. 是否有足够的钱
            # 4. source_accid扣钱
            # 5. target_acci加钱
            # 6. 提交对数据库的操作
        :param source_accid: 源帐号id
        :param target_accid: 目标帐号id
        :param money: 转账金额
        :return: bool
        """
        # 判断帐号是否存在
        self.check_account_avaiable(source_accid)
        self.check_account_avaiable(target_accid)

        # 是否有足够的钱
        self.has_enough_money(source_accid, money)

        try:
            # source_accid扣钱
            self.reduce_money(source_accid, money)
            #  print(a)
            #  target_acci加钱
            self.add_money(target_accid, money)
            self.conn.commit()
        except Exception as e:
            # 撤销对于数据库的更改操作, 回滚
            self.conn.rollback()
        else:
            print("%s给%s转账%s成功" % (source_accid, target_accid, money))

    def check_account_avaiable(self, accid):
        """判断帐号是否存在, 传递参数为帐号id"""
        select_sqli = 'select * from bankData where id=%s' % (accid)
        print("execute sql:", select_sqli)
        res = self.cursor.execute(select_sqli)
        # 判断是否能找到帐号为accid的记录;
        if res == 1:
            return True
        else:
            raise Exception("帐号%s不存在" % (accid))

    def has_enough_money(self, accid, money):
        """是否有足够的钱"""
        select_sqli = 'select money from bankData where id=%s' % (accid)
        print('execute sql:', select_sqli)
        self.cursor.execute(select_sqli)

        # 获取查询到的金钱数额
        acc_money = self.cursor.fetchone()[0]
        print(acc_money, type(acc_money))

        # 判断
        if acc_money >= money:
            return True
        else:
            raise Exception("账户%s没有足够的金额, 当前余额为%s" % (accid, acc_money))

    def reduce_money(self, accid, money):
        # 对于accid减少的金额为money
        try:
            update_sqli = 'update bankData set money=money-%s where id="%s"' % (money, accid)
            print("redcue_money sql:", update_sqli)
            self.cursor.execute(update_sqli)
        except Exception as e:
            print('Error:', e)

    def add_money(self, accid, money):
        # 对于accid减少的金额为money
        try:
            update_sqli = 'update bankData set money=money+%s where id="%s"' % (money, accid)
            print("add_money sql:", update_sqli)
            self.cursor.execute(update_sqli)
        except Exception as e:
            print('Error:', e)

    def __del__(self):
        # 当删除对象时, 自动执行, 关闭游标;
        self.cursor.close()


if __name__ == '__main__':
    conn = pymysql.connect(host='192.168.122.170', user='hello',
                           password='hello', charset='utf8',
                           db='westos')

    trans = TransferMoney(conn)
    trans.transfer('610003', '610002', 100)

这里写图片描述
这里写图片描述
三 成绩管理
文件score.dat中保存的是100名学生的姓名和Python课、高数和英语成绩。
1)定义学生类,其中包含姓名、Python课、高数和英语成绩及总分、均分数据成员,成员函数根据需要确定。
2)读入这名学生的成绩,用对象列表进行存储。
3)求出各科和总分的最高分。
4)请按总分的降序(高成绩在前,低成绩在后)排序
5)在屏幕上显示各科及总分的最高分,排序后的成绩单(包括总分)保存到文件odered_score.dat中。
6) 将文件中的所有学生信息, 保存在mariadb数据库中

import random
import pymysql
from itertools import chain

#生成100名学生的成绩
def createdata():
    with open('score.dat', 'w') as f:
        for i in range(1,101):
            name = 'student' + str(i)
            python_score = random.randint(60, 100)
            math_score = random.randint(60, 100)
            english_score = random.randint(60, 100)
            f.write(name + '\t' + str(python_score) + '\t' + str(math_score) + '\t' + str(english_score) + '\n')

#建立Student类
class student(object):
    def __init__(self, name, python_score, math_score, english_score):
        self.name = name
        self.python_score = python_score
        self.math_score = math_score
        self.english_score = english_score
        self.sumscore = float(python_score) + float(math_score) + float(english_score)
        self.averagescore = self.sumscore / 3

    def __repr__(self):
        return '姓名:%s python分数:%s 高数分数:%s 英语分数:%s 总分:%s 平均分:%.2f' % (
            self.name, self.python_score, self.math_score, self.english_score, self.sumscore, self.averagescore)


def main():
    createdata()
    #读取 score.dat 文件中的学生成绩,并使用对象列表存储
    with open('score.dat') as f:
        studentlist = [student(*line.split()) for line in f.readlines()]
    #输出各科成绩最高分
    print('python最高分:%s' % max(studentlist, key=lambda x: x.python_score).python_score)
    print('高数最高分:%s' % max(studentlist, key=lambda x: x.math_score).math_score)
    print('英语最高分:%s' % max(studentlist, key=lambda x: x.english_score).english_score)
    #对总成绩进行排序,并输出最高分,将排序后的成绩写入文件 odered_score.dat
    sumscorelist = sorted(studentlist, key=lambda x: x.sumscore, reverse=True)
    print('总分最高:%s' % sumscorelist[0].sumscore)
    with open('odered_score.dat', mode='w') as f:
        for i in sumscorelist:
            print(i)
            f.write(str(i) + '\n')
    #读取 odered_score.dat 文件, 并将数据写入数据库
    with open('odered_score.dat') as f:
        conn = pymysql.connect(host='172.25.254.69',user='hello', password='hello', charset='utf8', db='mariadb', autocommit=True)
        cur = conn.cursor()
        #cur.execute('drop table student;')
        newcreate = 'create table student(姓名 varchar(10) not null, python成绩 varchar(5), 高数成绩 varchar(5), 英语成绩 varchar(5), 总分 varchar(5), 平均分 varchar(5));'
        cur.execute(newcreate)
        for line in f.readlines():
            getuseful = [i.split(':') for i in line.split()]
            useful = list(chain(*getuseful))[1::2]
            linkuse = "insert into student values('%s', '%s', '%s', '%s', '%s', '%s');" % (
                useful[0], useful[1], useful[2], useful[3], useful[4], useful[5])
            #print(linkuse)
            cur.execute(linkuse)
        cur.close()
        conn.close()


main()

这里写图片描述
输出显示各科的最高分和总分的最高分
这里写图片描述
按照总分的高低,从大到小依次排序
这里写图片描述
数据库中存储的内容和显示的总分排序是相同的

猜你喜欢

转载自blog.csdn.net/weixin_42668123/article/details/82429295
今日推荐