QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6095|回复: 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、连接数据库
    / T- q2 w+ E* v! T& P1 L, D- j) r/ a$ H
    1)直接连接数据库和创建一个游标(cursor)) c) Y" B! j; ~# S& A% s' c6 C: C- j
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
      |6 H2 T# p, l: C! l! s+ M( s# Q# {2        cursor = cnxn.cursor()- j9 b- w8 h; M* q5 M# P/ S7 P
      X# m+ U8 M. w/ q3 N; b6 _
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    " c6 u4 I) q6 n" D* K1        cnxn = pyodbc.connect('DSN=testWD=password')
    6 L. e" h+ ~+ l7 k5 E! t2        cursor = cnxn.cursor()
    , j5 @: l4 C8 K* q# N1 Y4 R# l
    # o' k2 p& h$ W) \1 O6 X" A关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
      W9 ]! q; a/ b" T8 N* p, M; I9 y7 d3 l% Z/ k+ t
    2、数据查询(SQL语句为 select ...from..where)$ p" g" e' G: u  \, m% ]3 J

    8 g5 l# U5 A  x4 D  q, t) O, ]1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。/ Y, i9 f  b* Q9 j
    1        cursor.execute("select user_id, user_name from users")3 t: i0 X# ~6 y+ Q+ b
    2        row = cursor.fetchone()" M5 w4 l3 D; m8 H7 O2 P) B
    3        if row:
    6 t* e0 E4 C! r5 B: z8 q% X4            print row
    1 `# h8 u# a: N+ s( G' a, s3 V: v9 Q, t; m9 r7 Z
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。8 k  W) h) }' z8 n
    1        cursor.execute("select user_id, user_name from users")& w; ~" K$ L1 |5 E
    2        row = cursor.fetchone()
    # d. x2 a7 t7 V% _3        print 'name:', row[1]          # access by column index
    2 ~/ W8 I7 M% E0 `2 A+ m# ?" T4 f# t4        print 'name:', row.user_name   # or access by name
    / S6 ]% @2 g% O# {; }% ]
    ' l% Z- {9 k# C+ X4 r( g3)如果所有的行都被检索完,那么fetchone将返回None.; ~0 Z3 E( y' L% K- {
    1        while 1:
    1 S9 L7 K1 U; ?$ G/ R2            row = cursor.fetchone()6 T7 v3 z3 D! o6 x( ~; t2 v5 C$ j
    3            if not row:: x4 {! X5 @7 m4 D
    4                break
    * K2 F0 \3 @4 i$ H4 F! @7 j5            print 'id:', row.user_id$ C1 S' F* L) a, Q- `/ ~' K
    ( e4 C  G, e3 u
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    # s( S# Y, Z1 Y1        cursor.execute("select user_id, user_name from users")
    4 A9 Z, p7 F" y; _6 t0 U) d2        rows = cursor.fetchall()
    * m1 t7 d7 O8 |# t: ]3        for row in rows:  Z6 R& c( }+ A! i, v/ A
    4            print row.user_id, row.user_name
    . n' A9 q% ^6 w! a* {# Q* b0 Q/ T0 o' w" W! T5 l  z& E% Z
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。
    5 I1 j! k; V0 U" I) R1 @1 _1        cursor.execute("select user_id, user_name from users"):
    , y! z& W0 ~2 \# W: F1 |' P, o1 O# w2        for row in cursor:: m! _- ^9 `2 l4 h2 o+ l
    3            print row.user_id, row.user_name
    2 r8 I2 J& J/ S
    % Q! f+ F, V+ q0 G9 |% |% [1 h' X/ R6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    4 C# j( @$ C% r4 V, a# F1        for row in cursor.execute("select user_id, user_name from users"):% L2 v* D! ~: D: F( c- @0 b
    2            print row.user_id, row.user_name
    ! l  R/ ]& A  ?$ U1 X
    0 I$ `5 n+ b) x7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:
    ( B" D3 o* ?0 c* T1        cursor.execute("""
    , P& e/ G+ @7 P) j2                       select user_id, user_name
    + Q2 E+ j7 f* Y1 f3                         from users) {& M- U! \( U. f# h7 v- b+ G
    4                        where last_logon < '2001-01-01'
    3 I7 l  i9 U. M: l' t5                          and bill_overdue = 'y'
    - a* U8 @# J  ~, f; _6                       """)
    $ H% g- X5 [, D9 c% b
    0 G# C! j4 |7 |) v& J3 L% d' V5 }3、参数9 s5 M& Q1 p9 D+ g6 `1 \' W

    # N) g% C) {9 W3 ~# K1 ^$ ^1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    " q9 i7 y4 ]% S( k! _1        cursor.execute("""% f2 ~' W* j, O, W5 U* V3 Y6 e
    2                       select user_id, user_name
      j" Z/ d/ b2 d& c% p3                         from users
    0 N6 _/ _" Z+ P9 s4                        where last_logon < ?
    " h9 c2 z1 b& r/ k+ Z; z$ F5                          and bill_overdue = ?
    ' ]. M/ m: o  t/ U/ N) g6                       """, '2001-01-01', 'y')" n3 S2 P& X+ H' ~- Z

    * n: C. w6 T! S这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。* m) l4 `' b6 [
    9 |5 Z7 R7 h! K& ^4 B, y" R
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:' _' j# E; i$ X
    1        cursor.execute("""9 k0 M: W, J: J. s
    2                       select user_id, user_name
    3 ]$ }2 G% X' l3                         from users% I# m% Z1 I( Z& W: R
    4                        where last_logon < ?0 s9 j8 ]0 ]. G
    5                          and bill_overdue = ?9 x6 b9 s7 ~- ?" n/ i
    6                       """, ['2001-01-01', 'y'])2 y; M3 C* D5 c& d

    5 {2 |! F* X* P& {) s1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    . R6 t7 z. p4 E) A2        row = cursor.fetchone()/ x& k! s) Q; f' O7 i
    3        print '%d users' % row.user_count
    ! S: R$ w) _& x! M* r9 H4 [& x: z2 e* L! ~5 e" @  M8 ?2 x

    # E4 A' U& g  \. ^6 a! E; U2 Q7 D$ E1 Z6 w1 W. X& P& N, x  M; [
    4、数据插入) {3 S; ?  [; d, ]& Q( U6 C
    0 K9 f% o/ J6 H9 l5 W. n
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。6 q& L4 ~* v: z& w$ t
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    % H7 a; Y$ n( e  w/ ~' w! }+ m2        cnxn.commit()
    4 O/ m/ e! C! p- a3 G& @
    * r  \+ w5 X" t; g( X6 [1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')7 |2 L$ h* q# G: c: M5 V. u" g9 H
    2        cnxn.commit()) W6 R; B4 ^  _4 X) T4 t) i
    % V7 G) ]" n8 J2 b. @: D
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    / F! g0 q( U  b! w& s0 V0 C9 l; X+ z1 g, Y$ {
    5、数据修改和删除+ k4 K! i" g$ i! `, m
    ! o/ A/ a6 |1 \+ s/ m; M7 Y9 O# p
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    5 L8 R2 i/ c1 v0 G& W- \' r1 a1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    9 O+ J& A7 Y0 J+ v2        print cursor.rowcount, 'products deleted'
    * [  u' o5 J2 F; @  m5 i( A3        cnxn.commit()
    ; Y1 V2 c  V$ U- I6 u, V0 r: v% L' c1 E
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    ! s' ?1 |) L7 N" O/ y1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    ( B. `# j! C5 Q& d" F: }! O+ h2        cnxn.commit()
    3 Q) ~: f8 ]  q3 T" a7 S; E5 r  e" L. j2 z3 Z- y. ^
    同样要注意调用cnxn.commit()函数% K8 S  z; v$ |; M' c! B& p+ P
    3 ]# f8 |# ~. O2 o+ y
    6、小窍门
    5 g8 J! z! h  |. Y9 Y
    " I; d2 y& T2 J& B, ~' o1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:; R" G' W2 ]& W7 ]4 Q" o
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    # v/ D, j% u1 A: S2 q  o9 C* X0 E$ z( p4 n. ]0 V" F6 g
    2)假如你使用的是三引号,那么你也可以这样使用:
    $ v9 w- q3 J# F1 O5 L6 M7 x6 f1        deleted = cursor.execute("""3 H% K: T5 X4 S, ?, p6 q, L: T2 J
    2                                 delete
    8 g& p5 v2 |9 R% G; v  a' N+ p; n4 L3                                   from products
    & O+ R! t+ S. X9 g; \$ a$ s! K4                                  where id <> 'pyodbc'
    8 Q3 ~1 p3 O) L' j8 a( ~5                                 """).rowcount
    ( X; o; q; D& A) s* i1 Q7 q3 _% P( q1 i1 S2 F% A) e
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)* t& P& c4 ]* V& D
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    8 u, X8 V: N; A9 {! H; R. E; O2        print '%s users' % row.user_count, e' ^" [( z7 T1 k* i. G2 \
      t9 b# l) w9 K: O3 N+ m
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    # I* }- d4 s2 t1        count = cursor.execute("select count(*) from users").fetchone()[0]
    , N$ y6 x( X; ]7 Z) ~5 V5 G7 k2        print '%s users' % count
    . \" Z0 Z9 E& F% u, D0 y% j$ g1 z* h( L3 k
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    % I% z7 a( M2 |# Q1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    . N) d# l5 V& P) V
    - {9 v! X( n( e, C; g1 x& B3 ?在这个例子里面,如果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-4-20 06:40 , Processed in 0.437021 second(s), 50 queries .

    回顶部