QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6175|回复: 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 s$ h/ v7 Q, f
    " K$ G- n3 s$ W
    1)直接连接数据库和创建一个游标(cursor)& ]. x5 F5 U2 T! z  }' n
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    , |. F% B1 y! h; U( }+ `2        cursor = cnxn.cursor()3 R% n0 i# ?, Q5 R' m& D$ g

    - o* z+ g+ Z7 X) H8 T5 g2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    " N. v% i* O5 i  a4 Q# E1        cnxn = pyodbc.connect('DSN=testWD=password')/ T( Q7 s9 U! ?) Y# N* l
    2        cursor = cnxn.cursor()9 F1 S, Q% t* Z* h# H6 w
    9 c" A2 x) S4 x/ O$ I
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节* @$ I% o7 x' {; t% `# d

    , S+ Q3 f, V; G6 q. S( o0 [; n& {2、数据查询(SQL语句为 select ...from..where). d' x9 `% z) R2 C! M
    , T% K# O  L) v  g' q) W: m
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    * D4 h4 b- c1 _7 T1        cursor.execute("select user_id, user_name from users")
    + I2 d, ~8 Z+ i- R7 ?6 L2        row = cursor.fetchone(), h9 p9 n" N# ^, V6 Y( p* Z; b' L& c
    3        if row:
    2 A3 W" p% p5 Q4            print row
    4 g. T9 n- |7 ~7 o  g' o* Z: e; K, O+ N' S
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。4 x* B0 `& l( V  K4 m3 l# ^
    1        cursor.execute("select user_id, user_name from users")4 p( f3 f6 e: a
    2        row = cursor.fetchone()
    - y' c. {$ E, a: t0 X3        print 'name:', row[1]          # access by column index8 `4 a. O! s/ s- k4 Z
    4        print 'name:', row.user_name   # or access by name& f, J3 \+ W$ M
    , k1 \3 E' I- c
    3)如果所有的行都被检索完,那么fetchone将返回None.
    ( B$ N9 s0 z: ?7 U- N4 k1        while 1:: ~# n" {1 Q9 j- w1 s1 V+ a
    2            row = cursor.fetchone()# e" Y0 w6 m2 n  v
    3            if not row:
    3 W/ v( m% J( o* t, p4                break
    2 g' S* E% O- g3 I! E( |2 h5            print 'id:', row.user_id
    - K; |2 }1 X9 n' h0 ]: W4 S0 l' h6 |9 ?# y; l% w! z
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    2 v9 H# u  l4 T6 M1 |( _( J1        cursor.execute("select user_id, user_name from users"): n7 c4 z; Z: H. B
    2        rows = cursor.fetchall()/ h& `: r9 O) }
    3        for row in rows:
    , K3 t: i% n: g- r2 v% M4            print row.user_id, row.user_name- q6 Q% P; P5 b2 o  U4 ]! @- H# W

    / O7 E. b( p2 ~4 Z) t6 S5)如果你打算一次读完所有数据,那么你可以使用cursor本身。2 E2 ^. i- R" N, n6 N# U8 o8 {% o
    1        cursor.execute("select user_id, user_name from users"):
    3 J# l% K3 u9 m0 ]7 F8 n& ~( H' `2        for row in cursor:
    , ^1 n* Q. m5 [( j3            print row.user_id, row.user_name; O4 a! U& v- I1 x. E" H6 i: `: c

    , y5 c0 {$ b8 `' }9 V6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    4 @* k& a( I. K, x1        for row in cursor.execute("select user_id, user_name from users"):
    & x% }1 L1 A0 A8 ~1 k( x( C4 Q2            print row.user_id, row.user_name
    0 R6 o* f9 v8 G( p0 n# |' c8 k* S1 W& e7 f1 ?4 b# k
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:' ]: e& D. C7 v! D, D
    1        cursor.execute("""
    - T/ b7 \" u3 f1 h$ z* T: ~. c2                       select user_id, user_name. \$ |/ T" s1 Z0 k4 N
    3                         from users$ t/ T5 G) ~. N+ t
    4                        where last_logon < '2001-01-01'
    # U# ~7 |& L2 X5                          and bill_overdue = 'y'9 M  i1 f/ L' ?: ^
    6                       """)
    / q+ T% w( T- K9 P; o! O+ U; W: `3 n  l9 A
    3、参数/ v9 V( g) M, P1 s4 }
    : v$ l1 n. b- t; r5 J
    1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    * y3 v( l4 O- z" p# u1        cursor.execute("""
    ! T% [/ K7 \% d' @% ]2                       select user_id, user_name9 }$ T9 [4 x- o6 R) v: |0 R
    3                         from users8 R; x% y* w, E) ^0 ~( ?7 [
    4                        where last_logon < ?; L6 y- ~- F* A& _- V/ F
    5                          and bill_overdue = ?
    9 C! j  j: A+ R6 C6                       """, '2001-01-01', 'y')
    - E5 K% I$ e8 p
    # l1 w5 x3 Y3 ~# k% _0 o) q* `% x这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    % ?& Q" t3 o; x' K2 G! z# I, X/ _7 z0 ]% G5 N$ Q* S' u
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:) p& k3 a2 _! k8 Y0 J  C# u
    1        cursor.execute("""% l0 `/ n1 b4 C' s  D
    2                       select user_id, user_name/ e) j9 a9 W( ^0 F( S
    3                         from users% H2 C  G) ^1 R) f$ @1 J
    4                        where last_logon < ?7 H# t" k# M9 H& d6 S0 _. Q
    5                          and bill_overdue = ?3 T2 V( Y# i5 B& p9 O
    6                       """, ['2001-01-01', 'y'])
    5 D. y4 {2 o- b# c/ ]7 `9 C$ j; |" E9 V  t) f6 B
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    : U9 F6 p+ v# R% J2        row = cursor.fetchone()& H2 N+ H( m: O+ j
    3        print '%d users' % row.user_count
    5 Z& Z7 \* g* R: O+ x, E* }4 v7 c0 P+ N) R! `8 _; d& b
    4 j& |$ L1 n" k% d" o
    ! C3 c# C1 ]- Z. o" P& Q" x0 ^: P
    4、数据插入7 \4 ~. u( r2 r$ [3 q; o

    + n9 W- O+ k  I7 g6 l- R3 ]+ ~$ l8 J1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。
    & N1 E/ d  U# t4 M# |; p7 S5 e1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")2 P3 u8 [9 w- q) r
    2        cnxn.commit()8 r1 r4 G* r! V3 _# o5 L7 P, x8 I

    + F9 f4 N  @6 A  I/ ^) C1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
    1 }1 j+ e9 H9 s& y2 E/ W2        cnxn.commit()
    " u0 o9 ~$ b: Y6 @7 q' v" `; |( W1 I
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    ! I' T9 e" i$ J& `& o# y7 t4 o$ I0 L  ]( ~  i4 }
    5、数据修改和删除; q- Z8 Z5 u" x% d- j' A

    . l, n2 k+ P  ]2 z9 o5 y' N1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。9 ~7 G" R2 |; O+ Y; l. M
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')& A9 \8 y, m. y0 e+ S
    2        print cursor.rowcount, 'products deleted'
    * Z2 `  _& m* D& K/ l) V3        cnxn.commit()" K$ Y- k6 |4 J0 q
    % |% I9 k8 e6 G( r8 g6 q& x% ?  k5 G
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)" y6 {+ z/ |0 C' \9 i; }
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount) p( x7 F" e% N$ r4 S) S' ?/ Y6 q6 v1 A
    2        cnxn.commit()1 o4 e; E; r. _7 r
    $ M' i$ }$ m' d. o9 l: i3 I5 t1 v- R
    同样要注意调用cnxn.commit()函数  ^: c0 A" u* t, H1 {  q

      a. T( D% K  J$ D, ^8 t, s6、小窍门
    3 D! x( w% v6 @  D' G& d/ e4 ^% t& `0 d: i$ A/ O6 ]7 j
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:3 l; O5 B+ L% }* \  X" T1 M* T/ w
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    , o  S) f( ]% {* }# x+ O  D* S5 Y
    * j  N: n2 c: @4 T1 ]" C2)假如你使用的是三引号,那么你也可以这样使用:3 f) L. N/ P7 l; l5 `/ Z
    1        deleted = cursor.execute(""", T8 g) Y6 S( _# e% H/ q
    2                                 delete
    8 |1 ]5 ^( e3 l# @4 E1 N% m6 M1 R% R3                                   from products8 B( m# o3 m1 R0 t, y
    4                                  where id <> 'pyodbc'( m1 o: y2 H4 c& s0 |& M3 C
    5                                 """).rowcount+ w0 a3 p- Z; }: \
    2 u5 J4 I0 y* W6 i
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    1 b. o( \: H; c/ Q1 ~0 ~1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    , t- Q6 T3 Y3 ]2        print '%s users' % row.user_count
    : j; t( S( |) S% Y/ u
    $ d: M! u' K" G+ Z9 \1 H  X4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    " E! e1 p/ y" |, v( T1        count = cursor.execute("select count(*) from users").fetchone()[0]
    5 U' ^! _) m- W$ ^. p4 P- l6 P5 |2        print '%s users' % count
    ' v" _8 P2 B  I* X5 G; y8 ^& x; [3 \1 J2 `3 B/ ^& ]1 ?
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。/ F5 f5 C& Y( I
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    7 @# G$ R* M: x2 X# B* e
    ' E, d! x4 T, l) \4 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-8-4 22:02 , Processed in 0.400494 second(s), 51 queries .

    回顶部