QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6269|回复: 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、连接数据库+ E# S' E  X- v) ~  ]$ |" t/ t

    " p/ s; g! o- N4 v7 M1)直接连接数据库和创建一个游标(cursor)3 U: l+ }9 Y  b9 m
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')2 R- ]: d& g) a! s3 J
    2        cursor = cnxn.cursor()
    7 @* Z) V* h- U
    5 P/ I' y  Z0 t/ P2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    ! w$ ^( Y* P1 Z8 Y% b5 B# ^1        cnxn = pyodbc.connect('DSN=testWD=password')6 o- b  F" T* f8 |& ~
    2        cursor = cnxn.cursor()
    - @0 A) E$ C- y( w
    4 E' y9 a1 S+ [$ @5 P9 \关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    % G, |( ~; l4 ?
    ' q* h5 f0 V/ C3 U$ O6 ?, e  P2、数据查询(SQL语句为 select ...from..where)! y; N- x% F4 ]3 y

    8 h& Q; M4 a, u0 a& w* S2 b1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    9 ^8 q! U7 B7 s# S1        cursor.execute("select user_id, user_name from users")
    3 ^5 [0 k- A* I$ q: w/ S2        row = cursor.fetchone()# ?: p5 M1 m. E8 p0 |0 x
    3        if row:
    9 H2 ]4 g- ?! J: p4            print row& ?* Z4 r3 H: ^5 R4 K( i
    : w6 V' z) O$ z8 P( \
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。+ {; ?6 O, m) e  T
    1        cursor.execute("select user_id, user_name from users")
    6 s, S: o2 g+ l' M. z2        row = cursor.fetchone()
    # O7 k1 ?. u) I8 N3        print 'name:', row[1]          # access by column index
    % q, Y. p" T2 K. `# _2 S4        print 'name:', row.user_name   # or access by name" d2 J, V3 O; G% i
    4 K) F/ v! h6 T& R+ M" D
    3)如果所有的行都被检索完,那么fetchone将返回None.  ?" X, X7 F" R& c
    1        while 1:& _  N0 w' B9 p1 H9 r% a3 K
    2            row = cursor.fetchone(). d7 y$ x5 g2 W9 s: Z
    3            if not row:5 ^; b/ h4 [( p' A5 [
    4                break: W6 H2 s' h3 ^2 t
    5            print 'id:', row.user_id
    8 g) V! t. v! c4 o$ D; s
      y, J4 E! A) |" ~6 R3 ~4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)! |1 h' M5 K* u1 \. S; R) R! ?  d
    1        cursor.execute("select user_id, user_name from users")# {0 ]$ g7 U: W3 B1 \- L8 d7 B+ t0 V
    2        rows = cursor.fetchall()% l" c9 j& u  R9 o1 F" B4 n, D
    3        for row in rows:
    7 ?' @3 |8 ?4 x. K4            print row.user_id, row.user_name
    . P( [7 ~% {/ l) A- k  w6 G. e6 u: n% O5 Q  }: `2 l
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。
    . r+ s0 t) i  }3 q2 N) E3 _1        cursor.execute("select user_id, user_name from users"):- t+ c6 I) L) U* q! _
    2        for row in cursor:( s6 q1 X0 O* H4 e- l) E
    3            print row.user_id, row.user_name6 _- b/ L+ I( G
    / r6 G0 x, S' q( C( K
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    3 E$ w( i8 l# }1        for row in cursor.execute("select user_id, user_name from users"):# n: T  b& i" d) F
    2            print row.user_id, row.user_name0 ?  ~  l0 t, k" u
    , t4 w- U9 ^8 v8 k5 ~# S7 @
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:% v5 ], l! m$ b' `* g
    1        cursor.execute("""' |; Q  [$ H4 e" r9 _7 m
    2                       select user_id, user_name$ b$ K% k- p% i& c8 P
    3                         from users' a# j# l7 ?/ l9 b. `. U( |
    4                        where last_logon < '2001-01-01'" U0 e$ A  Y0 Q! W
    5                          and bill_overdue = 'y'
    ) Z$ R0 u% j& w6                       """)
    ) B( i8 B1 \0 h! n/ A4 j2 N( \' r0 [& y( S! J7 P- }
    3、参数7 b2 v* L1 o; e9 h& W

    % u( A: I/ j2 ^( `. l) c1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。4 `( ?3 ^7 h# _$ `7 {- n
    1        cursor.execute("""
    9 ?4 k# n0 R. E3 f2                       select user_id, user_name6 Z) S. |- q5 ~
    3                         from users
    : h  g' ~  l: i7 L1 ~# [/ B& e4                        where last_logon < ?; Z  r+ A2 p9 C! o1 s" s
    5                          and bill_overdue = ?' g2 S  J& m1 t
    6                       """, '2001-01-01', 'y')# z5 Z+ B. i5 `  R% \
    ' C* a2 E2 F6 O
    这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。9 A$ r0 p8 R! N- H3 C" T2 u

    # d6 J8 @: C8 j4 e& x3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    * J% X* Z. F: d: |: V" u5 ?) d1        cursor.execute("""
    % R- g- y4 h$ V2                       select user_id, user_name% y* s6 L- e6 f6 O2 s# U  u
    3                         from users
    9 P2 q8 E# X+ l' B* d$ K4                        where last_logon < ?
    : A, C+ a# `9 v& l9 L6 C" d4 T' G5                          and bill_overdue = ?$ W. V+ f2 _5 l5 Y; S: X
    6                       """, ['2001-01-01', 'y'])5 i: P6 V$ V; g5 ?' i% ?2 I
    " o! G. _( Y( _/ _; {& f' r
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    ( Q0 h  z8 q* B1 Q; M+ b) L+ l2        row = cursor.fetchone()9 ?: Q9 t7 ]) \  H& K
    3        print '%d users' % row.user_count
    / X/ U/ ^# w6 h9 H- Y) t7 P: z) m
    / ?1 l. ]5 j, V- x; p 7 D( U6 \2 l$ g, Y

    3 o9 S  w. b4 U! A9 B4、数据插入
    % J. v) o- t( z. p: r: Z  |; E; I" R2 n9 B
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。: v- S6 {+ h; q) U4 J: |4 Y0 s
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")7 j5 D3 Q1 L& Y
    2        cnxn.commit()
    4 e; ]2 o+ ]9 r% \7 U0 Y: ]$ Q/ R0 N  ^; g1 j$ \
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library'); x, R  F8 E0 t# ]0 A+ o
    2        cnxn.commit()8 h; K/ C. [) g1 ]
    ! l( S- S% U; @( s1 }1 X2 w
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。/ d$ L3 n/ H" V! L! ]

    0 v9 e' W3 X4 }* j; {# [5、数据修改和删除
    1 Z* u& k! {7 k
    " ]! Y0 J/ P& h2 m1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    ' E3 E$ `3 u" t8 }- Q) F1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    ' X1 E' N7 n# c' V) P& v2        print cursor.rowcount, 'products deleted'
    3 c9 l4 E6 u5 i  A: K( P( ]. T3        cnxn.commit()
    $ x& v9 X, E* _* m/ I+ D1 p/ ^+ X, ]0 N! l# F* J% E; e' c/ b
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)2 m  \1 R  T" D  `# Z
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    & R& g* D9 A0 \( c4 N4 x  a# |2        cnxn.commit()
      T% W5 F6 e9 z9 y: f7 p- c" ]3 A2 t5 w0 r
    同样要注意调用cnxn.commit()函数1 E. l& i' m# J! ]$ _5 e& T+ a

    ' o$ V( K6 R- F2 Y9 S; @6、小窍门
    $ q4 F( {- h7 Y! J/ [6 `# S1 [: [1 e# B$ |  h5 R+ z, o1 L
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    - |6 b$ U3 k1 |1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    * G- V( j6 d2 c' x
    6 i1 C: f$ v3 a2 e6 H2)假如你使用的是三引号,那么你也可以这样使用:
    6 @! Q* j6 L# P6 M6 |1        deleted = cursor.execute("""
    ; q& S! n) \8 @2 i# t4 d2                                 delete
    : p9 a3 X+ B4 |" h3                                   from products: y. o9 z' k1 ?7 A
    4                                  where id <> 'pyodbc'. k- |/ p: l1 a( c# M5 t4 H
    5                                 """).rowcount$ R9 }) R  j( o
    ! S" V* t$ [5 J$ V! y) \
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)3 s" z1 d9 D9 D4 a- W: g
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()* u. ?5 X- A: n6 C2 V" r6 e5 m5 i
    2        print '%s users' % row.user_count
      o( u  |: v- ]/ _8 K* [8 H( w6 d# }
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    0 p" v  Z- s% Q- v' p6 e. u7 k$ b1        count = cursor.execute("select count(*) from users").fetchone()[0]
    - |3 q) m  W9 i2 C: [# {! k. J2 n2        print '%s users' % count0 I8 i0 T" l  \/ o% r
    7 |% [6 _" w/ L- P/ K* G
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    $ c) b: \8 T- y% A0 p1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]3 L+ u2 ]0 v- e0 ~  m" E  q. ^4 W
    0 `/ [3 C2 G3 r! M5 F
    在这个例子里面,如果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-10-9 02:29 , Processed in 0.414064 second(s), 50 queries .

    回顶部