准备:今天拿笔记本装了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. 深入理解java虚拟机学习笔记(一)

    第二章 Java内存区域与内存溢出异常 运行时数据区域 程序计数器(Program Counter Register) 程序计数器:当前线程所执行的字节码行号指示器.各条线程之间计数器互不影响,独立存 ...

  2. 在Arch上安装VSCode的方法

    首先去特硬去下载vscode的安装包 mkdir /tmp/vscode cd /tmp/vscode/ wget https://az764295.vo.msecnd.net/public/0.3. ...

  3. 统计学习五:3.决策树的学习之CART算法

    全文引用自<统计学习方法>(李航) 分类与回归树(classification and regression tree, CART)模型是由Breiman等人于1984年提出的另一类决策树 ...

  4. sql随机数

    ) as P_jsnews_id ) as P_jsnews_id) * from P_jsnews order by newid()

  5. java一些面试题

    java虚拟机 什么时候会触发full gc System.gc()方法的调用 老年代空间不足 永生区空间不足(JVM规范中运行时数据区域中的方法区,在HotSpot虚拟机中又被习惯称为永生代或者永生 ...

  6. 软工2017第六周团队协作——个人PSP

    10.20 --10.26本周例行报告 1.PSP(personal software process )个人软件过程. 类型 任务 开始时间                结束时间 中断时间 实际用 ...

  7. Java学习个人备忘录之继承

    继承的好处1. 提高了代码的复用性.2. 让类与类之间产生了关系,给第三个特征多态提供了前提. java中支持单继承,不直接支持多继承,但对C++中的多继承机制进行改良.java支持多层继承. C继承 ...

  8. c# 委托初窥

    1.委托可以把方法当作参数在另一个方法中传递和调用 ,委托是方法的快捷方式. 2.委托是一个类. private void BeginSocketThread() { try { IPEndPoint ...

  9. DAY6敏捷冲刺

    站立式会议 工作安排 (1)服务器配置 服务器端项目结构调整 (2)数据库配置 单词学习记录+用户信息 (3)客户端 客户端项目结构调整,代码功能分离 燃尽图 燃尽图有误,已重新修改,先贴卡片的界面, ...

  10. 解决连接mysql报错1130

    最近在服务器上部署好的应用突然间连接不上mysql数据库,报错“ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this M ...