QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6261|回复: 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、连接数据库( _* z' U& ]2 t5 T( _1 X( [

    ' y9 U% j: x" ?' B" y, k1)直接连接数据库和创建一个游标(cursor)
    / C* C8 z1 U, Q3 ?) B  Y  O7 X3 g* |1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    + y4 [1 t$ @5 i, c7 F  Y. i2        cursor = cnxn.cursor()
    2 z: ?5 h/ {" M2 o% ]6 w+ ?+ R/ c$ p  @, g9 b
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。; n# ~, S  x7 |* f6 C5 V$ l/ P
    1        cnxn = pyodbc.connect('DSN=testWD=password')
    6 |, |$ R* ], k9 S7 p2        cursor = cnxn.cursor()
    3 ~: _" C. m0 [# q$ l5 a" ~6 ?& T, n# J& Y+ l0 T
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节! \9 s7 p8 s- q" C- O, {

    3 N6 U; e& x& F) s! H2 n2、数据查询(SQL语句为 select ...from..where)
    # M# N$ F, K7 s2 \. \  {7 H! \8 U
    ' Q- B: Y2 k; ^' Z8 j/ k# L1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。' y! M, w/ ]6 P3 }$ |9 a- Z. u: K
    1        cursor.execute("select user_id, user_name from users"), ^& e$ U. S( r% ^
    2        row = cursor.fetchone()
    " s( j& M( t* D+ I, v# _3        if row:
    $ n2 c% v7 ~' e: S, @$ ]$ S4            print row
    & Y0 |( p2 B# I5 v2 F+ d3 }7 n# v# K
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    1 T+ Q# A9 X7 r' ~5 l( t1        cursor.execute("select user_id, user_name from users")
    2 u. W% h1 N' P" R8 |* ?. h3 H* g2        row = cursor.fetchone()8 v/ g5 ~+ {) P# q9 n+ y2 G
    3        print 'name:', row[1]          # access by column index
    % G3 f' r7 P. P; d7 r% V# |$ J4        print 'name:', row.user_name   # or access by name
    # ?/ Z% T9 e6 i/ Z7 [5 n: F
    / J0 \. G7 D! u7 C. o3)如果所有的行都被检索完,那么fetchone将返回None.+ X6 V6 C7 u, A1 ~2 I- g
    1        while 1:
    2 W2 l+ Y* K! ~( ~. F" p7 G2            row = cursor.fetchone()" d: N1 ?9 W, p
    3            if not row:
    ! v( B8 _- @9 z5 I4 ?2 ?% ]1 @: G, `4                break3 |: E% H1 ]* C( [' t2 U
    5            print 'id:', row.user_id
    + V) o" L2 x5 T  _! A3 H- p0 K$ r+ Q+ e! V8 T4 g, }! X
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)* W9 @4 |7 O5 c: {- N! _' m+ h
    1        cursor.execute("select user_id, user_name from users")
    * R  L$ e% ?) k4 }- T3 M2        rows = cursor.fetchall()& b# x4 C+ E: w+ d/ d
    3        for row in rows:
    ) X, v+ S6 f+ C9 h7 I7 X/ \# x4            print row.user_id, row.user_name4 P7 h8 v9 x/ R9 o! J: H) E
    7 u& I6 B, T# c7 k. c
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。
    0 ^8 X6 v3 [+ l7 H, O5 L: F1        cursor.execute("select user_id, user_name from users"):" W6 M/ i& f9 G" Q. x0 p
    2        for row in cursor:, F2 Y& v, H& _3 t3 Z
    3            print row.user_id, row.user_name/ f- B; p- ^! L2 i) h8 A
    ) L  a* S4 q* J) {
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:: Y1 M( f8 ~6 s  S
    1        for row in cursor.execute("select user_id, user_name from users"):9 ^, f! y5 u& b6 d  h& `
    2            print row.user_id, row.user_name
    4 ]3 S% m$ f% j( I. i9 c2 J/ b
    9 O8 w* B8 I/ U' i" l# @: b7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:1 n7 Q; ~+ e; B; G
    1        cursor.execute("""+ d4 t( x. |  c( E+ F) E3 N
    2                       select user_id, user_name
    2 y3 p: \7 [2 F3 ]" S3                         from users7 F& \- z- a5 ~9 P/ E. ~! @. w
    4                        where last_logon < '2001-01-01'# B2 Y- @/ c  W) w; q7 P! H6 a
    5                          and bill_overdue = 'y'5 L2 {& X! \8 {# C$ R7 t5 C
    6                       """)! u: s2 U0 q* _$ t' O
    3 v6 I+ L/ H) ]8 u( _
    3、参数
    2 m4 e1 K# d* p8 \2 X9 O" x
    5 U; v: {; g7 c2 N3 D1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    ' i, Z% d/ f7 X. u& c1        cursor.execute("""
    , p+ n+ O  Q! ^# v$ R5 _+ t2                       select user_id, user_name
    . p% d1 n3 c* n1 ?3                         from users( L0 c3 S  A: G7 e
    4                        where last_logon < ?4 n8 S& R9 v( P! w
    5                          and bill_overdue = ?$ g9 v  F5 X5 L5 E
    6                       """, '2001-01-01', 'y')" v  r3 g' c2 d& R# o6 ^; C* e
    8 S7 k/ _3 i" g$ P
    这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    5 }5 v. i4 G3 S+ l- |2 v0 _% d- v' f
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    3 _& v, C/ C9 }& F1 K1        cursor.execute("""
    4 @' a! d: s7 @2                       select user_id, user_name$ T, X% n/ y+ r" j! n
    3                         from users  B& j  S6 Z0 Q4 ^1 W3 I
    4                        where last_logon < ?) M) @4 f1 o& J) o3 ^
    5                          and bill_overdue = ?3 d3 H  e( A7 i' q% R: u
    6                       """, ['2001-01-01', 'y'])6 l3 W# ?+ y; J5 Z- N
    ) A. a( e+ y: e. A# g  e
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21); j& ]" S6 C7 u' G: g
    2        row = cursor.fetchone()
    ) A8 K% u/ ?% h( k6 S, s+ V3        print '%d users' % row.user_count
    " F9 |! g; J% d: @6 F- n$ @/ d* z! b+ D

    . k/ ~6 q1 L; _1 X! N& J2 N* ]3 i. U7 b, C2 ?' ]/ \$ N, B
    4、数据插入# c- |) x& c1 P0 ]* k4 S

    5 T2 ?0 p" \; S. j1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。
    8 `' r0 O" [, \6 Y9 E1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")+ _/ t3 x, d* C2 a" d; w; I
    2        cnxn.commit()
    , |4 j3 p* M6 p6 z
    7 i: M) {) [0 V6 F& c" i5 H) ?1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')( y2 X3 l2 {& T5 }' Z) J
    2        cnxn.commit()8 G$ W& F3 L2 X4 Y

    $ |2 |1 W0 p( Y- i) P1 B& f; V注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    ) R* v; F5 D) [! `+ Q) y+ e( y
    9 L0 Z1 U; M0 k$ O5 P) v5、数据修改和删除8 L5 @# v$ W, X; o- }8 l7 m

    6 l0 \0 O7 J5 p0 Y2 ]0 ]! T1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。; `/ ]& V5 Z0 X; U
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    / f7 N7 Z2 b7 E. n, j$ Y  G/ e2        print cursor.rowcount, 'products deleted'/ S: p* ]/ |# t( @) N
    3        cnxn.commit()
    & h  @& ^& z+ m
    * P# Q, r) }. u7 v  N9 a7 G2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)% |* s2 Z" p$ W2 U' s
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount% Y$ I: \/ U3 u2 a/ V6 [6 s8 e, a: f
    2        cnxn.commit()& W: D2 t5 c; |6 |) `! C
    ! }% l, O- z3 M! N# V& u+ N
    同样要注意调用cnxn.commit()函数
    % t4 M; p) {1 Y# C
    " M' H! C5 E. l) \. j9 Y/ c6、小窍门2 [' t3 q" M$ X
    % e7 K- t7 l1 I( n& ~8 n" Q% n
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:
    6 C3 Q' `' x( e7 M/ W5 T% w- m1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount' V! t6 @3 j, Z9 u6 ^+ [7 P6 x0 J" m
    2 P; d, x* S, O/ \% a
    2)假如你使用的是三引号,那么你也可以这样使用:
    5 R5 j; F# ^/ o7 ?. P1        deleted = cursor.execute("""
    $ |1 M3 Y6 B1 o: o# f2                                 delete# g7 W  l; D' D9 Z2 h
    3                                   from products
    0 n6 s* v0 I" F' X# X4                                  where id <> 'pyodbc'
    * V' t8 d+ I* g6 R* [  n% X5                                 """).rowcount4 [8 k8 S; x# l

    0 B& F  p! K  s0 w5 d! _: {3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    ; @* D! U% R# x) [) ^1 s1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    ) }. d# u3 U, G2 P4 H# Y/ [2        print '%s users' % row.user_count/ B9 s; d+ h. r6 ?: K: q3 Y

    & I6 u* ~2 k6 a$ A; [4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    2 P3 P! N! s, G. Y" Q/ P, c7 Q0 {1        count = cursor.execute("select count(*) from users").fetchone()[0]( o- G% g' Z8 t' l  t
    2        print '%s users' % count
    / F$ F  ]0 t5 L3 o: ?3 R) H4 l- u4 B! X# M8 c
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。
    : k5 E9 v& U. H7 K; i' f6 Q1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    0 Y, a) I% D+ B. ]
    6 I9 j/ h* z. ^! C在这个例子里面,如果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 05:13 , Processed in 0.610201 second(s), 50 queries .

    回顶部