准备:今天拿笔记本装了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/

最新文章

  1. CRM(客户关系管理)
  2. 《C专家编程》第四章——令人震惊的事实:数组和指针并不相同
  3. Opencl 并行求和
  4. 决战大数据之二:CentOS 7 最新JDK 8安装
  5. C#-ado.net-属性扩展
  6. 使用DotNetOpenAuth搭建OAuth2.0授权框架——Demo代码简单说明
  7. python_way day15 HTML-DAY2 HTML-DAY2、JS
  8. Java DES 加解密文件
  9. web app 相关记录
  10. VBS虚拟键码
  11. sql 多条记录插入
  12. windows下安装oracle11g测试是否成功与监听器问题和网页控制台登录
  13. MacBook上那些好用的工具们
  14. BurpSuiteProxy安装使用
  15. modelsim仿真正确FPGA运行不正确的可能原因 - cm4写寄存器错
  16. 如何解决win10关机状态下,按键盘会自动开机的问题
  17. 关于QTcreator出现不能包含头文件的解决
  18. Java高级面试题及答案
  19. bzoj1819 电子词典
  20. cocos2d-x发生undefined reference to `XX'异常 一劳永逸解决的方法

热门文章

  1. Unity制作人物头像小图标和小地图
  2. jQuery筛选器及对DOM修改(学习笔记)
  3. fizzbuzz Python很有意思的解法
  4. 【WXS全局对象】Date
  5. lintcode407 加一
  6. 【转】unity3d 在UGUI中制作自适应调整大小的滚动布局控件
  7. Ubuntu—终端下重启与关机
  8. 【机器学习】多项式回归python实现
  9. Python3 Tkinter-Scale
  10. zookeeper:一.zookeeper集群安装