QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5700|回复: 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、连接数据库9 ]: _/ [3 p& ?5 q0 F
    1 _0 N- d' Q+ r
    1)直接连接数据库和创建一个游标(cursor)
    " A' F3 ?) ?. f5 m' C  W1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    : x; d* `6 C) O2        cursor = cnxn.cursor()
    ( ?: L$ j) J8 j* v0 p
    - E- {7 i3 l# Q! m# C$ G  W% ]+ I2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    7 X' ~! g& z# V6 k9 d0 {1        cnxn = pyodbc.connect('DSN=testWD=password')% X# ~4 p! m2 ~
    2        cursor = cnxn.cursor()
    ) X8 m* R: }+ x5 L( m9 N) E& F7 S0 t! L% z' O7 Y; N
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    " i) k8 H9 ^! l& p. L
    * ]& Z$ I/ W" L2、数据查询(SQL语句为 select ...from..where); h5 Y, {# w; A1 b. H+ l

    $ G9 d2 x! G+ f2 \' q1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。' }8 l- G1 O( P* R5 I/ q7 w
    1        cursor.execute("select user_id, user_name from users")# E/ y% `9 B: Y/ U
    2        row = cursor.fetchone()
    & f7 [8 b( y# l9 u3        if row:
    , ^  n7 [; W( S! G  D/ w0 G4            print row
    + X) d3 c3 w& R6 v4 t- L& B* N5 j* \8 j* K, O: E
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。1 q* a, b  a. {+ x
    1        cursor.execute("select user_id, user_name from users")
    # _  G) p; f6 F( l- D9 |8 Z3 Q2        row = cursor.fetchone()
    6 W1 ~6 V, M: G1 ?3        print 'name:', row[1]          # access by column index; H4 J" y% G8 h% ?' _7 T
    4        print 'name:', row.user_name   # or access by name
    ; t% A$ r4 @! G' @# |8 r, f
    # m. A2 F; U5 {, `: q3)如果所有的行都被检索完,那么fetchone将返回None., [5 o( P) G6 C% g6 W" Z! q( X
    1        while 1:
    " |; [" q% \: N. M; k* Z. ]2            row = cursor.fetchone()7 |8 a3 J: }4 }$ {6 W3 @( n
    3            if not row:3 q* [3 U; O5 k: [- o7 [$ l
    4                break# ~5 {) m! Y: ?
    5            print 'id:', row.user_id8 U( [1 ]% U+ y# E# U8 E' a3 Q; p- `

    * L2 }; M! D: D: C( l4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)# q( ~4 I1 L9 B& P/ g% X
    1        cursor.execute("select user_id, user_name from users")
    2 y( n: g3 o  c4 i' r+ u2        rows = cursor.fetchall()/ g/ Z( h" T: Z# Y9 U4 W/ K
    3        for row in rows:3 V0 i' ?: y4 h
    4            print row.user_id, row.user_name
    ! E% D* J2 f9 S' U% A3 @7 g$ b+ c% R1 S1 d
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。
    , w- d' G8 D/ N1        cursor.execute("select user_id, user_name from users"):
    ! l$ F( W/ U! n9 ^, w- H: V+ h( d9 L2        for row in cursor:
    5 R; b' `$ d$ P8 ~; S# S; E3            print row.user_id, row.user_name# X: _0 ]+ h2 ]/ F

    7 V  x: x2 Q  d; d9 u6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    2 C7 e; s8 g# M% M2 e0 q4 K1        for row in cursor.execute("select user_id, user_name from users"):
    ! S( R% z, w, U" A6 X; w2            print row.user_id, row.user_name6 z! @( Z/ ~9 h4 k$ W  w2 j
    , y, r, D/ K" {" }5 R
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:; b/ L, y; a6 X" N; A" _5 ^
    1        cursor.execute("""
    0 a! q& d* D" g" R9 q! y2                       select user_id, user_name" r. f0 @/ D) H: g9 W
    3                         from users6 ?& k. m/ O9 R: s9 V; S
    4                        where last_logon < '2001-01-01'& E2 w8 \4 K& j) a
    5                          and bill_overdue = 'y'# E$ |% E0 _7 @1 D9 }3 I
    6                       """). u, j, [/ Q6 F
    ) g8 R* Y2 J6 E% {
    3、参数
    - H4 M$ y  L3 B3 g1 C1 n, \5 T
    : @  `+ ]: L/ m; y& Q/ G1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。0 V5 P: q5 L( u; ~, ]8 X
    1        cursor.execute("""
    & p; G& T4 z3 H4 b- f4 b7 H2 r2                       select user_id, user_name
    ; S% Y; ^3 H- L0 x6 f0 P  I3                         from users
    $ G3 e" y  ]2 M+ [% g7 k4                        where last_logon < ?
    6 n5 w3 P5 y# j% y* a+ C5                          and bill_overdue = ?- A2 j: b+ y( K8 m6 l
    6                       """, '2001-01-01', 'y')$ d7 g- P' ^; b1 l/ T! `; I
    # l/ O) x- n! H7 X* R, S
    这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    ' J9 X7 y0 z$ V  `- G6 }5 t5 m$ X4 r+ N5 o, o( k+ [- x( P
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    , C+ O) x3 F& e6 g- J9 v1        cursor.execute("""
    + \) u0 t" [2 E- q/ r& A) t2                       select user_id, user_name
    : o1 F& y& Z  h3                         from users
    4 N) S0 b! c( x4                        where last_logon < ?! _- \) a* x6 W( i8 Q$ E" l# A
    5                          and bill_overdue = ?6 [; d' j: i  N) M( |- D
    6                       """, ['2001-01-01', 'y'])
    + n9 F2 s( _% {$ g5 l4 u, M6 n: V
    , t$ f; Y7 G' ~# }1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    * a- e' }! D+ Y) [0 ?2        row = cursor.fetchone()2 e7 g% E$ v3 f( K2 z$ o
    3        print '%d users' % row.user_count
    " o- j' N7 A3 Y4 b
    7 A; {0 q; g$ d% {+ z$ x
    * L, T, e! V& U* b' o& \. S* S0 b* ]: X% k$ n: O3 T
    4、数据插入
    0 H+ d) T( d, }  d  |1 c
    * e8 V/ I8 k0 P9 M& }1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。7 R% y& `2 L, X" J
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
      z6 F; V; B7 N4 I$ L9 v, g6 p4 {2        cnxn.commit()
    4 x2 J# p# f2 U) h  T- \; P. z! w
    , |# ~# ~" ~3 h/ b: [. m1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')2 O) e! A" k& T9 y6 O; R! j( }
    2        cnxn.commit()7 b. V6 T. g" ?* I5 [! S

    & n  V% \) y+ P: r) p8 {注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    * J- x# a  D6 k2 N6 _
    1 K7 X* U- s3 _( `5、数据修改和删除
    : l" p; d4 c0 i. h
    + J+ A6 f. V% D0 E# Y8 h1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。7 O% X+ R7 a" l( l2 c$ c5 o1 j2 P
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')- \2 [  _% v( @3 h/ @' G& ~$ e  W+ H
    2        print cursor.rowcount, 'products deleted'! e* g1 ~/ B& |9 ?4 @/ g$ Y
    3        cnxn.commit()
    . w! @! i/ Q! u3 d. u. I+ k1 o/ A4 f1 a$ |" c" a7 [7 Q
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    # M5 Y2 U5 K; x+ w6 V$ y1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount! L2 v. z: {' ^1 q; I
    2        cnxn.commit()
    ' L8 O7 o6 x" H( p; e+ V* _# A7 x9 v; l: }/ b6 C
    同样要注意调用cnxn.commit()函数
    ( y$ h" |9 [+ U/ g9 b2 o0 l- W! C3 p& ~0 {
    6、小窍门8 Q3 R4 X* m" z9 M* b  V- y

    & y$ r3 J1 r0 |4 A! g1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:& O, A, l8 l7 r5 d! v+ Q" N7 C
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    ! J* W6 k  w& k" g2 I% o, v7 v3 k9 g
    / s( t1 l" ]0 Y: d: X2)假如你使用的是三引号,那么你也可以这样使用:
    6 }7 u+ v5 B9 R1        deleted = cursor.execute("""
    1 A6 x6 |6 B9 i6 L- U3 B2                                 delete! Y  S% I- [% Z* z, _# E/ W
    3                                   from products
    / A! C6 ?8 \  T0 L6 y' S4                                  where id <> 'pyodbc'& ]* J  P. v& d- w: i
    5                                 """).rowcount% J( D/ H0 Y! z3 I! Q

    ) a- f0 W5 X" z* o5 l3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    & \6 {7 E; K0 R0 d1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    # s- i6 p0 t% j3 E6 t2        print '%s users' % row.user_count2 H% ?  U2 I7 F
    2 ]6 G  n0 S: h. _1 I
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。7 ?) q9 ?- F! R7 b( E' n
    1        count = cursor.execute("select count(*) from users").fetchone()[0]7 V! v9 E7 [- M  T8 a" D3 q4 s$ B1 T" m
    2        print '%s users' % count7 S- i7 Z; F5 q! T0 B: ?! c
    8 ^% W5 O8 K+ E. P  O/ K$ C
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    , {' G# B2 z5 h1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    $ ]4 h' R0 ~% v7 o) c
    ; C1 Q( a4 U$ e9 Z' Y在这个例子里面,如果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, 2025-8-3 02:40 , Processed in 0.360762 second(s), 49 queries .

    回顶部