QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6262|回复: 0
打印 上一主题 下一主题

pyodbc的简单使用

[复制链接]
字体大小: 正常 放大

102

主题

5

听众

913

积分

升级  78.25%

  • TA的每日心情
    开心
    2013-4-28 12:11
  • 签到天数: 160 天

    [LV.7]常住居民III

    群组: 数学软件学习

    跳转到指定楼层
    1#
    发表于 2012-7-4 14:30 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    1、连接数据库
    " s3 j/ a. ~' Y. o, i! N- @- m4 D
    ; W/ x8 e# z+ a, s) C* J) ^1)直接连接数据库和创建一个游标(cursor)" z! c  L$ R: [4 y
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    ! Q( p. f$ s- |, s# J/ A2        cursor = cnxn.cursor()1 u$ ], d9 E( `2 S

    * P% `- G% z! x) O9 s$ E% [2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    0 n  Z5 {+ F/ B/ L1        cnxn = pyodbc.connect('DSN=testWD=password')7 \; g# S1 z( W: e5 A
    2        cursor = cnxn.cursor()# e7 x- v- R; u7 F. G7 v& O
    ! o) P! B' Z+ N6 w$ h. d0 _0 C* |( Z
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节, N% v" S0 a; x* L* x
    5 c+ @' M: t; M" ^  m0 }& U( ]" j
    2、数据查询(SQL语句为 select ...from..where)
    # D5 G% d2 [' o8 l+ X* T+ k0 L( y2 ^# e! L$ u' K4 Y4 y
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    - P+ I2 c. c. h3 C: U+ x1        cursor.execute("select user_id, user_name from users")
    . k& X) i' t3 e) m! r" d& d) u$ o9 k2        row = cursor.fetchone()
    ' m. A) h3 Z; n/ D/ O3 B3        if row:
    1 P  _/ N' r+ E$ T' a4            print row/ V: P  z- o9 d! `. D
    2 t: }5 Z0 Z" H7 ]* U7 g0 X
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。# @7 r& W" x4 P* e; s
    1        cursor.execute("select user_id, user_name from users")
    1 `7 T* P0 k' f# P2        row = cursor.fetchone()/ ]3 ~; i8 I3 B
    3        print 'name:', row[1]          # access by column index
    - o& r* z$ x& c% ^. i) F4        print 'name:', row.user_name   # or access by name7 H+ V" @  m0 M" w% T( E

    2 S9 y  @( Q! p  R/ f: U9 h3)如果所有的行都被检索完,那么fetchone将返回None.+ @. Z4 T. _9 }- }+ E9 B
    1        while 1:  [! I8 u* L+ r. O
    2            row = cursor.fetchone()
    + u) k' X8 x* @+ I8 a# Z3 @# q- x3            if not row:
    2 c' S' g/ e  M2 ]4                break% u5 i; K0 M; c
    5            print 'id:', row.user_id
    + @) M3 x7 g) N6 o% a6 S* J- Q3 F( P  s/ @( }' @
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)9 j5 e3 P# n; G& L; e
    1        cursor.execute("select user_id, user_name from users")
      i; }! `, m% U* ?( p2        rows = cursor.fetchall()
    + f8 @+ A; j5 x. _  u3        for row in rows:
    + m4 _( f" N( K! y+ e; e4            print row.user_id, row.user_name
    ( u7 V+ c2 H9 ~6 Q/ o, d
    : ~9 j' F$ @/ L$ z$ T5)如果你打算一次读完所有数据,那么你可以使用cursor本身。
    / t2 G$ T% I5 [- b1 O9 A1        cursor.execute("select user_id, user_name from users"):
    : S$ ~) C0 V3 f# d2        for row in cursor:
    1 M9 J5 o0 w- l0 y3            print row.user_id, row.user_name
    0 h" `" ~; U, d* w$ ?. o+ v+ s' R! @# |- @4 r
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    - c! o. G0 {4 P# I8 p. D: b$ R1        for row in cursor.execute("select user_id, user_name from users"):- f) {3 q1 |- I3 Z& R+ W
    2            print row.user_id, row.user_name# `9 g; ?: }. S; Q! s0 L

    ; v( C7 p2 S0 ^  X/ W7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:
    0 @/ r8 y7 n  s8 E: k* T4 \- p: @1        cursor.execute(""") A, T$ L& F9 Z, Z) ?6 K4 k2 I
    2                       select user_id, user_name) t5 G- M& {  i( n2 ^: |
    3                         from users
    ' \5 m0 a7 Y/ [2 s( P  L3 b9 ]4                        where last_logon < '2001-01-01'
    4 T5 D# V. N8 u" J, ]# m) I6 N" R  d, Z5                          and bill_overdue = 'y'
    # b% ]" t$ @. a5 V0 V: i6                       """)
    : v- W1 _' \6 g- g. _  Q; ?8 t- Q2 D# d/ m( }( e' i/ t5 I5 J
    3、参数
    + L- d- `# o2 n
    ; ]) y* X- b7 k) x4 w# u! D, \1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    ' Z# ^2 [! J9 M1        cursor.execute("""" B. }0 }- H* B% }5 [3 Q' x
    2                       select user_id, user_name& r7 \* n; W2 s$ y4 `+ |/ G
    3                         from users- L8 o( R" [8 a% g7 J  s
    4                        where last_logon < ?
    1 F9 I# x, W/ u& ^0 V- A9 L8 z5                          and bill_overdue = ?
    - C5 a  F6 V4 b  D' ]6                       """, '2001-01-01', 'y')
    # z7 y, O' e$ Z0 U% g% C& g1 a
    # r& l2 R: k5 V2 B" W& y0 D这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。. m1 G, E& X3 h
    / d% C- R" _: L+ O
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    2 o) H4 ]3 w% M5 u  e1        cursor.execute("""; j  R6 s" P& u" U
    2                       select user_id, user_name, [* E+ k9 g( W; k; [' `
    3                         from users# x- \5 N. h, |& y( N$ M( q
    4                        where last_logon < ?
    * o, M0 ^5 T7 X- v' g. H9 `- g5                          and bill_overdue = ?' l* s# Z9 }; S5 G8 @, ]
    6                       """, ['2001-01-01', 'y']), e! `# f3 t! f, J/ L

    , F7 N- j5 o: D  e( \1        cursor.execute("select count(*) as user_count from users where age > ?", 21)# P1 z# n6 |6 [7 E
    2        row = cursor.fetchone()! a" B9 H+ u9 h4 a# {: T; ~
    3        print '%d users' % row.user_count
    : {, E5 t/ N+ v% t+ D0 e1 I; @8 S6 J3 |9 @- D* [; o
    ( w2 e( t; K1 @6 T. T/ t

    / L& W- U) B* g9 h4、数据插入
    ) {. e* E3 |3 P+ N; u
    ) \& U& Z1 m8 E! \* T7 \1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。- k8 H! u  j8 Y( s; o# X3 N
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    ' N* x. g( C$ Q2        cnxn.commit()# G( V5 Y7 i7 ~& _, Q: H( X

    7 q/ _+ l2 L; w' l4 e1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')" k* p3 [& v4 A( r1 Q
    2        cnxn.commit()+ l! Z& p$ Y1 r, H0 r

    1 K3 D; D6 J# p: k注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。: q* {% F8 R" }* P# L  j2 ~
    2 A7 I7 b' l5 Z4 C3 k7 ]; h7 c
    5、数据修改和删除% x- L* e  z8 c8 I9 H
    9 |1 q  t# C2 j) ^
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    3 Z( T2 X3 B  O" e: Z1        cursor.execute("delete from products where id <> ?", 'pyodbc')1 }+ w1 j4 u' [: W) A
    2        print cursor.rowcount, 'products deleted'
      B6 V6 @+ b" u9 k% I3        cnxn.commit()3 {( K. `) G& M. ?2 k
    ! v, Z5 P9 Z; O: ]8 E% z8 {
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    : d% ^) y; R- D/ k1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    9 x4 l  K( M1 G0 N; @. I4 d2        cnxn.commit()! b( ^' c/ E# V' T) _

    9 J3 J0 R: F: D8 j  ~+ b' q同样要注意调用cnxn.commit()函数
    1 D$ u1 @3 y4 }
    ' ?+ |6 T5 G* N! }6、小窍门
    ' `7 T, ]& U: o% u9 w: Q5 M7 K; ?! |+ n" p  j8 w: \
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:) u  f2 i7 H# a; m
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount0 y# U5 \1 F: h7 t* a+ j1 V; D7 U, ~# f4 X
    & ?0 L  I! b" e" n: N1 w' a  `
    2)假如你使用的是三引号,那么你也可以这样使用:$ o- m/ l8 |6 I/ O
    1        deleted = cursor.execute("""
    9 p+ a/ _0 j7 c. M7 i! n$ @, l2                                 delete
    ! \7 K) A) y7 @3                                   from products
    ( z0 @! J  e8 w0 j& `6 j; Z7 ~4                                  where id <> 'pyodbc'
    7 r8 n2 p' i6 Y# Q: X  g5                                 """).rowcount
    ) I: ?) o/ Y+ x- I/ P% C; r# ]" T$ E/ C$ x% ~% X. A' P
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)6 @; t# w$ ?! r
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    # X! k  v9 k% L$ Q2        print '%s users' % row.user_count+ Y7 z& a, \% O- d' N7 p

    : s: u  p' l/ `2 @4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    : x0 A- R2 H3 j, E$ S2 ^1        count = cursor.execute("select count(*) from users").fetchone()[0]( R( H& b9 p+ q
    2        print '%s users' % count
    # {/ ]7 ~7 I' s; a8 Z4 P+ _
    7 I6 D/ |" f+ Y如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    # Y; B. \* K7 r$ W) j! I# Q1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]2 n# F0 y5 {; g! K5 N7 V+ ^9 Y8 l

    . _6 W  N+ j- a& v' g  @在这个例子里面,如果max(id)返回NULL,coalesce(max(id),0)将导致查询的值为0。
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    《舌尖上的中国》所呈现的不只是美食,还有文化。这种被现实挤压而仅存于小时候的记忆,让人回味的同时也唤 ...
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-10-8 05:18 , Processed in 0.963652 second(s), 50 queries .

    回顶部