QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6260|回复: 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、连接数据库) K0 b0 B3 Q4 u9 Q0 @
    4 ]. E- h; E# x) v0 b
    1)直接连接数据库和创建一个游标(cursor)8 K% L* H& @  b0 o
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    - @8 n2 b& t, I+ Z1 s2        cursor = cnxn.cursor()4 M; d5 u# s/ O& i" ^
    5 F3 X# [3 [/ e+ s& x) p7 J
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。2 C# D- r: _, o
    1        cnxn = pyodbc.connect('DSN=testWD=password')
    . X0 S0 p+ o5 o2        cursor = cnxn.cursor()" _) f* Z4 S4 p' F' G0 e
    8 ]. W* b0 b& W7 p  m+ u2 G
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节2 t7 Z& \. k! X: C1 t; [& v4 I

    ; @( _) A0 ~) e! D' D2、数据查询(SQL语句为 select ...from..where)
    8 Y) o' G& p: F  i0 x- o! V5 ]* A' {/ K- x" F
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。) x* B) Z( q+ s( W2 n
    1        cursor.execute("select user_id, user_name from users")
    , {# R& E" N% k% `: V  t2        row = cursor.fetchone()
    7 K/ b$ y; M$ d: U. N( D& U" s0 R3        if row:. l2 v- f  ^9 I' d& }5 Z
    4            print row! Q; ^. E7 a; i( n( K3 s; O' y0 s
    2 T: j* O4 J4 r- r+ w! |, T
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    % o1 U* v  S( X2 @% i" \1 Y1        cursor.execute("select user_id, user_name from users")7 x& `/ W1 @! N1 e) ^8 n  f
    2        row = cursor.fetchone()
    * w% n- b/ q/ M! d7 Z5 f, h3        print 'name:', row[1]          # access by column index
    - z! B9 f; X/ |9 R7 ^, }4        print 'name:', row.user_name   # or access by name
    / }# c! }6 N; P$ a7 C; }( @. E6 Y3 ]+ H5 w2 \
    3)如果所有的行都被检索完,那么fetchone将返回None.
    ) x% l% O4 \" A1        while 1:( X5 y+ x+ W- b' z+ N
    2            row = cursor.fetchone()
    ; `) s# Z! ^1 n# @3            if not row:1 Z! a7 }. {, `) ~5 I
    4                break
    5 h; c5 g* `! S2 {  P0 P5            print 'id:', row.user_id
    . r$ I" L6 W0 X" {% [5 j0 z& P- ^
    # h0 Z* E- H5 ^4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    $ y6 l, B8 Y% N$ u  C0 q9 {1        cursor.execute("select user_id, user_name from users")( q7 s! q+ c& F1 [+ Z% ]
    2        rows = cursor.fetchall()5 p5 S2 s5 F& _1 k1 V
    3        for row in rows:% L" X% H1 H+ S4 i" Y$ \
    4            print row.user_id, row.user_name
    2 X. u$ A+ V! Y* a' f! O) a# a) @% s  S- J
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。
    8 [1 u& H$ ^3 i4 M1        cursor.execute("select user_id, user_name from users"):9 w: O5 s: ]8 Y' y5 k
    2        for row in cursor:* _+ B- p0 e$ R
    3            print row.user_id, row.user_name/ K$ [( y. p' F2 _  a

    & @7 k" @) @# C6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    , w4 G  j6 r' j" `" W! G. ~1        for row in cursor.execute("select user_id, user_name from users"):
    : [: `) U# [, [9 p! B) f2            print row.user_id, row.user_name1 g7 x; L, d2 A  n, G
    : h7 O) G7 a4 u6 e3 i6 }8 }
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:9 I) U' }* b4 b. z$ P
    1        cursor.execute("""
    4 b: W: D! i3 n' a2 l/ t2                       select user_id, user_name/ F. D% P6 u7 G: R* T5 J% Q' q
    3                         from users" M. {2 |6 g2 p9 C8 y1 O9 v
    4                        where last_logon < '2001-01-01'
    2 F$ B& N& L  ~) B7 {$ Z' H5                          and bill_overdue = 'y'+ W3 \3 ~7 m7 F
    6                       """)) t8 ~" u' T- A: J) B1 [% z% [
    2 t" y1 }4 V, e# B+ m. ]
    3、参数; u- ~5 v5 y; G: b/ L: b' C
    9 ]2 @6 j) y  w7 o3 P4 M$ p
    1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。. H1 X. F3 D# V5 ~; m* B/ H
    1        cursor.execute("""
    6 s1 U2 v0 t$ i8 e2 \7 @* j- C  Q2                       select user_id, user_name2 i6 Q0 E4 p6 q- G/ d7 `
    3                         from users
    8 _' y+ ^/ ?+ M4                        where last_logon < ?
    ; o: b( m5 m' P2 G/ x5                          and bill_overdue = ?
    . i7 Z" B# Q6 X8 a* H6                       """, '2001-01-01', 'y')
    ; Q  }" l# \7 z) v1 ^, ]
    7 G( h& [; N3 W& H, }3 T这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。4 ?% F# G2 K9 J! J8 _4 T

    $ `$ x) o! m  n7 s3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    1 I! e7 `8 l9 V1        cursor.execute("""
    & U8 G1 L. _' b2                       select user_id, user_name' m: F% C9 B) t* i1 c0 w3 h, _
    3                         from users. D5 o8 ?. Y9 G; i, k
    4                        where last_logon < ?
    ; p# o2 d! O+ O7 x. s5                          and bill_overdue = ?7 S% p& k) ~; }% L# Y: A
    6                       """, ['2001-01-01', 'y'])
      n* _5 ?, u- F  q" k" p5 A$ `! {
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    ! K) A% o& Y/ Q. t0 G5 F2        row = cursor.fetchone()' ?6 J+ |1 E& F- W
    3        print '%d users' % row.user_count
    ) S; ?$ A1 h2 j. g
    3 e$ V- c* G8 T; I' } ! f4 I) j  J8 V% Z
    9 r8 x" k+ r% ^* r- M6 s
    4、数据插入( t* Z1 j0 ^  A
    $ q) f0 I; ?$ `# X& j: w
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。! b1 j4 [& |4 T! F9 U
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    " c2 n$ k; D' H$ I9 s* L2        cnxn.commit()
    3 U  j* {, S  Y* ~6 w
    ) D: Y8 R+ k4 ^: S  N1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
    $ r- Y6 Q3 B( X' y5 }! w2        cnxn.commit()& ~) f/ G" a+ F( j
    ) K5 }+ {" _" G- |7 ~" G
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。+ t. A5 f& h# H8 D( H
    7 R8 u; b' \$ w" C
    5、数据修改和删除
    7 W+ v9 r) @1 N! U3 b# c/ P2 _/ ?# E8 X" A5 K
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
      A9 m# }; E. ?9 X1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    3 O, H* a* S$ _. d7 ?2        print cursor.rowcount, 'products deleted'
    7 ~2 T8 w+ R: r! i3        cnxn.commit()8 P2 q2 d6 X# G  J4 \2 _! a( R8 c! i# y
    4 t2 _/ F# c2 U7 F( V$ ^
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)& C2 K5 T- b5 ^" O
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    # W7 {' j$ |% a2        cnxn.commit()& |6 I1 W9 U0 j% K( C" x

    0 ]7 C; V7 l1 q/ o1 f同样要注意调用cnxn.commit()函数1 z2 }+ N0 E# [) K, J* B- ~  [

    / A# J9 [' a% I/ Z! M3 \* N6、小窍门
    ' P: t5 s+ ~% S$ U% U8 B) ^) M/ K4 b) }4 ?( o
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:3 C5 c9 _- P" l/ [8 i; l
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount9 b0 y' W0 {, g$ |& f
    ; n& b, U5 m& R- x
    2)假如你使用的是三引号,那么你也可以这样使用:' |' Q4 @# A* {+ ^! _9 r
    1        deleted = cursor.execute("""
    9 }+ Y3 o4 H4 z2                                 delete
    - ~" r- O  ^, K/ ^/ o4 K3                                   from products4 ]2 F% C! R& C2 z
    4                                  where id <> 'pyodbc'
    " {( W' A& M( k" V8 p# n5                                 """).rowcount
    " U* U3 |3 ~$ v/ b/ T) u+ E8 s9 k3 x, {7 p, E2 e  Q
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)2 A3 u# p0 h. J& [3 s5 j
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()$ C3 u6 e( ?) F5 L5 m8 @
    2        print '%s users' % row.user_count- R% Z# m' a9 ?* [6 y

    3 ^" y! f% G0 P. E* r( n2 o3 ?4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    : E5 U; I7 p3 `/ N  N) d( O1 q1        count = cursor.execute("select count(*) from users").fetchone()[0]# b2 w/ `1 G: K5 `/ W' m% D$ i
    2        print '%s users' % count
    / ~/ T$ a- s/ H3 h3 L2 w" M7 x1 q2 X5 L% c5 _* X$ N1 a. r* l. v
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    $ g( E6 A* O. y! Z9 c0 Z9 }1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    + ]! b& _+ [! w* ]7 L; ?( @7 ~
    " `$ `' c% W% [在这个例子里面,如果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-8 00:03 , Processed in 0.807481 second(s), 49 queries .

    回顶部