为什么不用sqlite3 新建一个项目默认使用的是sqlite3。可从setting.py里看到,DATABASES定义使用的数据库。
sqlite3的数据库使用简单,配合django.db的models方法也是美滋滋,本身是嵌入式关系型数据库,比较轻便,熟悉安卓测试同学可能会发现,在一些app安装目录下有 sqlite数据库文件,用以存储该应用的一些本地信息。该数据库没有用户名密码,也不好远程连接(我没试过),这也限制了他的使用场景。
再加上按照 django的模式,是先定义model,它帮你做好映射关系,然后执行makemigrations生成sql脚本再执行migrate执行脚本对数据库做操作。总体来讲不安全,风险较大,且按照目前项目组规则,都是通过SQL语句做变更,也便于做权限控制,每一次变动也都能追溯到提交人,而不必每次都要去改代码。
安装Mysql-Server 安装 为了方便本地开发,可以在本地安装mysql-server。
在https://dev.mysql.com/downloads/mysql/ 下载安装包,通常下载社区版(Community)就好
配置 下载后安装,然后配置Path环境变量。
以win10为例,假设安装路径是 D:\Program Files\MySQL\bin
然后新增配置文件 D:\Program Files\MySQL\my.ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [mysql ] default-character-set = utf8mb4 [mysqld ] port = 3306 default_authentication_plugin=mysql_native_password basedir = "D:\Program Files\MySQL" datadir = "D:\Program Files\MySQL\data" max_connections = 200 character-set-server = utf8 default-storage-engine =INNODB
初始化数据库,打开cmd执行下面命令
1 2 mysqld --initialize --console
安装mysql服务并启动
1 2 3 4 5 mysqld --install net start mysql
更改root密码
1 2 3 4 5 mysql -u root -p ALTER USER 'root' @'localhost' IDENTIFIED WITH mysql_native_password BY 'admin';
服务指令
| 启动MySQL服务 | net start mysql |
| — | — |
| 停止MySQL服务 | net stop mysql |
| 卸载MySQL服务 | sc delete MySQL/mysqld -remove |
mysql命令行操作
| 创建新用户 | CREATE USER ‘用户名‘@’%’ IDENTIFIED BY ‘密码’; |
| — | — |
| 用户授权 | GRANT ALL PRIVILEGES ON . TO ‘用户名‘@’%’; |
(用户授权,可以限制用户操作权限是表一级别还是库级别,也可限制用户远程登陆,这里不展开讲。)
创建第一个数据库 也可以通过navicat连接后在界面创建
启动服务后,使用命令行登陆
1 CREATE DATABASE database_name DEFAULT CHARACTER SET utf8mbp4 COLLATE utf8mbp4_bin;
character设置字符集格式 collate设置排序规则,会影响排序和比较 国内使用通常分别设置为utf8mbp4和utf8mbp4_bin
模块选择 操作Mysql, django推荐的是使用MySQLdb,但我个人认为这个模块有毒,我个人推荐使用pymysql,简单好用。
首先,开头说了 setting了定义了数据库类型,这边修改下配置。
1 2 3 4 5 6 7 8 9 10 DATABASES = { 'default' : { 'ENGINE' : 'django.db.backends.mysql' , 'NAME' : 'myblog' , 'USER' : 'root' , 'PASSWORD' : '' , 'HOST' : '127.0.0.1' , 'PORT' : '3306' , } }
现在到了选择模块的时候了,分别说下两种情况。
使用pymysql 使用pymysql比较简单,首先pip安装下(安装完记得cmd中输入python,然后import pymysql看看是否成功)
安装好了之后,由于 Django默认用MySQLdb,需要引入到项目里去。
在项目目录下的init .py文件中写(跟setting.py在同一层)
1 2 import pymysqlpymysql.install_as_MySQLdb()
这样就算是配置完成了。
使用MySQLdb (PS: 以下是windows平台安装方法,如果是linux或者osx,自求多福吧,不能只让我一个人蛋疼…..)
先下载安装下mysql-connector
https://dev.mysql.com/downloads/connector/python/
下载windows平台下第一个安装好。
手动安装MySQL-python
https://pypi.org/project/MySQL-python/](https://pypi.org/project/MySQL-python/)
下载最新版本
解压,然后进入解压后的目录
安装完成后记得打开cmd, import MySQLdb试试有没有报错。
Mysql使用 生成auth模块依赖表 如要使用auth模块,得先生成相关的表。由于模块已经写好了语句,直接执行migrate即可。(如果是要将你自定义的model在mysql生成,得先执行makemigrations)
1 python manage.py migrate
可以看到结果
再去看数据库
可以看到表均已生成,接下来照常使用即可。
后续若有新增表或更改表结构的方式,通过执行SQL语句来完成,就不要在创建和修改model了。
在代码中使用 虽然前面说了两个模块,不过这都跟你在代码里使用无关,只是因为如果你有model需要生成table,涉及到移植或者要使用auth模块的,那么第三步准备工作你是必须要做好的。
如果仅仅是代码里使用,就随你了,也有其他模块可以使用,这里说说pymysql。
例如查询和增删改操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 import pymysqlclass OperateMysql : def __init__ (self, conf ): self .conn = self .create_conn(conf) def create_conn (self, section ): try : conn = pymysql.connect(section['host' ], section['username' ], section['password' ], section['database' ]) except Exception as e: raise Exception("Connect Error %d: %s" % (e.args[0 ], e.args[1 ])) return conn def choose_database_info (self, env ): if env == 'test' : key = 'testEnv' elif env == 'trail' : key = 'trailEnv' elif env == 'prod' : key = 'prodEnv' else : raise 'No this environment as %s' % env getconfig = GetConfig('database.ini' ) section = getconfig.getsection(key) return section def close (self, cur, conn ): cur.close() conn.close() """查找语句""" def select (self, sql ): sql = str (sql) cur = self .conn.cursor() try : cur.execute(sql) results = cur.fetchall() except Exception as e: self .close(cur, self .conn) raise Exception("Mysql Error %d: %s" % (e.args[0 ], e.args[1 ])) self .close(cur, self .conn) return results """增删改都是调用excute写在一个里面""" def modifiy (self, sql ): sql = str (sql) cur = self .conn.cursor() try : cur.execute(sql) self .conn.commit() except Exception as e: self .conn.rollback() self .conn.commit() self .close(cur, self .conn) raise Exception("Mysql Error %d: %s" % (e.args[0 ], e.args[1 ])) self .close(cur, self .conn) if __name__ == '__main__' : conf = {"host" : "" , "port" : "" , "username" : "" , "password" : "" , "database" : "" } OP = OperateMysql(conf) res = OP.select('SELECT * from ts_storage_partinfo_order_batch LIMIT 1' ) print (res)
使用线程池 在上面的基础上,我们使用线程池,作用是为了让线程吃来统一管理线程数,把一些失效或超时线程关闭,节约线程数的使用,释放资源。
安装DBUtils
使用PooledDB管理pymysql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 import pymysqlfrom DBUtils.PooledDB import PooledDBclass OperateSqlite : def __init__ (self, conf ): self .pool = PooledDB(pymysql, maxcached=50 , maxconnections=1000 , maxusage=1000 , **conf) def select (self, sql, dict_mark=False ): result = [] conn = self .pool.connection() cur = conn.cursor() try : if dict_mark: cur.execute(sql) fields = [desc[0 ] for desc in cur.description] rst = cur.fetchall() if rst: result = [dict (zip (fields, row)) for row in rst] else : cur.execute(sql) result = cur.fetchall() except Exception as e: raise Exception("Mysql Error %d: %s" % (e.args[0 ], e.args[1 ])) finally : cur.close() conn.close() return result def excute (self, sql ): result = [] conn = self .pool.connection() cur = conn.cursor() try : cur.execute(sql) result = cur.row_factory() except Exception as e: raise Exception("Mysql Error %d: %s" % (e.args[0 ], e.args[1 ])) finally : cur.close() conn.close() return result conf = {"host" : "127.0.0.1" , "port" : "3306" , "user" : "root" , "passwd" : "" , "db" : "" } op = OperateSqlite(conf) if __name__ == "__main__" : sql = "select * from table limit 1" res = op.select(sql) print (res)
PooledDB的参数:
mincached,最少的空闲连接数,如果空闲连接数小于这个数, pool会创建一个新的连接 maxcached,最大的空闲连接数,如果空闲连接数大于这个数,pool会关闭空闲连接maxconnections,最大连接数 blocking,当连接数达到最大的连接数时,在请求连接的时候,如果这个值是True,请求连接的程序会一直等待,直到当前连接数小于最大连接数,如果这个值是False,会报错。 maxshared 当连接数达到这个数,新请求的连接会分享已经分配出去的连接
使用ORM 上面操作数据库都是执行的sql,这样语句多了以后,是不太好管理的,且存在被sql注入的风险,sql和代码在一个py文件中,修改sql有误也不大能看出错误,综上引入 orm的概念,把数据库的表结构映射为代码可以识别的对象,像写代码一样来操作数据库。 首先按照setting.py配置好要连接的mysql数据库,执行
1 python manage.py inspectdb
将会打印即将要生成的类文件
简单检查下,若全都无误,再写入到models.py文件去。
1 python manage.py inspectdb > models.py
后续的使用就跟初学django教导的操作model一样,想注册到admin也可以注册。