QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6144|回复: 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、连接数据库! w- N# G/ T1 ~: ]

    , Y- O/ ?4 w. r/ Z1)直接连接数据库和创建一个游标(cursor)
    , U/ \0 }" ?2 D, u1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')5 e# p7 |% O& A( t' C
    2        cursor = cnxn.cursor()
    . S/ [: }4 C: c& j( Z) G0 p9 z7 o3 I4 M+ x6 H/ a. K; n4 E
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。3 D+ y" S/ M3 i0 C& Z8 t9 y
    1        cnxn = pyodbc.connect('DSN=testWD=password'); @! T2 X' x  u% L, C
    2        cursor = cnxn.cursor(): ]3 g) K( _" y6 x

    ) c$ V  b( H# p关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节6 Z% i( f& Z6 x9 s
    ' k) |- H* X7 I0 V
    2、数据查询(SQL语句为 select ...from..where)
    * r- Z, K9 v$ \" v. ]0 n: e2 c. o8 [* N" }3 p& J. e' K) A) e
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。3 G2 I. I4 K% D3 ?9 \7 ~
    1        cursor.execute("select user_id, user_name from users")* L: C1 h1 F  c1 z; z$ f0 u7 K
    2        row = cursor.fetchone()
    6 o: ]8 U; A2 \+ K/ ?- K3        if row:
    * y8 P' D0 z$ [& K% o, z4            print row, R) o; p$ ?3 V7 h! H; k8 v2 Y
    - `& v- W1 W# O' ]
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    3 J, V, {1 B: Z8 M1        cursor.execute("select user_id, user_name from users"): G6 z% e0 G0 V  A# Y# v
    2        row = cursor.fetchone()$ H9 K" `, l4 M2 ^& @* U$ J
    3        print 'name:', row[1]          # access by column index3 }% T2 q. Y# A) T2 ?
    4        print 'name:', row.user_name   # or access by name& _+ m" A" c' e$ W% Q& C0 D0 E0 E/ N
    6 F% t5 [/ K2 n# q/ L$ N9 A1 R
    3)如果所有的行都被检索完,那么fetchone将返回None.4 j5 x$ A0 Y! E& t
    1        while 1:8 c+ v+ U$ ]  z9 k9 l5 B/ d! h
    2            row = cursor.fetchone()
    ) C' o: A4 ~6 D5 G# N" E5 G5 M3            if not row:
    / S5 w  Q% H$ S, O2 n4                break
    7 H7 N, g; p) w: V& K: ?0 Q1 S4 ]& J' k5            print 'id:', row.user_id
    3 n9 E# [+ w7 q/ a5 T7 y2 i* l# K: D) t% I
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)3 ?+ P5 K% d, n+ \
    1        cursor.execute("select user_id, user_name from users")1 w7 @; b( @* P8 u* E- `
    2        rows = cursor.fetchall()
    ( c6 V" F% O+ `( V3        for row in rows:% l% V$ ~% y; l% s$ c
    4            print row.user_id, row.user_name4 c- Q% e: w; B3 a

    - L$ ^7 Z! X- ]0 h3 w5)如果你打算一次读完所有数据,那么你可以使用cursor本身。# G- S# s! r% E4 [. A: N8 I
    1        cursor.execute("select user_id, user_name from users"):5 a+ z/ e! J4 p1 _/ u& h( G
    2        for row in cursor:1 ?" O/ [: g; l3 t2 W, N0 }' B
    3            print row.user_id, row.user_name7 ]2 u/ ?: ~  }
    8 O4 B0 l1 d; g4 L+ }8 L
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:! b1 L" A2 _% c1 [! l$ s
    1        for row in cursor.execute("select user_id, user_name from users"):6 x# F9 W$ g% b
    2            print row.user_id, row.user_name
    , [! m+ u2 E8 M# m1 g- e2 W& {& Q. H
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:: q9 n; ?1 s9 I3 D
    1        cursor.execute("""  e7 }8 Q! j8 A) A. z2 x
    2                       select user_id, user_name! s! k$ g! C5 K. R
    3                         from users2 K' _1 }4 I: R  c3 B  g
    4                        where last_logon < '2001-01-01'
    # J( T; S0 C/ M% g& Y5                          and bill_overdue = 'y'
    7 _5 m/ M2 F# m* B+ w  m2 i8 p6                       """)
    8 P! L  B6 U% V1 @8 M6 o- F  P+ @9 u/ E9 T9 q! O& O
    3、参数
    ! N% g4 U1 x! `2 R+ ^
    & i* @( o9 [" b! a) Z, b1 C1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    & ?" _, C1 ^1 T* ?" g1        cursor.execute("""
    3 M$ V! A5 h" y+ P* S3 }) W0 M2                       select user_id, user_name
    / o" O, y4 [2 h/ r3                         from users
    & ]" q" P: N+ C5 S4                        where last_logon < ?
    # }7 Y/ k: ~' Y( j$ Y- N# w6 ^5                          and bill_overdue = ?( Z% A0 Y' G, f9 ^4 v0 t
    6                       """, '2001-01-01', 'y')
    ' Y6 ^9 c- D# W7 R3 h; k
    - o, M; |" @9 E- O这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。& R% [4 x0 i! a# h' ^3 `. M

    7 ^' [2 d4 n% J. z! ^9 x, }5 |3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:6 e# o/ I+ \  t0 F$ E( N; e- l
    1        cursor.execute("""
    + H- ^' {* _$ b. `$ I4 q7 w2                       select user_id, user_name
    5 N6 l, u# s/ _3                         from users
    " f7 L/ q0 ~; b6 \  Z" L) q0 d' A4                        where last_logon < ?2 P- o# R5 v) I; N5 _( Y' I
    5                          and bill_overdue = ?  a) D1 q! }, ~5 R! g2 O0 m
    6                       """, ['2001-01-01', 'y'])( h( E6 {- H$ ?) D. B$ K

    ( L0 X3 v- \5 Z, O4 `* J8 l  v: X! i  y1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    * |% k7 d; c2 |3 Q' d' Z& }! e* ^2        row = cursor.fetchone()
    8 R9 Q3 O; h; g9 J8 ]3        print '%d users' % row.user_count
    ( ^, \) w$ t; p' W) D
    ) r  ?7 I: \0 B( a) J ! H5 \  e: X' N2 k0 X3 q' c$ ]
    6 e/ I0 S* I. Y+ W2 O: B! K# y
    4、数据插入
    * `( |5 C6 Q% I- D* G1 x$ {, K- p  [! I
    6 }6 c1 f1 t, {( O% W" J, L' s# h/ k# p1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。, F( \# A+ O6 \2 b! Z
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    9 s  j2 i& [0 y, q! n2        cnxn.commit()
      T% ?! s, E9 v; [" a+ c& [
    , _5 S; C  r7 E$ g& s1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')8 g$ D$ }( v; {7 |
    2        cnxn.commit()
    # K  |7 h3 Q1 U8 @& s0 A8 z
    5 y. k7 p& R4 Z( Y注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。5 B- N- @6 L+ m. ]5 z

    0 k1 b, z  s/ ~, b5、数据修改和删除
      c7 B8 S7 L% P, s" }2 ]4 R6 L& ~" p" J/ J
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    0 O: T$ \; @( N) i: ^, |1        cursor.execute("delete from products where id <> ?", 'pyodbc')5 T' w- h1 }# j& |; a6 Z4 ^4 ]; R
    2        print cursor.rowcount, 'products deleted'
    " Q: _  G$ o) z3        cnxn.commit()1 {! Z* b! }& E& A. c& d
    7 ?5 X& i* V' c: z7 N$ [
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)% Y* A5 i; d7 g8 _5 B% I
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    ( n% j& `% q; b0 V/ N$ D+ r& W+ |, ^2        cnxn.commit()- p  e: h: j$ A3 e- C
    & q3 E, e, ]/ F$ `0 w- t4 K
    同样要注意调用cnxn.commit()函数
    8 q2 P, n+ W& N5 L4 {9 l/ a
    3 W' J- g6 x. Q; o8 }% p* B! t0 m3 p/ i: d6、小窍门- w* t5 I9 D$ `/ }. }: [
    # p1 i+ Q6 O/ ]% v0 g( w
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    ; ]2 Q, W' T3 C" R$ O! s* W6 `1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    0 e' I3 L( b, X% g. {2 W' `2 d7 L/ f8 m6 N. ^
    2)假如你使用的是三引号,那么你也可以这样使用:
    6 |5 R* v0 C/ O3 G* a4 O$ h1        deleted = cursor.execute("""
    - [! u1 T6 O% M2                                 delete& A; `; D2 W" M- k( N, p
    3                                   from products
    - v  X# W3 I$ T2 R4 a  U' W5 c. n4                                  where id <> 'pyodbc'+ R4 F  ^4 G+ A# y
    5                                 """).rowcount
    & M- o% i+ D! b; i; q8 b. G/ a0 a; ?& E8 R' b/ \7 x
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    5 ?/ V8 Z/ G& I1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    - j* R$ n4 N6 v8 S' C8 ]* z5 |% }2        print '%s users' % row.user_count
    7 t1 v7 L$ @$ N( _0 a% a/ E
    7 C! [5 \# G1 i1 R: n4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。6 @4 H* G+ g+ U# I
    1        count = cursor.execute("select count(*) from users").fetchone()[0]/ M8 y( |" s( Y( k" a0 B% [& [; L
    2        print '%s users' % count
    : s. u- O9 d$ C3 w2 r
    % d) ~, q# k8 r0 V# J如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。; U7 r" t* z  b
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]4 A6 Y, N2 G5 k+ z

    : g$ d4 X3 Z; U  x4 D6 E9 p在这个例子里面,如果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-11 04:18 , Processed in 0.373042 second(s), 50 queries .

    回顶部