QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6171|回复: 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、连接数据库3 y5 H8 Y  i" r) X3 |

    + j7 v# k9 n6 {$ a1)直接连接数据库和创建一个游标(cursor)3 W% z% B) ?$ m: m7 A
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    / y( z$ Y6 M: U5 B+ ~2        cursor = cnxn.cursor(), p$ \% o/ e9 }' r, x
    ; O2 I2 Q: r: u1 S5 U( M3 k
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    # W8 ~# {6 Y% \1 t1        cnxn = pyodbc.connect('DSN=testWD=password')! E. b  A3 }& E! I: Q3 Q; Q0 ~
    2        cursor = cnxn.cursor()
    * R; f6 ^" d- k- ?: g& K" t2 w( U4 v/ b* q5 E8 {' P
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    " I/ ^/ L& S8 N2 e( k' _) h+ r7 H& q" l1 |
    2、数据查询(SQL语句为 select ...from..where)
    1 V4 {' U! X* ^) f1 _1 b% S- r  {; |8 @0 a
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。# w6 M9 p7 U' y# M, t% z
    1        cursor.execute("select user_id, user_name from users")
    ) M* W, F7 r" G. L. j2        row = cursor.fetchone()
    7 `: L* x' X4 F4 ^3        if row:7 q) J; e, n/ u  C8 C$ b
    4            print row
      y; m1 \0 c0 U4 a4 v: P
    2 L+ u& ?' C4 ?" \5 \" p5 N7 [2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。6 U% p! f, U% y1 Y; e) F
    1        cursor.execute("select user_id, user_name from users")
    % {) q; R) [. J7 b4 u2        row = cursor.fetchone()
    , l$ V# h- r0 [3        print 'name:', row[1]          # access by column index
    0 p! g; S. l+ U6 d) V4 A4        print 'name:', row.user_name   # or access by name$ `, J' Y1 b$ S
    " d' r% E/ t5 j1 _+ h0 B8 D: L
    3)如果所有的行都被检索完,那么fetchone将返回None.* z- D4 X- p; Z8 A! C/ y
    1        while 1:, @$ j; V7 c. J* ]. E
    2            row = cursor.fetchone()
    / [4 `7 b, Z" i, e. d5 l3            if not row:
    7 h) s1 g3 S$ a# t2 z- y  x4                break
    ! ~& E: f/ R5 W3 \/ _9 k& z0 Y7 [& }5            print 'id:', row.user_id% t8 W0 u8 L/ b* k4 j! N
    * j$ u  u9 |6 n1 \3 ^& a- a
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)) q7 |! d& J0 K0 }4 m
    1        cursor.execute("select user_id, user_name from users")
    ; U" l0 o( F- @! U2        rows = cursor.fetchall()
    % [8 b4 i4 G9 T6 G0 l3        for row in rows:9 G3 T  |1 K. X. s" z8 x9 b
    4            print row.user_id, row.user_name3 g/ C" r5 n9 w- B. a& R

    4 n/ t4 F& j, h% N5)如果你打算一次读完所有数据,那么你可以使用cursor本身。2 x0 g5 u; m2 w: k6 V2 h0 f9 X
    1        cursor.execute("select user_id, user_name from users"):
    9 p- u7 l1 o! e* m. y2        for row in cursor:7 o, h! m$ q# E6 \
    3            print row.user_id, row.user_name
      J: K( ^# f  }" \
    1 G' B* H, j/ L6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    * o3 r9 Y7 \$ P6 K1        for row in cursor.execute("select user_id, user_name from users"):
    . u& _% x1 P, N/ e; J4 s$ N2            print row.user_id, row.user_name
    0 c. P: @! X" ?  J& V, P. E0 y
    6 r; L4 T6 w6 X. Q9 L: {2 x* p7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:+ l$ |( _4 S: k# I2 \9 M) n3 x3 I
    1        cursor.execute("""
    6 l, _; R* m+ r& F9 @2                       select user_id, user_name( F% P* {1 W" B1 S# D; V0 j
    3                         from users
    9 D5 L( e4 a! v) [/ b8 h4                        where last_logon < '2001-01-01'
    - f# b' \1 t7 O6 J. }5                          and bill_overdue = 'y'6 k# {: c8 z/ @
    6                       """)' p/ O2 a6 q' t

    ( p' u1 h0 ]4 n6 Z) u3 r3、参数
    2 |2 ?) k  u0 U; F
    / R, L" L6 e9 [+ e9 q2 J8 S1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    ( {  K2 d( G1 L6 u1        cursor.execute("""
    ; q* K, `% ^/ E0 ]2 T$ v& m2                       select user_id, user_name
    1 B7 M$ @! s, b3                         from users
    ! L! Z- `( M2 X' Z4                        where last_logon < ?
    ! e  c" |  o9 r2 E& g! k+ ^5                          and bill_overdue = ?6 h) Z% |0 n- N5 C: d# `
    6                       """, '2001-01-01', 'y')
    $ B& M- S4 C, N. T
    3 m1 W# j, ^' p: {) [9 X8 \  q; w这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。# |# o) j6 g0 y2 |2 `

    8 r& e: |+ y2 i7 j3 b3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    / N& T" L1 ]8 n# V7 `1        cursor.execute("""! c% s) c" @$ O# }, K
    2                       select user_id, user_name, ^) D* I" ~5 E+ V# C0 U
    3                         from users$ x: Y7 `7 z. E/ X4 {/ I4 \# ~5 Q
    4                        where last_logon < ?8 X# v3 d( n- Z4 j$ c5 r$ l
    5                          and bill_overdue = ?
    8 s9 g. N* {  t5 @) @# b6                       """, ['2001-01-01', 'y'])* q  p; t, K7 ~; A/ `& ]
    " q4 F+ ~5 N' K
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)$ ^# i6 ~) L# h
    2        row = cursor.fetchone()& M5 L  |8 c6 u/ T; I
    3        print '%d users' % row.user_count
    2 N7 r/ c" g7 P7 m" x8 c
    ! y4 F! p% a( ~3 i7 ]( d3 g   U8 `+ _4 g. t# ^  `! Y2 T' O

    : ]3 Y5 a. [" p7 |6 i, w4、数据插入
    $ d8 R1 A, f* ~8 y( p" Y& J# i, _# O0 X4 f3 g3 V; k4 z' O1 ]- U
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。* e2 z9 O* H7 R4 ~
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")7 o3 w6 |* Y2 U6 q7 |. ?% n' E. A! s
    2        cnxn.commit()
    8 z+ F* \, U0 T$ L7 U( d* r7 N# F, H% Z, [+ }! V" R, O: Y
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
    , h% l: r4 n+ {1 U  c0 D) _2        cnxn.commit()
    * u3 _; T) f& ~$ w
    , J# N* E" j5 i. b注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    + N7 A1 P9 X$ ~# e  b8 N5 g4 S
    " |- ~1 q( b* y0 k! B7 E7 F5、数据修改和删除
      U& w' @6 h* c$ V1 O
    8 U+ o4 R4 r/ e) w& t1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    + Z' t8 w8 t. u1        cursor.execute("delete from products where id <> ?", 'pyodbc'); E; L% j. ]0 n3 F+ |' r; H
    2        print cursor.rowcount, 'products deleted'
    , t8 q  c/ y+ u. l3        cnxn.commit()
    , u* X: C- x0 V2 q6 t$ \' J
    $ [& a- D3 I/ f9 R! a3 s2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)' J6 N0 j: o. ^! |1 R
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    3 _& Z: n4 O$ N+ E: h2        cnxn.commit()5 I* d6 O: r3 x5 g
    . {7 S$ s' H, T2 Q& g" a
    同样要注意调用cnxn.commit()函数
      L3 c! Z- `; q3 z1 Q) K/ Z3 C* I! t1 D, R1 |7 {
    6、小窍门
    1 q, {6 r$ A. o, ]! [# h/ X) u
    7 ]* _* e  A4 s; d1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    $ R; R8 o! Y) F# u8 U/ J1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount- D' M- a9 y& s$ N( H7 g4 {; p( H
    ( U5 H' N+ q+ x  ~% s5 h& \
    2)假如你使用的是三引号,那么你也可以这样使用:" w1 N/ \/ ^0 a! d- x: _% l$ H
    1        deleted = cursor.execute("""
    . r: ~  d& d2 b! g2                                 delete
    * `9 Z/ n3 }# N' l3                                   from products/ ]! J6 K2 i0 L
    4                                  where id <> 'pyodbc'
    . w7 Q# T/ j) f; G' w7 S5                                 """).rowcount
    * @( O$ N9 l. f' M
    , r- S; G5 x/ E" H3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    : j8 f* U6 F+ o1        row = cursor.execute("select count(*) as user_count from users").fetchone(), \6 h- x3 E3 p' ?. W; w) x
    2        print '%s users' % row.user_count1 O# d5 T7 x) W8 c  s5 B
    * _* k9 D: i7 x3 [3 ]
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。, p, ]% b& ^4 [. h' k' X# n* f6 x. H
    1        count = cursor.execute("select count(*) from users").fetchone()[0]' z% l9 `5 A+ n% L
    2        print '%s users' % count6 O8 K7 F) i8 `% N' ^& U5 M

    - W, h0 [8 o- J" J* v6 r. G9 R# O如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    $ X. n0 G1 h$ y, t' j2 b8 P1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    2 `2 X# Q0 s& h' p0 _* B1 I. t% I
    1 G9 j+ e4 e0 m' r7 h, n在这个例子里面,如果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-8-4 16:55 , Processed in 0.435783 second(s), 50 queries .

    回顶部