QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6148|回复: 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、连接数据库
    1 Z0 n7 i3 H* X! z1 ]2 S. h6 a) Y5 |2 J  {4 w! E1 x* s
    1)直接连接数据库和创建一个游标(cursor)6 w, L* V  w* n7 |; k
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    + M5 R& a, f1 Y7 d3 G! q. [( d' E2        cursor = cnxn.cursor()+ J. S& H: u9 W  }

      g* q) a$ y5 a9 Y# f) s2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。. A$ L* N5 i, f
    1        cnxn = pyodbc.connect('DSN=testWD=password')
    ) }' O  Y* D6 t" U% D# K2        cursor = cnxn.cursor()
    9 p' m: L& O: b! d* s# A2 `
    # _/ [5 W! l2 x# v2 }1 j% _3 @: U关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    ! T7 z& j& H0 {! ]& l0 S# p- {# A# K* N
    2、数据查询(SQL语句为 select ...from..where)- G8 x9 F5 B* q& Z' D( e$ Z" [( X/ `: i
    6 _# [1 n) l, v2 ]. d4 E9 Z
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    ; q; F" G: q1 o; y  \6 y' z1        cursor.execute("select user_id, user_name from users")
    : a; Z/ `5 Z6 v8 u9 ]) x' P0 y2        row = cursor.fetchone()$ }+ i& I: Z; S7 u5 l0 e9 ?9 v$ p
    3        if row:  b; q( W& K2 [9 M
    4            print row
    ( n) E' H0 w  Q. W
    2 c0 V8 _' I" y& J5 v% ^6 t2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    & w: ~# R9 G9 ]9 E* ?1        cursor.execute("select user_id, user_name from users")
      F7 \7 I# s1 Q; X2        row = cursor.fetchone()! F: K2 @( b+ }1 O
    3        print 'name:', row[1]          # access by column index$ G4 Z2 t* Y4 }! A: w3 r9 o
    4        print 'name:', row.user_name   # or access by name$ U' Z1 \" L  W; _& I$ \
    / {( A% u5 n  L( e2 G# z
    3)如果所有的行都被检索完,那么fetchone将返回None.$ l4 {2 B/ |4 G6 h+ \; q$ t
    1        while 1:
    , l6 H" ^4 x" E# g2            row = cursor.fetchone()
    0 |! x) p7 ]8 w$ z3            if not row:
    0 A; [2 v4 l1 h: B$ X4                break# P  ]1 @- u: Z: p4 t3 O3 Z0 f
    5            print 'id:', row.user_id% L2 q# q" Q+ x7 f, A
    / Q" O* X: f- x7 j
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    + {" M4 E" e' O4 U8 X% j* B1        cursor.execute("select user_id, user_name from users")+ ]- h2 z  H6 F8 W
    2        rows = cursor.fetchall()
    * y- y$ Z) V( ]5 t4 v6 ~% K3        for row in rows:9 o8 g1 _) x! l% M$ {6 B
    4            print row.user_id, row.user_name
    ; z' ~# }  K$ H8 V; w" q( ?0 Z( y, c- h7 h4 s
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。. K6 U& d# l2 r: j: n; K# N1 s* h$ E! Y
    1        cursor.execute("select user_id, user_name from users"):
    " }" O- o! g5 o+ z2        for row in cursor:
      D* i" W# ~( f! N, E3            print row.user_id, row.user_name
    1 {4 i, F: h5 i) P$ H
    - f" b9 c0 G( J/ M6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    6 {/ A+ f2 [+ o' t3 P6 G8 S* Y1        for row in cursor.execute("select user_id, user_name from users"):# T. o3 \0 i# n3 H3 E2 h" w
    2            print row.user_id, row.user_name
    7 B3 W* a4 i' i% `; e( T/ I: ~% N8 `: j4 j1 A& c" F0 k: U
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:# ^* s# h1 ^" r" m
    1        cursor.execute("""
    - s0 q2 I1 |9 F% K" {2 h2                       select user_id, user_name
    + W9 b! v4 l2 {- g# S1 w3                         from users7 }. i- O; c* v6 Z& e
    4                        where last_logon < '2001-01-01'
    * d: \* c' _, r% Q/ D* p$ Q, o5                          and bill_overdue = 'y'2 Z4 s. g' q3 b9 _5 E7 e3 ~
    6                       """)  \4 I3 p3 F1 T

    ; ^( f; y6 U# \# w3、参数
    $ A1 D9 Y1 u8 {& W: ?+ Q2 ~, i' V! e" ^
    1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。( [8 \! v* p4 p6 T
    1        cursor.execute("""
    / A: q- s7 r: w) Q: k2                       select user_id, user_name
    , ]# G8 @- |5 w3                         from users2 o' v5 |" c4 q( t! b
    4                        where last_logon < ?
    6 V- ?, x1 _& M5                          and bill_overdue = ?
    7 S$ b% W9 |3 s5 x' k+ \) \- Q6                       """, '2001-01-01', 'y'): g3 u( ], Q- i* t; b) h( ^! ]9 [) G
    $ U+ D  v% o; s+ r& M
    这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    6 S& U) \! B5 M6 R. D8 ]% W7 P+ M- b5 h9 t/ R2 |
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:0 X- i& \& z6 p2 y
    1        cursor.execute("""$ e; U7 B8 L0 Q2 f) G
    2                       select user_id, user_name( ]# g3 O$ [" j5 x. B
    3                         from users
    . ^4 t  V9 a/ a" a4                        where last_logon < ?
      K+ _% x" T( f2 f5                          and bill_overdue = ?$ T" ]9 B3 m1 ^  |, B8 I
    6                       """, ['2001-01-01', 'y'])
    9 h$ ?. y2 d  _) j  M& `+ j( n0 r( G9 M# {
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    ! p7 J1 M/ U+ o" Z! J2        row = cursor.fetchone(), L/ z  g% s# Z
    3        print '%d users' % row.user_count
      `( M; G( m" Y0 f+ u5 n  p
      }3 q/ e0 ^* [3 @
    9 a% `" {, N; p
      c% Z* g3 B  O6 Y- d0 c4、数据插入8 e$ E% s  U& v6 r' s7 I- Y
    ! f. I* p, e: }" r
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。$ V' U& Y) x- y, N8 U
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')"); o* c, G" \: E" B2 h& F
    2        cnxn.commit()$ N& s% V4 B0 t  P4 |  b9 K4 U
    4 P% G0 B$ x. _7 Y
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')% d/ w/ U* }: M
    2        cnxn.commit()1 Z+ Z* e$ F2 F% Q7 N
    # i6 G) [6 \% D# J7 x7 O# u$ P
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    " Q/ J2 R; [2 x- M% a) t3 Q1 h% K( i/ G3 C; n$ |8 W
    5、数据修改和删除
    - M9 D& C1 \7 S: C4 I
    * l! i1 `9 D8 r. @" ?# a- x2 V1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。) s; K" S. d4 t2 M1 I2 D% S* c5 T
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    + G* D, m% _$ V2        print cursor.rowcount, 'products deleted'
    6 ?  O: W+ T1 j& v) T5 ?3        cnxn.commit()! c6 p" S9 l) D0 v8 n
    7 F5 @3 s* r. M: Y/ p  |0 \
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    0 }, E0 L9 J% c' ]  S" D) E1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    7 t: f3 e; V/ o$ b0 Q) o; S2 Q2        cnxn.commit(); [7 ?' Z* S, c5 `" B! w9 i0 D5 j

    ) d" p1 j0 e$ G! @同样要注意调用cnxn.commit()函数
    3 H& z7 M; n+ X7 C: j
    ! O! t: N6 u+ y# E# J6、小窍门; t: |$ m% U* Y$ `, b6 Q

    - S+ m" U: _- z: w# V9 s1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    9 i2 A1 @$ h3 H% X1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    ) p0 H' S! _/ A$ W: [) A% Q, k, T/ j
    2)假如你使用的是三引号,那么你也可以这样使用:
    " z" r  V) {: m7 w3 S7 X1        deleted = cursor.execute("""6 [8 |9 m7 ]9 R8 C+ ~
    2                                 delete
    3 K* Y* d2 K; u$ Z! T5 t) Z9 i3                                   from products
    8 K, G2 q, ]2 {- B) d9 {* f4 Z4                                  where id <> 'pyodbc'
    * f; V& u& @2 i( S5                                 """).rowcount4 w4 w$ @, U( \% _4 D; C
    ; ]6 G3 a: u9 S5 [  z6 Z# y7 c
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    9 W8 s, z  W7 [+ z1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    ' |) q# z5 ]" J8 ^2        print '%s users' % row.user_count
    ' u6 o% U. e% Y& w" \
    ; L) ]. E* a5 a. H* g" F2 s" q4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    2 A2 t4 [5 v5 b9 p$ w' Y- @1        count = cursor.execute("select count(*) from users").fetchone()[0]2 }! _* p$ p5 R0 |
    2        print '%s users' % count
    # p  y8 A- X% F# h) h  m
    4 t5 g1 {7 F4 b$ P6 n; z& H如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    / h$ S% V% l3 J/ t% W1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]( S' f" l! v; i+ V9 A: E1 u

    , P/ n5 l; m/ M8 H/ V0 |在这个例子里面,如果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-6-12 06:54 , Processed in 0.400575 second(s), 50 queries .

    回顶部