准备:今天拿笔记本装了mysql,这样就能在不同地方用其他电脑远程访问同一个数据库了。

python安装MySQLdb模块:http://www.codegood.com/downloads

21.1 介绍

本章的主题是如何在大型项目中使用关系型数据库。本章对数据库知识和SQL语言不做介绍,本章从一个Python应用程序开始,了解在Python框架下,如何将数据保存到数据库,如何将数据从数据库中取出来。“在Python世界里,无需怀疑,与数据库协同工作已经几乎是所有应用程序的核心部分了。”作者原话。

所有Python接口程序都一定程度上遵守Python DB-API 规范。

21.2 Python数据库应用程序

什么是DB-API?DB-API是一个规范。它定义了一系列必须的对象和数据库存取方式,以便为各种各样的底层数据库系统和多种多样的数据库接口程序提供一致的访问接口。

下面是一个例子:

#-*- coding:utf-8 -*-

import MySQLdb as SQL

#首先需要与数据库连接
cxn = SQL.connect(host='192.168.1.105', #这里是自己数据库主机地址
user='xxx', #用户名
passwd='xxxx', #密码
db='JiaoYanShi', #所用数据库名称
port=3306, #mysql默认端口
charset='utf8') #编码方式
#连接好以后与数据库进行交互需要创建游标对象,一个游标允许用户执行数据库命令和得到查询结果。
cur = cxn.cursor()
#创建一个表
cur.execute('CREATE TABLE IF NOT EXISTS users(login VARCHAR(8),uid INT)')
#插入数据
cur.execute("INSERT INTO users VALUES('john',7000)")
cur.execute("INSERT INTO users VALUES('jane',7001)")
cur.execute("INSERT INTO users VALUES('bob',7200)")
#执行execute以后数据已经进入了数据库,但是如果没有下面的事务提交语句,已经进入的数据就会回滚,导致数据库中不会有数据
# python 操作mysql 是用 事物 的方式来实现的,所以必须有commit 提交的过程,否则数据表不会生效
#然而commit原理还没怎么懂…这样commit()不知道是否妥当,后续继续研究
cxn.commit()

#必须进行select以后才会有打印结果
cur.execute("SELECT * FROM users")
content = cur.fetchall()
for data in content:
print data
print '-'*50 #下面进行表的更新
cur.execute("UPDATE users SET uid = 7100 WHERE uid = 7001 ")
cxn.commit() cur.execute("SELECT * FROM users")
content = cur.fetchall()
for data in content:
print data
print '-'*50
 
#下面进行表数据删除
cur.execute("DELETE FROM users WHERE login = 'bob'")
cxn.commit() cur.execute("SELECT * FROM users")
content = cur.fetchall()
for data in content:
print data #关闭游标对象
cur.close()
#关闭连接
cxn.close() >>>
(u'john', 7000L)
(u'jane', 7001L)
(u'bob', 7200L)
--------------------------------------------------
(u'john', 7000L)
(u'jane', 7100L)
(u'bob', 7200L)
--------------------------------------------------
(u'john', 7000L)
(u'jane', 7100L)
[Finished in 0.3s]

下面的这个例子展示了数据库数据通讯的一般框架:

#-*- coding:utf-8 -*-

import os
from random import randrange as rrange COLSIZ = 10
RDBMSs = {'s': 'sqlite', 'm': 'mysql', 'g': 'gadfly'}
DB_EXC = None HOST='xxx.xxx.xxx.xxx' #这里是HOST地址
User='xxxx' #用户名
Passwd='xxxxxx' #密码
Port=3306 #mysql默认端口
Charset='utf8' #编码方式 #下面这个函数是选择数据库类型
def setup():
return RDBMSs[raw_input('''
Choose a database system: (M)ySQL
(G)adfly
(S)QLite Enter choice: ''').strip().lower()[0]] #下面是返回一个database.connect连接对象
def connect(db, dbName):
global DB_EXC
dbDir = '%s_%s' % (db, dbName) if db == 'sqlite':
try:
import sqlite3
except ImportError, e:
try:
from pysqlite2 import dbapi2 as sqlite3
except ImportError, e:
return None DB_EXC = sqlite3
if not os.path.isdir(dbDir):
os.mkdir(dbDir)
cxn = sqlite3.connect(os.path.join(dbDir, dbName)) elif db == 'mysql':
try:
import MySQLdb
#下面这个模块是专门用来进行数据库错误处理的
import _mysql_exceptions as DB_EXC
except ImportError, e:
return None
#下面的处理时用来创建数据库(如果不存在),可以作为一个标准处理流程
try:
cxn = MySQLdb.connect(host = HOST,
user = User,
passwd = Passwd,
db=dbName,
port = Port,
charset='utf8')
#连接不成功进行如下处理
except DB_EXC.OperationalError, e:
#先连接一下数据库地址,不写数据库名称
cxn = MySQLdb.connect(host = HOST,
user = User,
passwd = Passwd,
port = Port,
charset='utf8')
try:
cxn.query('DROP DATABASE %s' % dbName)
except DB_EXC.OperationalError, e:
pass
#创建数据库
cxn.query('CREATE DATABASE %s' % dbName)
cxn.commit()
cxn.close()
#连接上数据库
cxn = MySQLdb.connect(host = HOST,
user = User,
passwd = Passwd,
db = dbName,
port = Port,
charset='utf8') elif db == 'gadfly':
try:
from gadfly import gadfly
DB_EXC = gadfly
except ImportError, e:
return None try:
cxn = gadfly(dbName, dbDir)
except IOError, e:
cxn = gadfly()
if not os.path.isdir(dbDir):
os.mkdir(dbDir)
cxn.startup(dbName, dbDir)
else:
return None
return cxn drop = lambda cur: cur.execute('DROP TABLE users') def create(cur):
#创建新的表users
try:
cur.execute('''
CREATE TABLE users (
login VARCHAR(8),
uid INTEGER,
prid INTEGER)
''')
except DB_EXC.OperationalError, e:
drop(cur)
create(cur) #插入的数据
NAMES = (
('aaron', 8312), ('angela', 7603), ('dave', 7306),
('davina',7902), ('elliot', 7911), ('ernie', 7410),
('jess', 7912), ('jim', 7512), ('larry', 7311),
('leslie', 7808), ('melissa', 8602), ('pat', 7711),
('serena', 7003), ('stan', 7607), ('faye', 6812),
('amy', 7209),
) #下面是一个创建函数,当调用此函数时,得到一个生成器
def randName():
pick = list(NAMES)
while len(pick) > 0:
        yield pick.pop(rrange(len(pick)))

