关键词介绍

  • 什么是mysql
    • MySQL是一种开放源代码的关系型数据库管理系统。MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,属于Oracle旗下产品。MySQL使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理.
  • 什么是SQL
    • SQL是用来操作数据库的语言.
  • 为什么要用SQL
    • SQL基本上所有用到的数据库都可以用它来进行操作,是最基础的语言
  • 什么是PEEWEE
    • peewee是python中的一个库,可以使用它代替SQL对数据库进行增删查改等操作.
    • 同时他的性质属于ORM(对象关系映射).可以使用它操作不同类型的数据库.
  • 为什么要用peewee
    • 基于python开发的,使用流畅.
    • sql语句的执行效率问题:应用开发程序员需要耗费一大部分精力去优化sql语句.
    • 各数据库的语言可能不通用,如果项目需要切换数据库则变得难以维护,使用peewee可以解决这些问题.

引言

之前用python去操作mysql数据库的时候,是直接拼sql语句,然后执行,再获取返回结果.整个流程没啥毛病,但是就是麻烦,本来python就不是我主要用的语言,还得去学一个SQL.而且因为是手写SQL,所以也没有一些语法检查或者其他辅助措施,写的SQL有问题的话也只有在实际运行时才会报错.然后我得再根据报错信息去查问题.很麻烦.后来知道了peewee,大概研究了一下,感觉peewee就是把操作数据库时写SQL语句变为python语句.这样来说整个程序就会简单一些.

开始使用peewee

首先,我这边的情况是,数据库已经定义好了,甚至用sql的python程序已经开始动工了,现在要转到peewee.另外,因为peewee操作mysql的时候是根据数据模型来的(简单理解就是你需要在python中根据peewee的要求定义一个class来描述你数据库的结构以及一些字段名称啥的).因为我们数据库已经建好,所以可以利用peewee提供的工具来自动生成这个数据模型的python代码.

方法如下:

1.首先,基础的库,是要装的: pip install peewee mysqlclient

2.然后执行这个命令:

python -m pwiz -e mysql -H localhost -p 3306 -u root -P  -t table_names database_name > model.py

参数解释:

其中database_name是要导出的数据库名.

选项解释举例
-hhelp 显示帮助-h
-eengine 数据库引擎-e mysql
-Hhost 数据库地址-H localhost
-pport 数据库端口-p 3306
-uuser 数据库用户名-u root
-Ppassword 数据库密码-P
-sschema 模式-s public
-ttables 指定生成来自表格-t tweet,users,relationships
-vVIEWs 指定生成来自视图-v
-iinfo 添加原信息-i
-oorder 保留表格列顺序-o

engine支持的数据库:
sqlite
mysql
postgresql

举个例子:然后在这个命令执行的目录下就会生成aac_iot_model.py文件,打开这个py.内容是这样的.

from peewee import *

database = MySQLDatabase('aac_iot', **{'charset': 'utf8', 'sql_mode': 'PIPES_AS_CONCAT', 'use_unicode': True, 'host': '********.com', 'port': 3306, 'user': 'root', 'password': '*******'})

class UnknownField(object):
    def __init__(self, *_, **__): pass

class BaseModel(Model):
    class Meta:
        database = database

class Device(BaseModel):
    id = AutoField(column_name='Id')
    device_type = IntegerField(constraints=[SQL("DEFAULT 0")])
    firmware_version = CharField(null=True)
    heartbeat_time = DateTimeField(null=True)
    mac = CharField(constraints=[SQL("DEFAULT ''")])
    name = TextField(null=True)

    class Meta:
        table_name = 'device'

class Firmware(BaseModel):
    cos_path = TextField(column_name='CosPath', null=True)
    firmware_description = TextField(column_name='FirmwareDescription', null=True)
    firmware_type = TextField(column_name='FirmwareType', null=True)
    firmware_update_date = DateTimeField(column_name='FirmwareUpdateDate', null=True)
    firmware_version = TextField(column_name='FirmwareVersion', null=True)
    id = AutoField(column_name='Id')
    path = TextField(column_name='Path', null=True)
    project_code = TextField(column_name='ProjectCode', null=True)

    class Meta:
        table_name = 'firmware'

