QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6151|回复: 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、连接数据库6 A9 L' P) e  y3 B2 H

    ; H4 r6 ^* I6 c1)直接连接数据库和创建一个游标(cursor)
    % c5 e! t& y1 }0 J; a6 H' i1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    & X5 U5 c+ Q! |7 \( g2        cursor = cnxn.cursor()
    " n( Q* K4 b* `- {" [5 B5 D. U# v9 l9 @$ Y0 l6 [) L
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    8 W3 X( n1 m. s  I. w1        cnxn = pyodbc.connect('DSN=testWD=password')( i6 v$ p1 \/ e0 h. _1 D; A
    2        cursor = cnxn.cursor()6 \+ A- [" I3 t) y6 E3 l

    2 k( E1 S/ W; K: O+ ^- I关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节4 X0 u! K3 \! s  S7 [4 I' z- Y
    ' Q% ~+ f  s0 o% l6 I; G8 \
    2、数据查询(SQL语句为 select ...from..where)! t& X( l. B) j1 t" y4 e( m2 I0 d9 a5 N5 D, `

    & J1 g/ ~7 e% ^+ Q1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。+ m# S0 T' W- _! }2 j+ D. z
    1        cursor.execute("select user_id, user_name from users")' T5 T) I) `8 \, P3 n$ Q7 M
    2        row = cursor.fetchone()  N' [) x0 g; B/ t- k
    3        if row:* M) Y3 P7 l, e2 K2 K8 v  ^! f
    4            print row
    / x7 R' @. t6 H! y: T3 Q' c) [) P" ]( ~( ]" n) X
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    % Y- }( Y7 |8 p7 a" P4 r- U1        cursor.execute("select user_id, user_name from users")
    7 M1 W1 W$ r1 Z* Z+ T6 k1 T2        row = cursor.fetchone()
    # P" D3 G9 L3 L0 T3 x3        print 'name:', row[1]          # access by column index
    ! x, ], ]1 T* l, J4        print 'name:', row.user_name   # or access by name2 K( f" X% U" e5 J
    % i( d7 |. @1 s# g3 G; Q$ [& _
    3)如果所有的行都被检索完,那么fetchone将返回None.. ^6 H1 w. X  L+ f
    1        while 1:
    & d% [; r: I' d( h: x, a$ s$ I" c5 n2            row = cursor.fetchone()
    3 w. Z7 s. l: P/ d2 F3            if not row:/ |" o- ]* T1 J- e, U
    4                break
    0 B6 S/ V& Z; `2 @" N5            print 'id:', row.user_id, K4 P1 ~8 V1 d  R9 C2 n2 ?

    ; p  t+ U+ q; ]4 s4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    " J; [+ D6 l( t5 O4 O1        cursor.execute("select user_id, user_name from users"): \* W" T+ S- P* u
    2        rows = cursor.fetchall()
    % h$ Y; A9 ~- u8 ~% E3        for row in rows:2 `- \- B4 i( _, T& ~4 {
    4            print row.user_id, row.user_name/ V) k' L; `: n3 w

    % Y- g# R4 u8 d& R7 R4 f7 d* }! E3 h5)如果你打算一次读完所有数据,那么你可以使用cursor本身。8 _& ~9 {0 A5 H- H, f: f
    1        cursor.execute("select user_id, user_name from users"):
    4 G! c9 K* ~. u* S5 V' C; J  W2        for row in cursor:8 j5 R5 Z  U( q0 d* O3 f9 N5 i- K$ k  s
    3            print row.user_id, row.user_name
    2 ^, u4 U6 |# ?6 Z3 H# S  a5 K- p2 w2 p6 q6 w
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    ( V8 w, X% ]( k5 W1        for row in cursor.execute("select user_id, user_name from users"):0 p8 v6 O4 R7 L' r4 f
    2            print row.user_id, row.user_name
    : [1 _8 b8 H5 R% d; G$ u3 c3 [3 D, r' r7 @/ t+ _$ O$ G- ]
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:
    / h; o! z  ~# V4 y% q4 D; T# r1        cursor.execute("""! J& L$ @& G$ d/ P/ ]% |
    2                       select user_id, user_name( V% u$ x9 D3 |0 v+ A, f0 q7 f) ?1 S: z
    3                         from users! f7 k1 M* M6 S. [# {8 V  x
    4                        where last_logon < '2001-01-01'# M, T  O! M" ?! ]0 W9 P
    5                          and bill_overdue = 'y'
      g1 n4 L, U% x  B! q6                       """)/ d" w! h% C8 ]+ z$ g% z: g
    / o1 B- @1 Q$ {
    3、参数6 M- P" M1 g: a( Q! D0 z

    ) W% s  [! {! f& |" ^/ `- f7 Y1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    " c' M0 ^9 P8 `& L" l1        cursor.execute("""
    - i7 n0 U1 E# y0 m9 N2                       select user_id, user_name' o) I. T/ X! f2 L' M, v
    3                         from users4 T1 |, O$ M3 X/ p+ w0 z
    4                        where last_logon < ?! D* o9 [( T7 C" W
    5                          and bill_overdue = ?# y/ d7 u' P/ a; I+ @1 |
    6                       """, '2001-01-01', 'y')% a# |* b- k& d6 ~6 E3 ~9 ?

    9 {7 a/ N2 F4 {: D) B这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。5 o  G7 r8 n3 M% m7 ]

    1 V; R6 B" S, e* [% N3 f7 z3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    . Z$ T6 E4 r. j% F' \1        cursor.execute("""
    9 Z! \* H* P: V( z9 C* p- v# u2                       select user_id, user_name* `6 U, s6 l6 f; `& J
    3                         from users7 ~$ j3 v" Y0 h8 `
    4                        where last_logon < ?
    + x" B# r/ I; `  u6 H7 P* S5                          and bill_overdue = ?
    9 u6 c: Y0 V6 @7 L* V* G9 G5 p6                       """, ['2001-01-01', 'y']), c+ g7 e" m% u% v; z. T$ ~6 b" O! @# }

    7 b' T. t; \! }% g& _, A1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    ) B4 ~! p) i1 [; D9 j% [2        row = cursor.fetchone()1 K$ y; V& \0 V% R3 Y
    3        print '%d users' % row.user_count
    : Y/ w! h1 k2 g+ w# k; t; F1 c# W" @! M" _2 Y. ]; r  y! R
    + {9 k8 t6 ?! Z: Z; o! E
    4 R! g* t8 j7 Z* H% A/ O0 }5 F3 ~
    4、数据插入7 P. L' |3 J) C: E& U2 Y8 A
    $ q, P( l! [8 G6 V: Y" e
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。! ]2 @' R  i% ^9 y9 }9 t# o) F
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    8 ?3 F% u: L8 y( H6 L+ Q+ F2        cnxn.commit()+ L0 ~6 r0 b+ N7 }7 s

    0 o  u7 r) D# m$ ?# {1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
    ! L; ?/ S. r- D( U: y& m2        cnxn.commit()
    ' N, V. g& X# z  K4 |8 O/ K/ [/ ^% ?. O: ^( F, N# L  d- m
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。! X0 L& v9 x( z: [: F
    2 }# @6 h% L0 _, _2 T
    5、数据修改和删除9 A. D' L! J9 M
    5 g' [: T. n4 L3 P2 R. o4 B0 r" u
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。9 H2 y: Y4 R! {7 y8 e8 E  L
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    ) x' b; ~7 _/ M1 b! K2        print cursor.rowcount, 'products deleted'
    8 C* S& n* g) G  `3        cnxn.commit()
    ! {) z$ V! V- g1 \; H/ }  [& |: A8 f
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)$ U9 p2 Z0 U, }0 W
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount6 K! p+ {" y8 x1 s
    2        cnxn.commit()
    * v( H6 N! b) X& F8 u; L1 h( t
    * s. ~2 _5 ]' O2 h$ W同样要注意调用cnxn.commit()函数
    9 [) Z& l& A5 G* z$ N1 {
    - v4 F6 C  Z: N: ?& J' k- m; s! O6、小窍门5 }. t. k- H8 Y; E
    / Q9 O$ e: `2 k+ Y3 v& S" b. ^/ r
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    9 L+ ~* q- l5 O& n1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount5 B: ~3 G: X3 O; ~7 O: Z
    % b  x" X3 D# }4 \+ p9 C" }4 ~3 k: K5 ^
    2)假如你使用的是三引号,那么你也可以这样使用:
    5 ]; r* t& A* h3 S1        deleted = cursor.execute("""
    - c' ~- |% [/ ~& p% t% O' L, q2                                 delete
    ! P# Z7 @) {- _; v* r. O8 I$ K3                                   from products- ^" X: e9 q2 W* v& {& ~
    4                                  where id <> 'pyodbc'. w) L$ c# U- a+ `+ r
    5                                 """).rowcount& H' y) P0 D. u1 W% K& b1 Q0 i* s
    7 s( m. c; o5 p3 r9 ~
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)% O) z8 @: \5 a) y" w( P6 j
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    % K, h) H& a8 s7 H8 x/ _# Y% F- m1 d0 r2        print '%s users' % row.user_count  Q0 n% s) b7 p1 l
    4 V5 Q6 Z/ N) U; Y
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。4 @: L" r- Y) ^9 i. \
    1        count = cursor.execute("select count(*) from users").fetchone()[0]' L6 s. W" A: \. B
    2        print '%s users' % count9 f# h& a0 I$ v& k# O

    4 P% d4 b" i3 w# g: S如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    ( O5 r1 [* O5 S2 _8 `/ F+ M% z. _1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    7 ?, g7 C! i9 F- y/ d) z7 o) W' p) \  a2 c
    在这个例子里面,如果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-12 22:03 , Processed in 0.388573 second(s), 50 queries .

    回顶部