#下面的函数进行数据库中表users的写入操作
def insert(cur, db):
if db == 'sqlite':
cur.executemany("INSERT INTO users VALUES(?, ?, ?)",
[(who, uid, rrange(1,5)) for who, uid in randName()])
elif db == 'gadfly':
for who, uid in randName():
cur.execute("INSERT INTO users VALUES(?, ?, ?)",
(who, uid, rrange(1,5))) #下面将NAMES写进数据库
elif db == 'mysql':
cur.executemany("INSERT INTO users VALUES(%s, %s, %s)",
[(who, uid, rrange(1,5)) for who, uid in randName()]) #cur.rowcount用来记录最后一次execute影响的行数
getRC = lambda cur: cur.rowcount if hasattr(cur, 'rowcount') else -1 #下面执行数据更新
def update(cur):
fr = rrange(1,5)
to = rrange(1,5)
cur.execute(
"UPDATE users SET prid=%d WHERE prid=%d" % (to, fr))
return fr, to, getRC(cur) #随机删除一些行
def delete(cur):
rm = rrange(1,5)
cur.execute('DELETE FROM users WHERE prid=%d' % rm)
return rm, getRC(cur) def dbDump(cur):
cur.execute('SELECT * FROM users')
print '\n%s%s%s' % ('LOGIN'.ljust(COLSIZ),
'USERID'.ljust(COLSIZ), 'PROJ#'.ljust(COLSIZ))
for data in cur.fetchall():
print '%s%s%s' % tuple([str(s).title().ljust(COLSIZ) for s in data]) def main():
db = setup()
print '*** Connecting to %r database' % db
cxn = connect(db, 'test')
if not cxn:
print '\nERROR: %r not supported, exiting' % db
return
#游标对象
cur = cxn.cursor() print '\n*** Creating users table'
create(cur) print '\n*** Inserting names into table'
insert(cur, db)
dbDump(cur) print '\n*** Randomly moving folks',
fr, to, num = update(cur)
print 'from one group (%d) to another (%d)' % (fr, to)
print '\t(%d users moved)' % num
dbDump(cur) print '\n*** Randomly choosing group',
rm, num = delete(cur)
print '(%d) to delete' % rm
print '\t(%d users removed)' % num
dbDump(cur) print '\n*** Dropping users table'
drop(cur)
cur.close()
cxn.commit()
cxn.close() if __name__ == '__main__':
main()

上面的例子只是应用了MySQL数据库,其他两个没试验。

21.3 对象-关系管理器(ORM)

ORM即对象-映射关系(OBJECT/RELATION MAPPING),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。也就是将Python对象与SQL进行映射转换。

如果用ORM,那么需要尽量避免直接的SQL查询。数据库中的表被转换为Python类,它具有列属性和操作数据库的方法。

最知名的Python ORM模块是SQLAlchemy 和 SQLObject。书上说两者有着不同的设计哲学...

1、SQLAlchemy的接口在某种程度上更接近SQL。SQLAlchemy的抽象层‘相当完美’,并且在必须用SQL完成某些功能时,它提供了足够的灵活性。‘其实这两个ORM模块在设置及存取数据时使用的术语非常相似,代码长度也相似。’

这部分课本上的代码过时了。。

