QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6179|回复: 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、连接数据库0 q2 N7 f5 d: l$ W
    , }2 A3 \6 Y$ k# a( J8 ^% r# `
    1)直接连接数据库和创建一个游标(cursor)
    : P' d0 b9 h; M& w$ z8 m& {: M1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    - N3 Q/ [$ Q. l# ^7 D9 t2        cursor = cnxn.cursor()  p7 J# i# O9 B3 ]1 i, Z; v% _$ {" I

    ; \  F$ ^% a5 w8 y3 |2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。3 l0 w1 d% R& V# m. Q4 m. }
    1        cnxn = pyodbc.connect('DSN=testWD=password')
    ( g( G3 }0 d; T2        cursor = cnxn.cursor()
    " S+ |# g4 @; T4 I. Q" ^
    6 }/ j! a% w. h/ j3 U; b关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    $ a) R3 `0 {; S  B# z2 e% s' p
    . t, F9 S% ~  x9 m2、数据查询(SQL语句为 select ...from..where)7 m8 L) G7 Y1 c4 O1 e

    7 y( V8 l3 Y5 ]+ F$ E/ Q1 Y( i1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    0 K; W& I6 \9 T1        cursor.execute("select user_id, user_name from users")
    3 L( J( Z( }# |7 `8 O2        row = cursor.fetchone()' [9 n8 U6 \2 u  K. g
    3        if row:
    3 T* e) K7 J8 @- F6 S8 U8 n4            print row% L; @% }. Y9 m- z7 T

    2 |8 K) b& |8 S8 D" ]2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。. y4 U' W& F7 l
    1        cursor.execute("select user_id, user_name from users")1 _# F( A) l  K6 X4 [
    2        row = cursor.fetchone()( g" [7 J2 L" P$ `  o
    3        print 'name:', row[1]          # access by column index2 m: X1 u% x& R. }* S9 c  L
    4        print 'name:', row.user_name   # or access by name
    ! {4 }* e* Z0 m" u$ c" q% d4 E: P3 p3 d9 K- ]) p$ \$ J: B9 O
    3)如果所有的行都被检索完,那么fetchone将返回None.
    3 \* X5 z9 x( Z. [1        while 1:
    - B! d$ s7 S; h2 ~% C2            row = cursor.fetchone(). z- s, N- w5 Y8 h
    3            if not row:% i2 F. W* Q3 O* y
    4                break( K7 a+ _. y3 z4 E7 b  \
    5            print 'id:', row.user_id
    0 A+ g* i; w0 g  ~" g3 w! Y8 H5 p) l# D
    / K4 q! ?7 T* u# q. k8 q0 P  N0 y# Z7 @4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)! I3 n5 ]. q* V: h- U, T
    1        cursor.execute("select user_id, user_name from users")
    0 d8 Q# f0 \5 O! A/ h7 a% o2        rows = cursor.fetchall()
    4 m; K7 u$ L( B) t& r* T3        for row in rows:
    / I9 @. \; p4 I. \: r4            print row.user_id, row.user_name/ l0 F$ \& a, S3 h" q7 @$ [

    : |; ^5 h# N7 C) e, c0 j  d5)如果你打算一次读完所有数据,那么你可以使用cursor本身。9 z) F& ~8 Q5 A' f2 \; X
    1        cursor.execute("select user_id, user_name from users"):) y7 ?' E; |, K9 Y' V
    2        for row in cursor:
    ' ~9 y" X5 @6 l6 e0 m3            print row.user_id, row.user_name2 C# r9 e9 f! D9 H
      o0 o4 L+ R9 C5 n0 e
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:1 t$ y3 O& K. f+ H1 E0 X. w  z" T
    1        for row in cursor.execute("select user_id, user_name from users"):: R6 v5 X) z) Q* ^  f$ ]+ W$ I
    2            print row.user_id, row.user_name" j- H4 G/ l% D$ v  A- v

    3 V2 s( O8 B8 m! ?' K7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:& C: }9 [1 K+ j: j+ v7 N0 `
    1        cursor.execute("""5 P4 r# y! _7 m) t( c/ J5 `
    2                       select user_id, user_name, [) w7 a0 f/ g
    3                         from users
    & T  r! e) X" }+ x5 t4 o4                        where last_logon < '2001-01-01'6 U" E/ }* i$ {* ~6 X# I0 L
    5                          and bill_overdue = 'y'
    * R  C8 V0 Z2 d3 j# i8 W3 m6                       """)
    . a0 J, |0 i: ]  l) v8 L. `( z( Y4 Z& h9 Y
    3、参数$ ^& c9 l$ U" d" `# {

    - o& L: V- z( i* W- b1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    ) t& Q8 C4 W4 `! l' H( m# p1        cursor.execute("""
    $ N1 w2 f# Y" e9 I& l3 u$ z( O4 y2                       select user_id, user_name; j% [; P+ L! i: V% c8 P$ d0 V
    3                         from users
    ) W, Z4 z4 u1 b4                        where last_logon < ?
    / Z) P  H# ~" _# |; o1 J% n$ L4 V5                          and bill_overdue = ?
    $ b3 @9 V# H4 p' y2 `- n4 Y& A/ \3 l6 L  y6                       """, '2001-01-01', 'y')
    4 i$ \3 L6 N( F, T
    . h7 n: w0 s; I这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。8 O) D; y# A4 ?1 J4 Y; W
    % L/ W" r+ O0 Z8 P  F3 u) t' i: H
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    , R- X, t. w6 @- O( a( c" q$ W0 L1        cursor.execute("""
    ! x: J" Y. F" _/ K2                       select user_id, user_name( c, R! A% \7 m2 ~- W/ n
    3                         from users
      U0 J5 _: J4 z# a  e! Y1 f1 [4                        where last_logon < ?
    ! R! r) i8 {5 u4 G( V2 L! z5                          and bill_overdue = ?' W( K7 x. o* f1 v7 p! }% v
    6                       """, ['2001-01-01', 'y'])2 s$ w# H" w% J  l+ R# G
    * l! e% L6 f$ K. C
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)3 W. k% e+ s. {3 x; F9 j
    2        row = cursor.fetchone()
    ; n) S) ]' d$ _8 [! m0 H- _3        print '%d users' % row.user_count
    ' D; P8 e7 r& F# @* N4 Y5 D5 `; [0 B  o7 D, O

    : i2 h& S* F: w+ p) M& i
    . E2 T7 O3 e2 d" u7 f5 f1 x  {4、数据插入
    & t5 f7 e9 i3 q- }( k( L, h) ]$ S& F6 X8 ]5 H9 |2 g
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。
    * l! W. G) ]( x2 V' l2 r# s1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    ( \  U2 H& D- v& ?5 a! d! [, y2        cnxn.commit()% z9 ~9 o! E2 T: i; O. }# M

    , i0 i3 u; u/ e- J- o, ^1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')' _$ H3 m$ h1 P4 H% t' a$ R
    2        cnxn.commit()+ ^5 A/ N! _% j
    5 F5 A* g6 _" K9 k# g2 A
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。/ s7 j' p2 U, s8 D
    1 r! B. F' F4 p2 L8 K
    5、数据修改和删除
    5 \% V- Z+ t3 K# p3 L' X$ T+ i- {. t: `) [# Y
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    1 S; C, R" _1 y6 j2 y1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    / E% S" c1 r7 o. Y- l2        print cursor.rowcount, 'products deleted'
    / q7 g3 U9 G  n) G; @  u0 u3        cnxn.commit()
    6 ?3 k0 _9 U- y* W/ \9 @' C# ]# d3 ]# x
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    8 b' T1 P+ S5 m. D% c1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount, [) @7 G/ m& Z6 ~
    2        cnxn.commit()0 L" _" ~  _, k
    / R* Q! v# w( w$ Y. ^( p, X2 M) B
    同样要注意调用cnxn.commit()函数
    $ m8 e, q$ V7 _
      l. ?" t+ A3 b* b6、小窍门* |! [) T  q% ]$ a3 Y) G

      d9 j, I+ V% e: q# m( p7 h1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    % J  w8 V9 ^5 u! d4 u* R$ r! G/ t1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount. L! O4 K# m/ U( u+ }: G9 v4 o+ T' {

    4 u2 w1 M$ c- M0 B1 A' o8 n2 ^" p2)假如你使用的是三引号,那么你也可以这样使用:4 D! Y4 \1 E5 {- K
    1        deleted = cursor.execute("""
    & }, @1 l) Q! q8 L( t4 g% H2                                 delete1 a9 o% p7 a* X; Q
    3                                   from products
    - J9 T( d* H: ?5 @4                                  where id <> 'pyodbc'
    / t; w; J; b. T- x6 g5                                 """).rowcount
    6 S5 P! @; P2 a2 g- c; b# c: M& G8 F+ C" Y2 l
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
      o3 J" U! ?6 @! Z1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    % W* l' h0 }: J9 i' @3 K) C2        print '%s users' % row.user_count
    * E% g1 P- @) {# O* w9 z+ u0 S7 I1 i  U! x2 A! z% p
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。5 b+ F) Y8 q' X; v- T! ~$ X
    1        count = cursor.execute("select count(*) from users").fetchone()[0]5 H  z+ \) [! v- x
    2        print '%s users' % count
    2 f1 P, ]6 i9 g" [; {3 G* \1 j3 d$ D* z: Q$ d
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。5 m  k: |1 A0 x3 o2 F
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]8 U  g9 t' V0 e+ L/ a0 m4 b
    3 E$ R1 w5 z% n6 E
    在这个例子里面,如果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-5 17:43 , Processed in 0.474504 second(s), 50 queries .

    回顶部