class Project(BaseModel):
    device_icon_url = TextField(column_name='DeviceIconUrl', null=True)
    device_type = IntegerField(column_name='DeviceType', constraints=[SQL("DEFAULT 0")])
    id = AutoField(column_name='Id')
    project_code = TextField(column_name='ProjectCode', null=True)
    project_name = TextField(column_name='ProjectName', null=True)
    project_state = TextField(column_name='ProjectState', null=True)
    project_type = TextField(column_name='ProjectType', null=True)

    class Meta:
        table_name = 'project'

再对照数据库的结构:

可以看到,这个py文件就是对数据库结构的描述.然后我这边因为把连接数据库的部分另外摘出来了.所以对这个py文件做了些修改,变成了这样:


from peewee import *
from mysql import mysql_interface


class UnknownField(object):
    def __init__(self, *_, **__): pass


class Device(Model):
    id = AutoField(column_name='Id')
    device_type = IntegerField(constraints=[SQL("DEFAULT 0")])
    firmware_version = CharField(null=True)
    heartbeat_time = DateTimeField(null=True)
    mac = CharField(constraints=[SQL("DEFAULT ''")])
    name = TextField(null=True)

    class Meta:
        table_name = 'device'

class Firmware(Model):
    cos_path = TextField(column_name='CosPath', null=True)
    firmware_description = TextField(column_name='FirmwareDescription', null=True)
    firmware_type = TextField(column_name='FirmwareType', null=True)
    firmware_update_date = DateTimeField(column_name='FirmwareUpdateDate', null=True)
    firmware_version = TextField(column_name='FirmwareVersion', null=True)
    id = AutoField(column_name='Id')
    path = TextField(column_name='Path', null=True)
    project_code = TextField(column_name='ProjectCode', null=True)

    class Meta:
        table_name = 'firmware'

class Project(Model):
    device_icon_url = TextField(column_name='DeviceIconUrl', null=True)
    device_type = IntegerField(column_name='DeviceType', constraints=[SQL("DEFAULT 0")])
    id = AutoField(column_name='Id')
    project_code = TextField(column_name='ProjectCode', null=True)
    project_name = TextField(column_name='ProjectName', null=True)
    project_state = TextField(column_name='ProjectState', null=True)
    project_type = TextField(column_name='ProjectType', null=True)

    class Meta:
        table_name = 'project'


def bind_db():
    mysql_interface.get_mysql_aac_iot_db().bind([Device, Firmware, Project])

其中mysql_interface.get_mysql_aac_iot_db()的部分是这样的:

import MySQLdb
import pprint
from peewee import *
from IoTProject.AAC_IOT import aac_iot_mysql_interface

global mysql_aac_iot_db

global mysql_username
global mysql_password
global mysql_databasename

global mysql_ip

mysql_aac_iot_db = None

mysql_username = "**********"
mysql_password = "**********"
mysql_aac_iot_databasename = "aac_iot"

def connect(ip):
    global aac_iot_db_conn
    global mysql_ip

    mysql_ip = ip
    global mysql_aac_iot_db
    mysql_aac_iot_db = MySQLDatabase(mysql_aac_iot_databasename,
                                     **{'charset': 'utf8', 'sql_mode': 'PIPES_AS_CONCAT', 'use_unicode': True,
                                        'host': mysql_ip, 'user': mysql_username, 'password': mysql_password})

    # 绑定数据库
    aac_iot_mysql_interface.bind_db()
    return True


def get_mysql_aac_iot_db():
    global mysql_aac_iot_db
    return mysql_aac_iot_db

然后操作数据库的时候直接这样操作:


# 判断设备是否存在
def device_is_exist(mac):
    p = Device.get_or_none(Device.mac == mac)
    if p is not None:
        return True
    return False

# 删除设备
def del_device(mac):
    try:
        Device.delete().where(Device.mac == mac).execute()
        return True
    except Exception as e:
        # 发生错误
        print("remove_dev_info 发生错误")
        pprint.pprint(e)
    return False


# 更新设备的心跳包信息
def update_heartbeat_datapacket_info(mac, firmware_version="", heartbeat_time=None):
    try:
        p, created = Device.get_or_create(mac=mac)
        p.heartbeat_time = heartbeat_time
        p.firmware_version = firmware_version
        p.save()
        return True

    except Exception as e:
        # 发生错误
        print("update_heartbeat_datapacket_info 发生错误")
        pprint.pprint(e)

    return False


一个电子工程师的自我修养