QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6083|回复: 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 U- @  a8 S- R* m+ e: d, N- F+ J4 v

    ( O8 @. k: l0 U# j5 o! r1)直接连接数据库和创建一个游标(cursor); n! K- o, d+ [7 v
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    ; e8 T+ z1 j1 x5 M) q0 I' a3 K9 o2        cursor = cnxn.cursor()$ k. ~' S) R( b. T
    & m+ x4 k7 q! o* V" k
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    . {) J# V) i) G7 ]0 b1        cnxn = pyodbc.connect('DSN=testWD=password')* ?* V. n9 P% Q1 X* I  M8 F3 F( D
    2        cursor = cnxn.cursor()! y+ A: z( c0 A0 o$ \: l( w
    # j7 L5 o) b# x4 n; [) a) ~
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节9 @* p* E( h$ w  k; f4 b3 R
    * I6 A/ E$ k; |+ i0 T5 u; |
    2、数据查询(SQL语句为 select ...from..where)
    . P- }  Y) h% }; _, K! m
    0 |% J2 C: d1 L, v; f0 j) J1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。4 r5 R$ u. k' c+ v" G
    1        cursor.execute("select user_id, user_name from users")$ x2 L* l& l: G& M  t: [, O: J
    2        row = cursor.fetchone()0 }4 n7 \/ D4 Q$ g3 n
    3        if row:- V0 g; E3 ^2 O5 K0 Z' y$ L* I
    4            print row: x! H& o; [5 ^. F$ ~% Q* ]7 o. x
    / T$ Y# g( Q7 b* e1 N
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    3 r( g4 I# n" D1        cursor.execute("select user_id, user_name from users")9 R7 W7 M+ C% d' w) p
    2        row = cursor.fetchone()
    / W- \0 {: v5 [5 q3        print 'name:', row[1]          # access by column index% l& i9 M0 i( R8 g
    4        print 'name:', row.user_name   # or access by name
    & ~3 C' z5 W( S; q9 }. u( {  W$ Q* o3 a
    3)如果所有的行都被检索完,那么fetchone将返回None.7 E# Z6 A) t/ Y- W
    1        while 1:
    4 s8 O, O- t: }( U1 d2            row = cursor.fetchone()$ z1 V# E0 d! p5 c# Q
    3            if not row:
    $ p9 a! l% W# w1 n: n6 S4                break7 M  M5 _! w& \
    5            print 'id:', row.user_id8 a+ H8 @. M/ D: D

    # k7 C2 u, J9 o1 f& e0 l, r4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)9 q4 x- b- y$ y* q+ T# ~
    1        cursor.execute("select user_id, user_name from users")
    ) G9 N% I0 [/ O* n% h$ |  c2        rows = cursor.fetchall()
    . }2 g/ v; ^0 ^' }0 K2 A3        for row in rows:! c2 H$ L% a) V7 o0 i: Y
    4            print row.user_id, row.user_name3 d( w9 V) ^' d4 R, L

    . L0 @! E* {9 `; [% [2 Z( U+ w5)如果你打算一次读完所有数据,那么你可以使用cursor本身。7 b% H6 z3 \7 d" s" \; e6 h
    1        cursor.execute("select user_id, user_name from users"):
    4 r8 [/ M# w; z" _. R2 H2        for row in cursor:
    * S) C1 V3 o# V3 a2 F( c1 B1 v( k3            print row.user_id, row.user_name
    6 p! V( q' b9 D0 @8 @0 m( s, ]1 z( o
    6 e0 l/ k. A1 Z, s/ r& `3 \4 L6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    # d# n+ r( g9 z% ?. \1        for row in cursor.execute("select user_id, user_name from users"):
    / y. u* W: _: D# p/ P. w  E! V2            print row.user_id, row.user_name( J1 u* R, |' t$ {/ l8 |( U

    $ `! |/ p" v" i/ X  O) k7 a7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:
    0 P9 Q' j- a6 l6 M0 {5 U; B1        cursor.execute("""" O7 p' G' @" v7 [, U8 Q
    2                       select user_id, user_name4 d+ t' e9 z3 Y% U; G6 g; k8 ^* {
    3                         from users
    ) w0 U1 w& K& N& c. l; H$ c3 }4                        where last_logon < '2001-01-01'" w6 m8 k. v0 g, i5 |. A
    5                          and bill_overdue = 'y') r7 j) t# P9 g* O' y
    6                       """)
    ( L9 w: A# J: M  U3 ?4 f# T
    , D. M$ T4 z) L4 I8 ?2 n& D3、参数0 n3 h( n/ y7 J
    ( c* P4 j' g2 x# L
    1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    ; K' h) V; _0 u4 u6 a  K9 Q1        cursor.execute("""
      V' D8 p+ ^1 o6 u! Y2                       select user_id, user_name
    4 j5 Q1 }6 ~6 s, ^3                         from users' B# f/ ]/ ?7 m. C( `: t
    4                        where last_logon < ?
    % y6 d6 r, m+ _* Y! ]5                          and bill_overdue = ?" n2 l) c# X1 g4 Z. m, m
    6                       """, '2001-01-01', 'y')
    2 k6 x4 y+ b. ^" ~0 w5 H% C$ l+ r
    这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。9 h% V% r" `4 c% W, a
    ; A# U( L' {; L( c: A* @- }
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    % S6 z$ _! g& C/ S1        cursor.execute("""3 ^  R- J' B) |( L3 L+ O; t
    2                       select user_id, user_name
    5 s6 h3 y3 |% J8 \3                         from users
    + F+ Z# R0 ]+ }4                        where last_logon < ?7 g7 \. s/ _# i. y
    5                          and bill_overdue = ?! [8 v2 f+ i; b* D* M3 C
    6                       """, ['2001-01-01', 'y'])
    6 o. O, q. ^1 S; z# Z9 f. c9 \* u: R7 n
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21). I. y; P9 u: y/ _8 U) [
    2        row = cursor.fetchone()3 H& Q# N$ {7 m0 O4 t8 L
    3        print '%d users' % row.user_count; R8 W2 B5 }: {2 Q& \1 F  V9 ]
    8 @) g: k4 R* L. G. @, ]: Q
    . k6 v0 b5 A6 Y& J
    + ?* h% X5 b" ^+ b0 H' a
    4、数据插入
    / l& v/ K9 h' N( m6 m' Q  N" A0 m4 F& M4 H$ `( o8 F
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。- Z. r( Y2 A3 d/ }
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    ( _$ [) {, x9 l; {; ?9 W3 W0 ]2        cnxn.commit()
    , h, _7 [# w* G$ |. m4 K! z. c( M) Y. n
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
    - w. Z/ K# X# i6 x( O5 s4 t2        cnxn.commit()( ?' T+ \) |* G
    8 X- N8 ]5 x- t% {9 l: m- Z; q! x# u" G! ~6 D
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    , g" Z. X2 s. |" j( I5 r
    2 {; z2 Z; T0 ~# u: R+ u; i5、数据修改和删除
    & z$ i5 Q+ b/ j8 c  F9 v9 r0 M" z' Q* U8 {8 U/ y; G0 ?5 @$ Z7 H
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    " w- O( [* V  r9 C1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    : J8 _# C- t, s. E) ?: ?2        print cursor.rowcount, 'products deleted'
    " _4 }  b: d) r) d* [! k3        cnxn.commit()
    ) x7 v4 X" I. {) J. T; Z  ~" Q# D6 G. Z0 {' I
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    5 e9 g2 U/ n# K+ P/ P) U5 q1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    # T$ d6 D4 e9 b+ x2        cnxn.commit()0 h3 A# V5 E+ G* o
    ) N. q9 J* v0 ^3 ~; F* N: g
    同样要注意调用cnxn.commit()函数( p( a7 p6 F; R1 A- ~* L

    2 C+ p" D. `& K6 C6、小窍门
    : I9 _+ X9 Z8 R. f) k4 X
    & Y0 R6 ^. L3 Y' l- W7 z. _3 z1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:8 w$ h' \3 H6 R6 m
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
      u1 _" m; g5 P6 V  b
    ' a6 n. I: v, ?  }6 _% L& ~5 Y% j2)假如你使用的是三引号,那么你也可以这样使用:
    % y- ?; \: O( z* k; X1        deleted = cursor.execute("""
    2 q" E, V2 s1 S3 D! H$ m/ y& |2                                 delete
    1 v$ Z4 \! D2 I; ~3                                   from products
    ) s6 Z* K! r6 E- U- Q4                                  where id <> 'pyodbc'
    $ e) t. G( g5 m. {5                                 """).rowcount
    7 Z! k  P2 S" x4 |. j7 B7 P6 \2 T
    5 V4 _+ ]) x$ o" I  v# U3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    0 {* r, q- a2 A& t1        row = cursor.execute("select count(*) as user_count from users").fetchone()7 s* G& o" i; E0 X6 m0 F; u& L
    2        print '%s users' % row.user_count
    7 _4 l5 q$ A9 C, g8 Y, G) }  G( G" i; w( e  L! w
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。2 [/ m( Q$ `- f5 H' ?" j" ?( o1 Q
    1        count = cursor.execute("select count(*) from users").fetchone()[0]
    5 L2 c* U) n3 D: b: l2        print '%s users' % count' u/ e4 Z4 |" @; g0 f0 D; g
    ' b- W3 x9 n/ ]6 I/ v
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    . w0 d* i$ h6 r' f1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    6 E9 I0 t5 A; H! Y2 {+ j7 [' t/ i4 H: v1 k/ H9 H
    在这个例子里面,如果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 00:22 , Processed in 0.822118 second(s), 49 queries .

    回顶部