下面教程很好,谢谢了,http://blog.csdn.net/billvsme/article/details/46783491

官方文档:http://docs.sqlalchemy.org/en/rel_1_0/

《python核心编程》--读书笔记 第21章 数据库编程的更多相关文章

  1. 《Clojure编程》笔记 第2章 函数式编程

    目录 背景简述 第2章 函数式编程 背景简述 本人是一个自学一年Java的小菜鸡,理论上跟大多数新手的水平差不多,但我入职的新公司是要求转Clojure语言的.坊间传闻:通常情况下,最好是有一定Jav ...

  2. 《python核心编程》读书笔记--第18章 多线程编程

    18.1引言 在多线程(multithreaded,MT)出现之前,电脑程序的运行由一个执行序列组成.多线程对某些任务来说是最理想的.这些任务有以下特点:它们本质上就是异步的,需要多个并发事务,各个事 ...

  3. 《python核心编程》读书笔记--第16章 网络编程

    在进行网络编程之前,先对网络以及互联网协议做一个了解. 推荐阮一峰的博客:(感谢) http://www.ruanyifeng.com/blog/2012/05/internet_protocol_s ...

  4. Java编程思想读书笔记--第21章并发

    1.基本的线程机制 定义任务 public class LiftOff implements Runnable{ protected int countDown = 10; private stati ...

  5. WCF服务编程 读书笔记——第2章 服务契约

    操作重载诸如 C++ 和 C# 等编程语言都支持方法重载,即允许具有相同名称的两个方法可以定义不同的参数.例如,如下的 C# 接口就是有效的定义: interface ICalculator { in ...

  6. WCF服务编程 读书笔记——第1章 WCF基础(2)

    续:第1章 WCF基础(1) 元数据交换 服务有两种方案可以发布自己的元数据.一种是基于HTTP-GET协议提供元数据, 另一种则是后面将要讨论的使用专门的终结点的方式.WCF能够为服务自动提供基于H ...

  7. WCF服务编程 读书笔记——第1章 WCF基础(1)

    第1章 WCF基础 本章主要介绍WCF的基本概念.构建模块以及WCF体系架构,以指导读者构建一个简单的WCF服务.从本章的内容中,我们可以了解到WCF的基本术语,包括地址(Address).绑定(Bi ...

  8. TIJ读书笔记-第21章-并发

    一本Think in java,从去年6月份开始读,读了快一年了,也快读完了,然而回头想想,却好像什么也不记得了,好记性不如烂笔头,那就从现在开始记录一下吧.由于现在在读的是并发,那就先从这章开始吧. ...

  9. #《Essential C++》读书笔记# 第五章 面向对象编程风格

    基础知识 继承机制定义了父子(parent/child)关系.父类(parent)定义了所有子类(children)共通的共有接口(public interface)和私有实现(private imp ...

随机推荐

  1. Python常用函数--文档字符串DocStrings

    Python 有一个甚是优美的功能称作python文档字符串(Documentation Strings),在称呼它时通常会使用另一个短一些的名字docstrings.DocStrings 是一款你应 ...

  2. MarkDown编辑器使用

    有几款好用的MarkDown编辑器,参考: https://blog.csdn.net/bat67/article/details/72804251 我就下载的是 MarkDown 2来使用. 现用现 ...

  3. 基于Hadoop2.5.0的集群搭建

    http://download.csdn.net/download/yameing/8011891 一. 规划 1.  准备安装包 JDK:http://download.oracle.com/otn ...

  4. [c++] Getting Started - CMake

    CMake is an open-source cross platform build system, according to CMake's creator, Kitware. But CMak ...

  5. POJ 3845 Fractal(计算几何の旋转缩放)

    Description Fractals are really cool mathematical objects. They have a lot of interesting properties ...

  6. 自测之Lesson7:设备文件操作

    题目:请编写一个输入密码(不回显)的程序,要求通过设置终端来完成. 完成代码: #include <stdio.h> #include <unistd.h> #include ...

  7. lintcode-34-N皇后问题 II

    34-N皇后问题 II 根据n皇后问题,现在返回n皇后不同的解决方案的数量而不是具体的放置布局. 样例 比如n=4,存在2种解决方案 标签 递归 思路 参考http://www.cnblogs.com ...

  8. PAT 1035 插入与归并

    https://pintia.cn/problem-sets/994805260223102976/problems/994805286714327040 据维基百科的定义: 插入排序是迭代算法,逐一 ...

  9. 原生javascript自定义input[type=checkbox]效果

    2018年6月27日  更新 能用css3,就不用js 用纯css3实现样式重写 <!DOCTYPE html> <html lang="en"> < ...

  10. svmtrain输入参数介绍【转】

    -s svm类型:SVM设置类型(默认0) 0 -- C-SVC 1 --v-SVC 2 – 一类SVM 3 -- e -SVR 4 -- v-SVR -t 核函数类型:核函数设置类型(默认2) 0 ...