QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6184|回复: 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、连接数据库2 L. j$ Q2 ~7 N, V% @% ]
    4 r# I) X0 t8 ~; j% H$ d
    1)直接连接数据库和创建一个游标(cursor)3 z2 f6 ]+ x, M8 P9 j2 \
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')
    2 u) ?8 B. |6 I$ s8 h% I& D9 |0 S* }2        cursor = cnxn.cursor()
    * q% S1 @: |: R+ |; e; L2 q, I2 b  r
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。5 I' O7 T) R! R, p
    1        cnxn = pyodbc.connect('DSN=testWD=password'); v6 b7 t: w" ~. t& h7 F; H! ~- f2 @
    2        cursor = cnxn.cursor()( R' n+ J3 w0 F# M

    % ^* }. }) ~5 w: a$ g关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    0 B& S( L* m" j3 T1 @  b2 t2 H  g7 ~$ A3 O* D# E6 X; z
    2、数据查询(SQL语句为 select ...from..where)
    " a' k+ N8 O6 [% O+ v9 I- K- U
    / w: D  U) Y/ |& C9 h) `1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    1 e$ M- p2 L. C- l1        cursor.execute("select user_id, user_name from users")
    5 \3 ]: V! J; \6 t* X9 A0 {, \1 |2        row = cursor.fetchone()* U9 G3 }% T+ B) L* w, ^- ]
    3        if row:1 T1 W; V" b/ y' U% |* ?8 \
    4            print row. F2 g1 C) M- Z

    ) V: X- H8 n" w# [2 n4 j2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。
    " Q4 `( |5 C; l! ?( V7 w# g0 H8 k1        cursor.execute("select user_id, user_name from users")+ J! e/ q, J& @; y
    2        row = cursor.fetchone()% k( L9 a4 G( q3 ]( n8 f& {
    3        print 'name:', row[1]          # access by column index
    ' D% f7 H1 D; y5 t7 m  j1 A  j) J1 [4        print 'name:', row.user_name   # or access by name2 F7 `- ?. h  m
    " q% w" J$ H6 o3 H
    3)如果所有的行都被检索完,那么fetchone将返回None.
    - c2 E8 o' V4 m! v8 `, Y7 P& \1        while 1:
    ! V" |: ?8 F" T2            row = cursor.fetchone()$ e: G0 ^  ~3 y$ q/ E
    3            if not row:" m' j; m& s2 C: S* |1 x0 k& w
    4                break
    , Q/ t4 F5 C2 G$ x! C6 s- q% {5            print 'id:', row.user_id* z2 n+ q- [! y( \% _" |; h

    8 L' f0 i5 f( |  ~6 T4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)/ o$ I$ k# D; t. i* N
    1        cursor.execute("select user_id, user_name from users")
    & p& n7 ]2 n) s: U: t2        rows = cursor.fetchall()
    4 g; K% t3 U- M3        for row in rows:
    % h' H2 v: Q; O2 `4 a4            print row.user_id, row.user_name
    ' S  u) ?1 A# Y+ l8 a1 D  o9 F/ X- r5 ^
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。3 M5 m2 r4 Q  |
    1        cursor.execute("select user_id, user_name from users"):
    7 e2 q3 d, G5 F) X' C/ h9 A2        for row in cursor:
    7 [1 s0 h. o5 ]: b3            print row.user_id, row.user_name  t) c% d" |. I* Z$ H% P. ]3 [
    6 N" \( l0 L1 b/ C$ d, M
    6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    2 Q# H, s4 g, v6 s4 Q1        for row in cursor.execute("select user_id, user_name from users"):
    ' H; ^$ v5 F, X. {, s2 ?7 e! Y; _2            print row.user_id, row.user_name) Q/ B2 I% [, J: [+ P. T  |
    9 l) T2 m7 h$ \' [  H3 Y
    7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:
    $ o1 u  S( s, Q7 n2 h4 r1        cursor.execute("""
    1 |, ^0 i& R2 Z# d* y, t6 X2                       select user_id, user_name
    0 Q/ E, w' W' O' R* Q. S3                         from users4 z) A7 N) s9 I
    4                        where last_logon < '2001-01-01'5 t8 R; S$ j/ D' i* E1 u) y: K
    5                          and bill_overdue = 'y'
    ' E9 t. E5 `/ ]! k& a6                       """)
    # g4 H8 s7 Y2 z- a
    3 y' s  f2 J" T- M$ a8 s3、参数
    - P; N# Z% Z/ d' A% J, U
    4 j7 Q! f7 c* b- Z8 s1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    % E* j( ]7 ^, s0 ]8 Q4 W7 B3 e( j1        cursor.execute("""
    " ~9 H1 j' E! {7 \2 M2                       select user_id, user_name$ T. b- a3 a$ W
    3                         from users
    / L# X4 E9 r/ q, w' @2 A4                        where last_logon < ?/ t, a# y) O9 x, V2 V5 }6 }
    5                          and bill_overdue = ?9 N2 J+ [! a6 b9 q4 Z2 _- ^+ j' i
    6                       """, '2001-01-01', 'y')
    1 i  M9 V6 R, u6 b/ i) b, T
    % I% W% B# H) s5 l' n这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    * p8 {: W( U- v  L0 k, B/ u9 B" u3 g8 @
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:: i9 V7 Z; a  Q# o, K; y
    1        cursor.execute("""
    & x! q1 a  Y) C1 f2                       select user_id, user_name( `9 w# P5 O$ L# z# T
    3                         from users1 K2 |" k1 x5 Q* n6 M, O( B
    4                        where last_logon < ?
    ! c% @4 H% p0 x7 s$ J! A4 w5                          and bill_overdue = ?
    " \; a  B2 d; T0 X- E6                       """, ['2001-01-01', 'y'])6 F1 @, S# j! M9 Z

    - M* N' W" w; L7 I1 \$ }; h1        cursor.execute("select count(*) as user_count from users where age > ?", 21)3 c% V6 G9 W6 d$ Z
    2        row = cursor.fetchone()
    3 C, z7 _; O# K; q. o: v& w3        print '%d users' % row.user_count6 b! d6 i# q& S( U8 B% E6 r; ]
    5 G" Y4 p' L, y' ]+ n! m: B

    0 e8 _. s+ Z: t% @5 l
    7 s: K0 }& p3 m, `5 ^' L1 z4、数据插入
    $ Y; k- s( {2 x4 V" I$ k. N% h& U$ D' `
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。0 S' R, }" y8 ]- `; ]
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")9 Z, o; C8 K- Q/ j5 C
    2        cnxn.commit()1 {  n( k, {$ `* D+ c
    * b5 [4 H6 d; {
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')9 c# G, |& I6 @" h( C
    2        cnxn.commit()) K8 ?& c; A, X* E6 b
    $ d3 {! @+ m7 ^" _+ F# }: J$ Z7 B2 c
    注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。& v6 a4 R. ]( g% t5 z

    * q# L* T2 p0 g5、数据修改和删除
    7 w4 I+ |% x, M3 f
    3 e1 w* c3 T4 c; C. a* A& e' c1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。8 U; s- j3 L% p1 c+ Z7 W. w
    1        cursor.execute("delete from products where id <> ?", 'pyodbc'). R: g% X' s% G3 |9 w
    2        print cursor.rowcount, 'products deleted'
    5 l8 i( f( x9 B! t3        cnxn.commit(). L# t# d) ?; n
    7 @- f" e5 y6 F/ I7 x2 Z
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    ( c1 x4 V& z# F! `3 P  h1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    & R  c4 G- ?5 t  w" y2        cnxn.commit()
    - w2 b. \- r' x0 _
    # t6 Y8 R, c0 ^1 M1 f% ^8 i同样要注意调用cnxn.commit()函数
    1 E4 g" [! \" D' u* U4 B: X
    6 T% p, n" r# N! ~" ?8 k8 G6、小窍门
    ( v3 N3 W8 A1 s) P9 |0 g
    7 k' S" _- q) F, s8 f) b. S: |1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:) f; A" X- g. G% z3 _- `+ Y
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount0 m; y% {2 N1 Z0 d& {
    3 x: w5 S% T# h7 h/ O, }' c8 z
    2)假如你使用的是三引号,那么你也可以这样使用:$ v# w- i2 B% T9 A
    1        deleted = cursor.execute("""
    0 K2 `* O9 `' v& Z4 C! P( E, P7 g2                                 delete
    : Y  ^' ^2 ^( M! {) V/ s3 x+ @- g3                                   from products
    ! }& j% T6 n4 z% o, U4                                  where id <> 'pyodbc'9 k  U6 O( T5 ]* x1 D( o2 b, \% L8 v
    5                                 """).rowcount
    / G$ L# L6 f! A! o, |2 C
    ' r/ z. @3 x- ?, o& g% [& y; i. k3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    . Y/ |2 T: D* d1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    " c* e' D6 P  M' r6 a4 c2        print '%s users' % row.user_count
    6 E2 @3 {; X0 {+ J. _" U) z; P5 I- `8 [! V4 Z& d. i0 _& }
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。
    & Y+ e6 W5 Y  e, R1 i% m% l1        count = cursor.execute("select count(*) from users").fetchone()[0]6 H9 f+ A& J& g; Z
    2        print '%s users' % count7 p8 z; }' p  P
    ; N: p' r6 G7 x6 ]# m; z% W4 V
    如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。% R0 H$ [) j7 k1 p/ T1 e. }8 l
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    1 W: F4 U7 D4 N' F5 c0 }/ u% ]# n9 v- h7 ^
    在这个例子里面,如果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:01 , Processed in 0.384134 second(s), 49 queries .

    回顶部