QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6264|回复: 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、连接数据库
    0 V$ A" X0 M( N7 B
    1 {% y- X9 w! g2 C' Z7 @- g) G% h4 H1)直接连接数据库和创建一个游标(cursor)
    + |% z# n+ U8 h( @# O) S1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')" _! _1 M- P# [. ]( l/ \" B/ r
    2        cursor = cnxn.cursor()8 b& I; V: A. x

    6 F- _4 o; P% O) Q% ^2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    0 K/ x& f! y3 N1 C) Z0 J9 ]1        cnxn = pyodbc.connect('DSN=testWD=password'); m. t% A7 u% B* |5 n
    2        cursor = cnxn.cursor()
    ; ?. k2 ~, ?4 P- J* e6 a
    " q4 ]* D2 t) N/ g# f2 z关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    ) G7 e$ T- `0 g* |- Y- L  W) b3 r8 V: @6 B
    2、数据查询(SQL语句为 select ...from..where)3 K0 [) W. n2 W# r6 a0 c  r8 O
    6 w7 p5 t4 i6 R
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。+ c! J9 o3 P5 I
    1        cursor.execute("select user_id, user_name from users"): S6 D7 G* z8 N: B$ |. r" ~! e
    2        row = cursor.fetchone()$ ~7 J2 W( R1 h$ p: J! }
    3        if row:
    # z: e6 o# m' i8 p; S3 Y6 H4            print row9 q% @: p' ]8 V0 q  Y  z& \

    , r4 I. x1 [3 W2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    1 ?" k: {* Y% ^/ m, J1        cursor.execute("select user_id, user_name from users")( ]- i  S* v- }0 L. a
    2        row = cursor.fetchone()
    4 y) K2 D' ~7 T7 r+ r+ g, L3        print 'name:', row[1]          # access by column index: n1 z" o/ ?& X4 a
    4        print 'name:', row.user_name   # or access by name- J1 A# f* g* Y* Y' N

    % a& Y  f6 n, J6 ]/ g# g+ U) f3)如果所有的行都被检索完,那么fetchone将返回None.$ H* V( l2 g% L' Z) v- [' d0 B# `
    1        while 1:& @* r* i5 \/ h$ F  n5 m0 \, F1 S
    2            row = cursor.fetchone()  g# ^% {3 Y1 |. S
    3            if not row:! I& [! U1 W. b' m1 u
    4                break0 J% J* w: t+ ~$ s& c( l7 d( A
    5            print 'id:', row.user_id
    % m7 Q7 P9 q- O8 x" O% ?8 F% \" H: B, Q3 n! _
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    0 F/ n) H9 k0 T1        cursor.execute("select user_id, user_name from users"): F) h, J8 t. |& x1 y
    2        rows = cursor.fetchall()
    " J& X+ k5 H7 M7 I2 Y9 L% F3        for row in rows:' p# d+ @9 V3 y
    4            print row.user_id, row.user_name
    1 ~9 b/ n& z7 Y) s, Y; \+ k* u6 a4 ]+ e& \; j
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。8 }8 \$ o1 \7 p! l, x6 n. O  d) i+ g
    1        cursor.execute("select user_id, user_name from users"):' i: D, ?0 A  v* X" H
    2        for row in cursor:" ~' R2 U! |0 a5 W9 C
    3            print row.user_id, row.user_name
    " s8 n1 l$ M0 J* ]$ [0 R1 a0 ~3 F5 z+ E* |' F
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:9 W! v, p" n  {& q) w4 }5 H. i
    1        for row in cursor.execute("select user_id, user_name from users"):
    , K  o) R6 G/ C# ]6 ]2 j* x2            print row.user_id, row.user_name
    2 L$ ?& d, K  p( r  G" V9 A! K, w1 m& L/ @) n, b+ L
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:
    - _  t$ u+ }6 T, y3 a$ a1        cursor.execute("""
    6 V  t' ?) D1 w2                       select user_id, user_name
    8 k  C% C8 x$ |# t3                         from users
    ' Z/ g& P; I, t9 T3 m8 R5 @4                        where last_logon < '2001-01-01'& n" l( h1 \- A9 g( @- |
    5                          and bill_overdue = 'y'/ x. i5 O0 J% p! d4 d0 H
    6                       """)7 [2 A8 [1 t2 S' V! }3 `
    : K4 }: V2 g. n7 e  J
    3、参数# q/ O7 Q! b/ ]3 ^$ s8 l$ S# c
    : f/ B8 r, V, r5 @
    1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    3 c$ S9 ~/ W. o# y1        cursor.execute("""
    $ W6 a4 {# L& x" A4 B3 |2                       select user_id, user_name
    ) y) P' I& E2 R* W; K" Q  m% k( [! U$ {3                         from users  C9 F$ |2 T7 ~9 {; u7 T' q2 X
    4                        where last_logon < ?& q( w/ W5 d. V" w( D+ J& T# s0 N
    5                          and bill_overdue = ?3 S3 w' _2 C7 ]7 L5 a! H( S, v
    6                       """, '2001-01-01', 'y')0 X- }* j$ J+ u0 `

    # v) G5 [7 C2 c7 M- ]2 a# i; I9 U这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。% J: }% n) @0 O, ?1 A. A

    5 x- \! |3 P1 p2 X; V3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    % L2 I( s- Z& m+ E1 D# {$ ?1        cursor.execute("""
    ; o! \! L  i# b" Y" V! n4 X$ \2                       select user_id, user_name
      H( U$ j  W+ Q' V- j3                         from users
    - x2 d* p" A5 ^5 q7 X& Q8 A4 y4                        where last_logon < ?5 l, a/ g5 R7 U& K, G# O/ ?
    5                          and bill_overdue = ?
    2 R9 P0 t" {, y; B! Y5 X. l5 L6                       """, ['2001-01-01', 'y'])
    , ]1 g- W' c6 q* b) r. b1 ^; W7 _# Y0 D
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)! A! r% P2 [- m% W
    2        row = cursor.fetchone()& }1 D/ F  B0 p- ^( Y7 ~
    3        print '%d users' % row.user_count
    . _, v6 Z$ l8 b& s# J6 y8 o9 F. ^! J0 E3 @6 T) a

    1 i1 b* v2 A* S, f3 ]9 E1 U; p$ N* k# }
    4、数据插入
    2 }! F' p4 ^% r- S+ S0 W: r( Y2 j5 Y2 \$ D7 W) _$ n5 I' Z
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。
    4 [2 N$ {! n0 ^, @5 F7 @' T8 ?6 l1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")5 ]# x" d0 ]9 B3 W+ [1 a
    2        cnxn.commit()
    : Z6 N, k$ d8 _$ b. h8 n; i. b# e% w; g+ S8 ^
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')' [8 g4 M1 k0 q8 f( Y' U
    2        cnxn.commit()' `6 u7 G9 C, s8 \
      m9 {6 {! e$ t' \
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。
    0 H8 m+ F% v2 t3 Z) v- K- r3 N" R* n3 X
    5、数据修改和删除
    5 K+ _4 B( ?# T8 p+ U% k' d9 q2 W) ~2 f2 |
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    7 n0 K" |$ _( k) V  `1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    9 q; ?* k) _0 t0 h: g2 c2        print cursor.rowcount, 'products deleted'
    5 m0 C) T+ d8 J3        cnxn.commit()
    ( U& e3 W; w# F# R& Z) O% Z* F0 I5 A9 n% V  A2 J6 ^
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    : l6 M4 u" @' O2 y5 L# y1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    ; k, _6 I  O8 N) {& O6 _' @# @. e; C# Y2        cnxn.commit()
    % T1 [: w2 w' U, g5 M# T  Z  X( Q5 Q) `" T
    同样要注意调用cnxn.commit()函数
    ) \+ z5 u3 f" {$ o# k( f. f9 x6 _0 ]9 p
    6、小窍门- Y2 e2 M8 y% V5 \( q
    . h' |4 A6 |3 Q# e) c" Y% \
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:+ U) Y- L+ o. b8 y3 \6 B
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    ) m8 l2 d. f* t! ^
    . B, p9 ^) q; J0 w2 V4 }! x2)假如你使用的是三引号,那么你也可以这样使用:
    ) l( a; o0 r# A& f0 F7 \1        deleted = cursor.execute("""3 V" m7 k9 c5 w9 ]# c( h. X
    2                                 delete
    ' m2 r( `" D* x( L( v, c3                                   from products
    ) H& C; r5 C9 J# o) d# [  N; H4                                  where id <> 'pyodbc'
    1 L8 q& _. y# g9 K) E5                                 """).rowcount
    8 |" w3 O7 _/ f" q( w8 ?# P/ S  b! `: D0 V2 |
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)" N" g* m2 n+ t
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()# N( T$ R% P+ y0 u, D
    2        print '%s users' % row.user_count
    % O4 q, y& q/ D% I" K: ^
    ! N$ h* V$ d+ |2 G4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。+ Q9 s8 {" W) F- B
    1        count = cursor.execute("select count(*) from users").fetchone()[0]
    " V+ ~5 h* I& _9 a! |3 p' _& p2        print '%s users' % count
    7 m, B. g8 I% o6 S9 W% G: |. R  n
    8 l$ A5 {) s7 a' T* l/ q5 A- f如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。0 _& X/ e. B0 K: c. V
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]: s, p  T+ [, ~

    ' r. @2 I) ~6 B, R( F7 T, e$ S4 Q在这个例子里面,如果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:42 , Processed in 0.646321 second(s), 49 queries .

    回顶部