QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6084|回复: 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、连接数据库0 o: H4 _2 ?( q% Y7 `5 U# K* W. e
    $ r( T4 [3 o$ ~9 \# v4 N" X2 s
    1)直接连接数据库和创建一个游标(cursor)
    $ K- `8 A8 r/ U9 d- p( i1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')  f, ^% Y+ p0 _5 x/ [8 D5 u
    2        cursor = cnxn.cursor()
    5 t- O( @. M- W) h5 k, m  J8 i' i; ?- M( i
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    , y1 }, u; p9 H& i/ d1        cnxn = pyodbc.connect('DSN=testWD=password')9 S0 Z9 w! i" z/ Y" N+ K
    2        cursor = cnxn.cursor()/ @7 u" U+ C/ g8 |
    ' V% q" n3 Z3 c3 m7 a, ]. U
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    6 ?5 H) |5 K) Z2 ?8 a
    ! H" A7 K# V$ i1 ^0 E3 O; D2、数据查询(SQL语句为 select ...from..where)( Y/ C+ N3 g# ?3 t. w( r; D" s

    / w' e  y/ I, S6 f; P9 L- I1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    % u/ U' Z8 q4 @* O9 K  W1        cursor.execute("select user_id, user_name from users"), O3 V0 ]3 a  T
    2        row = cursor.fetchone()9 F; I  ]- Y& z6 G7 M8 k
    3        if row:9 }7 C6 i. G3 o  S' M0 A
    4            print row3 {! n9 m3 R; w+ @
    4 w) p$ R( l3 i
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    3 E& {) v* v& Y. r; w8 M3 x1        cursor.execute("select user_id, user_name from users")8 m/ S8 l9 }; E' e  Z3 e% \; u
    2        row = cursor.fetchone()
      r- l% V. P/ p; g. _+ i- W3        print 'name:', row[1]          # access by column index+ s* p2 }( r) Q6 \6 a* w  k
    4        print 'name:', row.user_name   # or access by name
    4 z) D) W* c, c' r+ }
    9 \; p/ t. [2 h6 W' r" ]3)如果所有的行都被检索完,那么fetchone将返回None." a  U0 J+ C: V) A
    1        while 1:
    $ j+ ~. r& p9 P" k5 v* l" R2            row = cursor.fetchone(). A" G+ m- n$ u: S3 h# }! I+ c
    3            if not row:
    % p/ H/ C2 b9 u) f; W. h9 o+ k4                break
    - w, u' N; x" S& \+ G5            print 'id:', row.user_id* k8 b4 y7 H" W+ Y$ s

    0 Y( A6 t* V* a1 L1 Z, v* I4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)7 I, G' @. T! f
    1        cursor.execute("select user_id, user_name from users")
    ' A* C2 O( t1 S, G2        rows = cursor.fetchall()& O6 l, S. P$ s/ g9 E5 \
    3        for row in rows:1 {, W5 j: O0 w  q9 l
    4            print row.user_id, row.user_name, x6 \% F& J+ s0 a6 o. X
    % T3 q4 n; O- `3 ~# d( c
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。9 D) N  E; K3 |1 j# \
    1        cursor.execute("select user_id, user_name from users"):. Z0 G1 G* N2 o# ]
    2        for row in cursor:9 R- @1 [7 g5 `, _. x; e& @& O
    3            print row.user_id, row.user_name
      D/ r9 f7 S2 z' F; l3 n+ ~. R  e9 S6 W4 d6 ]4 V0 v
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    ! p4 N! R( [# |/ L1        for row in cursor.execute("select user_id, user_name from users"):
    : x+ {" v+ _0 G2            print row.user_id, row.user_name9 J% ^5 u% z* m* T4 i
    " p1 a3 \6 J( o4 {3 [) y
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:5 x% s, \6 c8 J( p1 f
    1        cursor.execute("""5 ^9 J6 X8 Z& [3 I7 m
    2                       select user_id, user_name
    ; h2 v4 l+ q# O" v3                         from users
    / f* g( K) Y/ k2 x' d  \$ d4                        where last_logon < '2001-01-01'5 \2 F8 K9 l+ L! W6 H1 w
    5                          and bill_overdue = 'y'# D' A2 @  _; E$ A
    6                       """)
    & z1 S* o. g9 ]9 b+ `
    + C/ {  \5 w' |- ]: V3、参数
      n/ q: p3 ?( X. p9 z. L
    - f. q/ g6 c3 \1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    . c5 u8 g  K) Q& H1        cursor.execute("""
    3 x7 ?! F7 e8 X9 w; k: c% C* X2                       select user_id, user_name
    7 U9 u! r& q" W3                         from users
    ! }. i' |2 k) D2 s- F2 ]4                        where last_logon < ?
    0 R( c' `$ R/ Y" k7 b/ ]5                          and bill_overdue = ?
    - `9 e& E# `" f' |6                       """, '2001-01-01', 'y')
    $ K) n$ o# u; c, L& I" r6 c  k9 F3 B0 \' a" ]" y1 `
    这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    8 g1 o& B/ I9 N: ?' c! M: w# o6 ~/ S, ^. f6 l
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:5 W8 v- U4 i0 T  l( J* d( E2 ?) T
    1        cursor.execute("""
    ) W* ~( J+ h( @2 L+ O8 w6 {2                       select user_id, user_name* D2 h( J3 ]9 C) S+ V- k+ Y7 T9 q
    3                         from users
    6 t4 ]8 t, l" e( }0 L4 q5 \4                        where last_logon < ?
    4 j7 Q' y7 q  ?/ l5                          and bill_overdue = ?
    / y0 w$ Z# m2 r2 ]3 I" U6 k6                       """, ['2001-01-01', 'y'])
    5 r2 S; }/ ~5 W
    , H% L/ O$ U% T9 g1 |1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    ! J& R3 K* g- |0 J8 x% v: Q2        row = cursor.fetchone()  c9 Q3 o+ e3 O1 @% D' p0 X
    3        print '%d users' % row.user_count
    7 N9 m1 f  |; I+ F1 P0 R: q, [( D. s$ ]3 E: T4 d8 W

    8 z" G% I* f" C' U
    6 w1 p& Q; K; o1 u$ k4、数据插入
    * u3 D. A& N( b1 H; h( M) \9 W7 ]( p5 T! \9 v# Q' O! X+ m
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。; j3 t; {* P5 r  _/ ~+ Q8 N
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")1 s8 |* f+ y) p4 \! ?
    2        cnxn.commit()1 @6 s5 v" c+ N1 K5 ?; \
    0 `+ U7 |6 P2 u8 `8 \* E
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')) A  J- D- e8 G* X
    2        cnxn.commit()4 U7 V" X  C2 ]) W" F2 S

    ; W: f. U- y: F6 J+ b# R; _注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    $ N1 l# A  L% m; s, h# n8 h& {% `5 j
    5、数据修改和删除* [! r5 c' H4 ?& V

    # h. F" @+ ^/ p4 F+ t1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。6 x4 F' o7 W7 Q" j- [$ B
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    9 Z  Q( f, G2 M; @6 |9 q, b9 X2        print cursor.rowcount, 'products deleted'
    . o8 p' q# v  p/ e' a" d3        cnxn.commit()
    ; [) i9 O+ A% I3 z$ [9 `% }9 h" S8 q9 k
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    9 g' i& K/ R3 Z3 X+ L* i1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount8 U- A8 v" W# D5 A6 l2 |
    2        cnxn.commit()
    9 c! d7 z5 w. Y: H# n- ^: N8 p4 a
    : F( Y* r$ Q# x3 Q* V" Z7 w同样要注意调用cnxn.commit()函数
    # G9 y# o' W" W( e
    8 G+ Q* M, r. T4 @2 r) `) Z6、小窍门
    ! [/ p9 K' J+ B& \8 |, T9 z
    1 D& C- p7 b7 k/ g1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:+ \& N0 y4 ?* a: Y4 w& l2 B. N
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    ! u0 P/ e# }- E. \
    $ J( [6 ]. s1 w  Q/ ^2)假如你使用的是三引号,那么你也可以这样使用:
    1 P) [9 ]( E/ ~' `1        deleted = cursor.execute(""". G. ]6 R6 n# m' i! H+ a
    2                                 delete
    . }2 g1 X8 J; I0 L! P3                                   from products
      D6 D( U( ]' w7 Z4                                  where id <> 'pyodbc'
    ' [! z# P0 O0 G; O5                                 """).rowcount
    + Y& @) T" o8 k* x/ z! N  }6 J
    * d; d! a$ K) r2 @5 e+ r3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”): t! p/ K) R/ [" G  ^
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    5 p1 L7 q+ ]+ T( ~( {' J2        print '%s users' % row.user_count. _- N- R# ]9 f0 r0 c

    4 s; R) h2 s: _5 w4 ^. ?8 J/ z4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。* A4 B- Q: P! j9 ~4 ^( V
    1        count = cursor.execute("select count(*) from users").fetchone()[0]1 O6 X# x- N- m* E
    2        print '%s users' % count3 f8 J' n* E0 V8 z8 i# \3 L0 [
    8 R3 j" N9 n$ s# f3 F
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。/ H8 Y5 h! j7 U8 A
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    # K/ P% S$ h4 a, u
    2 R* d( i! k3 v* U2 h6 w2 v在这个例子里面,如果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-4-10 06:04 , Processed in 2.697933 second(s), 50 queries .

    回顶部