QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6185|回复: 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、连接数据库& w0 o1 X1 e5 {2 A& X- \# ~

    + F8 c* R9 C* Q+ J- W+ G$ y1)直接连接数据库和创建一个游标(cursor)' O2 L# b9 `: `5 c0 e; A9 k
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass'): T; `# v. l* c: {/ u: _
    2        cursor = cnxn.cursor()5 R  d6 }+ v( {  r+ P: H
    4 C' K% w7 {4 q$ [# v$ B
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    9 O$ a( t5 y8 C3 L! N1        cnxn = pyodbc.connect('DSN=testWD=password')' Y# a) q2 d5 U1 M
    2        cursor = cnxn.cursor()
    * e/ ~" {( C# y* F6 l$ x9 Z% b' c  g9 Y
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节( Q6 A3 {+ m* v; K: |
      R0 ^) P" u7 i. ?
    2、数据查询(SQL语句为 select ...from..where)
    * v/ {9 j! e1 S' S1 t* ]% i/ c! w8 D
    2 ~# Z0 X, F! b1 }% A1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。" i  T( s  p+ G, D6 {$ m
    1        cursor.execute("select user_id, user_name from users")7 r5 G; ^' Q$ _! m7 r0 P( ^2 O' I) X3 p
    2        row = cursor.fetchone()
    1 w! T% j! A0 B, G8 \: W) Z3        if row:
    + g# J1 A7 K6 j4 F3 d4            print row
    3 d" s' C( r9 o7 a7 ]7 l
    5 t. E8 o7 o* X% D1 M5 M# p0 G2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    3 y- J+ P# I2 a) Q2 }) e+ Z( U' W( l$ s1        cursor.execute("select user_id, user_name from users")( c  O) |( y: V6 ^, ^! t
    2        row = cursor.fetchone()' {: d7 n( t/ J1 c  Q
    3        print 'name:', row[1]          # access by column index) ^* n4 |5 w7 `2 o0 y: f) L5 C
    4        print 'name:', row.user_name   # or access by name1 J. Q. S" K4 Y0 F- W8 X$ [0 w
    ( d' Z# t* z- D- g& o! u
    3)如果所有的行都被检索完,那么fetchone将返回None.8 D) x" A6 b8 z
    1        while 1:' P% K8 |0 q0 J! j# d7 q
    2            row = cursor.fetchone()( L0 P8 H' N  l8 C
    3            if not row:+ [& {: P7 P; k$ u
    4                break* ^* ]$ {0 p/ J* O4 V7 J" m
    5            print 'id:', row.user_id* U1 `1 f1 [/ G' j

    9 A+ ~1 n0 T! l' B) ?2 h; k4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)& t  p1 i3 W: n- V- u
    1        cursor.execute("select user_id, user_name from users")
    * ~: s; L8 M. i: p' e+ i2 r+ ]- h2        rows = cursor.fetchall()
    * h( q8 P3 `8 ]/ B- H2 |( ?3        for row in rows:/ L" x! l2 r$ O& _  K. N' T, A
    4            print row.user_id, row.user_name
    7 B: B7 a( ]" @4 y) g
    & V6 W% Q0 ~4 h& P* P4 y5)如果你打算一次读完所有数据,那么你可以使用cursor本身。* u0 j6 {# g; c, ^: I7 E  X
    1        cursor.execute("select user_id, user_name from users"):% e% q' d2 s$ d) E, g6 {4 w
    2        for row in cursor:
    + \; [/ k3 a: ^6 @' d. t$ ?3            print row.user_id, row.user_name
    0 o6 y8 e! \, A2 E
    0 L( r8 H% s) G) x& p) J6 ?6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:3 v4 ?# E+ A" k/ c$ C- ~
    1        for row in cursor.execute("select user_id, user_name from users"):
    ) J, ?9 z3 a  ^. U9 T/ h2            print row.user_id, row.user_name: M  Q% Z9 z) S- |
    , O+ q; R* e6 C! s8 s$ R
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:/ E+ V1 C0 }4 i  U2 C
    1        cursor.execute("""
    2 W7 Q, J. i& X5 d# o4 u$ w& n" h2                       select user_id, user_name( [0 j+ S/ r" J( F
    3                         from users4 i$ l- W, x0 k, G; {2 F% m
    4                        where last_logon < '2001-01-01'& Q* N9 A/ n. B1 q% i" l7 P
    5                          and bill_overdue = 'y'
    : A# f% s+ |" `) U6 }4 y6                       """)
    # b. _9 }* }& G9 c# x( T; x0 u4 Y! }2 z& ~- S# t4 T: Q; ^
    3、参数
    8 [) d% j; H+ ^: x
    + [& z7 O6 V2 o2 c3 I5 X1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    # w5 E% W/ h; D  a0 p, \1        cursor.execute("""
    & A$ B. ^4 c+ w5 C: I$ a4 e. x% Y0 n; D2                       select user_id, user_name0 X' N( _% a  r* F& ^. U3 ]4 Q
    3                         from users  i- e* A/ \# I; ]
    4                        where last_logon < ?
    " B$ m! q% v7 I' A) O5                          and bill_overdue = ?4 a9 t  F1 N4 j7 b8 K
    6                       """, '2001-01-01', 'y'). g9 S" J  }0 T

    . O5 p8 ~, y' d& s6 E: H1 L这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    ' v( Z4 l. T8 H, r9 a
    " N0 u1 b" b2 f' r  w& A3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    8 a0 `( O% \8 e2 `8 @1        cursor.execute("""3 H0 M$ N3 |/ M4 A. p. v& m
    2                       select user_id, user_name, ?8 R3 F) u1 i. h
    3                         from users) t. `' X" Q6 ^% z/ b0 R& W
    4                        where last_logon < ?5 m2 p5 n! b6 A& }# }/ D
    5                          and bill_overdue = ?
    : E: V) J8 T0 m1 M6                       """, ['2001-01-01', 'y'])
    9 B( d* z# K) H$ Z% I+ l1 {: I# V6 h. J7 w) U+ q/ X' P+ a
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)& w% Z7 t7 H$ ?; p2 F
    2        row = cursor.fetchone()
    # k/ Z2 ^+ w+ J/ o! r% c& l3        print '%d users' % row.user_count
    3 d+ Q% L9 C, }# _5 z, e: w  q9 x; e

    0 ]) P/ E+ O+ k4 f! m) D7 G* m) d/ h$ E; v
    4、数据插入% }3 I1 s- R$ X

    9 ?# P5 m! ]; r. [0 B; h1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。9 ?8 k# o- n: W' |
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    0 Z: Y+ W! ^! q9 E# E. [2        cnxn.commit()
    & a4 V8 ^5 P+ ^. o/ x
    7 Z* h9 g* }2 @4 P) q* E1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')% V% k5 r- h* Z, f
    2        cnxn.commit()
      [1 v, u9 `. u, Z5 C: T
    0 j* s- d# y" T注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    3 k4 K2 K3 `9 g+ l4 G3 [  j% p/ I1 Y* i) M& ?" N0 D
    5、数据修改和删除
    5 G0 c) X8 ^9 z& U8 r1 ]# J
    9 J2 e9 z+ W, X0 F  {1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。$ S- u( x6 Z3 m  D- d% r
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')2 K( q% \  @5 I
    2        print cursor.rowcount, 'products deleted'
    8 z6 z" ^6 Q$ W8 F3        cnxn.commit()8 R) n& n+ v# x! e

    * T( {: w* y5 o% ^( }" I2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)2 H. d* f$ o# p1 [. O- C0 I
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount' h6 A4 d' u. B. p5 L
    2        cnxn.commit()
    ; A; \" b$ ^% R$ O0 X8 y6 J2 z2 G2 V+ Y6 T0 N; i
    同样要注意调用cnxn.commit()函数" J. v3 X3 }+ X$ F
    ) A2 d% D. c: ^
    6、小窍门1 S; r3 b9 U8 U( t( y1 G7 A

      G0 L8 d/ x' N$ M# W6 \( J1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    " a( a! }1 l: k3 [$ Q1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount7 p* |, h% l! V7 N. y

    # o- v7 d& r# ]6 X: q0 L2)假如你使用的是三引号,那么你也可以这样使用:
    ! ]4 \% k9 W' P/ G* S; V1        deleted = cursor.execute(""": v0 Y6 h4 t; I, O' s: c; I
    2                                 delete5 T! d" }4 _% s" v
    3                                   from products, d, w9 f* F% _
    4                                  where id <> 'pyodbc'$ [) Z# C* @$ t. f) d9 X
    5                                 """).rowcount- k9 }) r' @2 T. n# k6 P. T9 v
    8 K! c( T- C8 _, y% ~) ]: [6 L
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)5 n, ~3 A  Z1 p' R% g* H
    1        row = cursor.execute("select count(*) as user_count from users").fetchone(); u, [# L2 P& e6 S$ S2 B
    2        print '%s users' % row.user_count
    . s4 s, i5 W' [, X, f- G% }. Q9 _, o3 @: G- N% I, X2 q5 }& ^  ]
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    9 }/ `; L) ?# M1        count = cursor.execute("select count(*) from users").fetchone()[0], P. h9 R' B- T6 M6 ~
    2        print '%s users' % count
    9 f2 X/ Y7 K2 p5 w
    8 q  x4 r4 g+ f) {, @1 F0 H* w如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    4 D. s' }; |* U, T1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    $ Y* z: m8 P/ U& l3 M0 l4 V% A+ n' o+ O
    在这个例子里面,如果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-23 06:51 , Processed in 0.425895 second(s), 49 queries .

    回顶部