QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6088|回复: 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、连接数据库- R  I! f0 ~/ K) Z7 v1 x

    6 q6 J6 W6 w1 n3 @+ Q/ p6 H% e1)直接连接数据库和创建一个游标(cursor)
    6 X* h8 p, [6 v* ~* K1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')" t6 I- }( h; b
    2        cursor = cnxn.cursor()
    ' h/ o$ }- K/ T" l2 P
    9 G+ I( N. {( o. w6 s2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    % c0 }, Q( X9 i/ c1        cnxn = pyodbc.connect('DSN=testWD=password')
    $ a# E& d, K2 f2        cursor = cnxn.cursor()
    " j6 i' z+ h0 ^/ f8 p
    - j1 m6 L! M% _! ?# A8 J关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    $ R: G9 l7 T" |9 k. g4 f
    ( a; Y; B, Q: l" M( g) B2、数据查询(SQL语句为 select ...from..where)8 ?$ ^4 k3 Q: H# z, I

    * G, N6 P( x" O1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    + Z. x2 O% v7 a- E1        cursor.execute("select user_id, user_name from users"). m1 `* Q% `; a
    2        row = cursor.fetchone()0 |/ m; z/ z5 Z3 ]
    3        if row:
    3 [. O1 S7 o, [- s4            print row9 _0 b- O2 x% H# A

    ) E1 X" ^6 T! K$ w6 K2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。( v2 l* D: Y% X
    1        cursor.execute("select user_id, user_name from users")
    ) ]6 ]" V! G$ W0 h7 x! p2        row = cursor.fetchone()/ D% t! j/ p; n$ @3 l2 N
    3        print 'name:', row[1]          # access by column index# d' b8 H% V3 u7 [* l0 M% i% ~( }  \. W
    4        print 'name:', row.user_name   # or access by name
    / y3 T8 R4 \) u- J3 X
    + x) o  z/ ~& h1 y1 `3)如果所有的行都被检索完,那么fetchone将返回None.
    3 G) t8 b% Z' n; k8 @2 v2 d! ^; z1        while 1:6 ^3 v# o# N: u& Y" W% |( c
    2            row = cursor.fetchone()
    ' c: T1 u% b8 T3            if not row:! q* o( V4 {# k7 n- u$ z, ]/ L, u
    4                break
    2 H# {5 _7 Q1 z5            print 'id:', row.user_id
    $ B  l0 p5 n# u3 k2 a
    8 C+ _+ l+ \8 d9 i: w: Z! @4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    6 @4 v, V$ f6 @* Z1        cursor.execute("select user_id, user_name from users")
    ( E& M. i5 e% Z" D' G+ Y  @2        rows = cursor.fetchall()# C2 C0 z. K; c, F
    3        for row in rows:5 \: `0 s0 e1 R
    4            print row.user_id, row.user_name* R7 Q; F0 ~6 G

    ) q. S: I$ Z' S6 Y# M5)如果你打算一次读完所有数据,那么你可以使用cursor本身。
    & p: ^8 C* ]' O0 f  q1        cursor.execute("select user_id, user_name from users"):% z$ N1 h1 |' \* |8 Q
    2        for row in cursor:3 R; K% x& i+ v$ Q- N- S3 V
    3            print row.user_id, row.user_name
    - q# ^  }( \! A7 c7 z! ^
    ) Z) }* V- D+ N9 H6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:- U8 e" E4 N2 x* b
    1        for row in cursor.execute("select user_id, user_name from users"):
    , f) t9 K- q; k  g7 h7 q2            print row.user_id, row.user_name' h- Z3 w6 u2 v! f  e; j/ r, x# a1 m

    * M. f: q& [$ S% H7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:$ z9 ~. L2 ?2 H
    1        cursor.execute("""
    7 R, c, A* X' E3 X/ D  X# S( Z9 o2                       select user_id, user_name
      l! y, E) N3 F' g4 M, k# G0 k! M3                         from users
    0 u, _; I0 ]( E1 ~8 E2 \6 f8 W4                        where last_logon < '2001-01-01'
    # L# b3 _4 N1 j4 s5                          and bill_overdue = 'y'0 w+ V- s- B  ?- x6 `5 P* Z  e! r
    6                       """)
    ! X" d& t0 G( _" v1 `8 c8 d8 L2 U0 m: T+ `- Z' k
    3、参数' k. V  n% |0 _) ~$ w% i# T3 f
    6 M6 `9 N1 J/ {4 u, O
    1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    ; g$ l- m; N; ~- N) q. A1        cursor.execute("""
    $ f! s5 x# @  p2 U6 j# f2                       select user_id, user_name$ v' r. g  I2 x5 W8 l- p
    3                         from users
    " `: @$ n& B- B' l1 S, v4                        where last_logon < ?
    , ~" r/ z) C7 ~% q7 L* L5                          and bill_overdue = ?
    / O3 Z' t' j2 F& S  g9 H9 H6                       """, '2001-01-01', 'y')
    1 n; Z' Q! z+ f  ~% a% {  Z4 }6 F! h8 t& r/ A; h
    这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。, ~; J0 o7 L/ d/ h% ~

    ; E, i( G" B; }0 ~% q6 Z3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    2 S+ `- M; t; ?1        cursor.execute("""
    . l) O3 c; N; _9 v2                       select user_id, user_name
    9 \8 r  R/ A, ^+ \2 Y. v" s2 Z3                         from users
    $ |. g: r* q0 i( W  l7 i4                        where last_logon < ?
    # P8 @4 F7 C2 `4 d7 Q/ q5                          and bill_overdue = ?' w2 s: L7 _# s, x
    6                       """, ['2001-01-01', 'y'])3 @# e8 \+ j3 E, d1 l/ j

    + @; m. t) y: l4 s2 @1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    * m) ]9 f& M8 C% ~2        row = cursor.fetchone()
    * m1 \9 R3 d; z3        print '%d users' % row.user_count
    7 v3 n/ s) x: R: n
    ; o( D! X, f$ b& B! O- i/ I$ [
    / ~* @1 q$ n/ N5 ~
    & i5 k6 R' P, Z) `4、数据插入: Q- @- _: e, F; K2 q" J8 Q, C9 c3 r
    - Y& u3 B. ^- O! R6 ^6 j
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。( f2 {' _. Y" @. Z" |
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")# t) I4 Q2 _5 ], [9 T
    2        cnxn.commit()
    3 L! ]0 S0 o  q/ r
    6 N! g7 ]  V  a+ ^& y: R7 ]$ V1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')0 Z3 j8 G3 [* p4 E% D
    2        cnxn.commit()4 v( p" z6 p% ]. Z4 [; [7 `' T

    - |  y. M: O7 B% o注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    - H! n# Y" \) @- z) a+ W( I8 l; b9 N1 y3 x# M
    5、数据修改和删除
    % o9 ]: P7 L+ G- K/ i7 x- P9 N# Y2 v4 f8 b* M* j0 \
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    $ R% D- j1 Q. V0 n: ]. k  C1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    4 y8 p$ U: r2 W2        print cursor.rowcount, 'products deleted'
    4 u0 g. v4 h$ {3        cnxn.commit()
      ]. L5 z% v* y( g" J1 k
    4 }6 _' r/ D6 `6 V! U) z- i2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)+ |* b3 H* H& T% @
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    8 D+ y+ j) D( ?0 F2 x2        cnxn.commit()
    0 l& g0 P) ~6 D5 G. U' s1 X, R
    4 n$ A" ?, T7 G1 \同样要注意调用cnxn.commit()函数
    9 F3 s0 a1 b5 ?& o6 D; M3 z4 S- N7 N4 N
    6、小窍门
    $ Z' h! l  _5 h, B4 ]* o
      m( x% Q5 w/ L  n1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    & b4 Q' u" g; h+ Q7 c8 y2 G1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    / z& `: b4 Y/ F  Q. {
    % r# ^  e# a/ F# J4 a( f* O2)假如你使用的是三引号,那么你也可以这样使用:
    ( {3 s/ y" l( G' W1 T* r2 [( J9 f1        deleted = cursor.execute("""
    0 s1 g. Y, i  n2                                 delete
    + M  ^2 O( i- {% x6 c8 t, N3                                   from products5 n; ~7 H2 q9 |  C: _5 |% G5 ?
    4                                  where id <> 'pyodbc'9 E1 E; z) }1 A& F8 W
    5                                 """).rowcount7 j! A' N0 N) v9 i+ b* r; x2 C  E* V
    6 t/ X3 @) b) Q& G
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)2 ?% Z& `* E) j- c- s
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()2 m) k! u) F2 B
    2        print '%s users' % row.user_count! |! Y. m5 P* d8 s+ W$ H7 c& S

    2 [- X& S6 j6 i& l' J3 Z7 [4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    " w6 W7 I9 R- J8 G7 {1        count = cursor.execute("select count(*) from users").fetchone()[0]) ?4 C$ }& m3 j, K+ H  L
    2        print '%s users' % count/ |% x5 y; d$ @. {
    - ~; q. n$ T' G6 N6 p; r& }
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    . e1 {, y/ g7 I) N% R1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]% Q9 S. @+ P/ w5 y7 X# I

    2 A  V" o$ ~' L/ }5 l在这个例子里面,如果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 15:38 , Processed in 0.383665 second(s), 50 queries .

    回顶部