QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6263|回复: 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、连接数据库
    1 ^( U. l1 R! {) J& a4 p) P  m
    * h5 a, p. V! R* H8 O1)直接连接数据库和创建一个游标(cursor)4 j3 Q3 x3 J$ H
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass'). Z4 }1 J" I3 X; {$ m" a/ l7 N! ~
    2        cursor = cnxn.cursor()4 V, w! h0 e; C. D' p8 I$ g

    4 x0 U  f# ~/ a! b( V2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。% J' b* ?3 Z8 w; g9 q
    1        cnxn = pyodbc.connect('DSN=testWD=password')
    9 B* Y' d# D4 n' j% H( z) m2        cursor = cnxn.cursor()
    / ?( ^! [: W$ d
    ; v8 I' z/ D5 e8 Y8 S; @* q  h! Y关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节- `/ r4 S5 d' }' l" A9 c
    / E, T- @; l/ t/ S
    2、数据查询(SQL语句为 select ...from..where)
    1 f( V* f- G- T5 f& D9 B# G* S% n, y- ^4 A. k$ C8 T+ v4 U
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    7 {; g" y5 N: T/ W- Y5 y9 g1        cursor.execute("select user_id, user_name from users")/ Z) a% A# g, c8 ?7 x
    2        row = cursor.fetchone()& Z8 o' V2 m/ F/ C9 d1 a) W" E4 s& ^/ }+ q
    3        if row:
    * t: R; F. l$ [/ x$ _0 ~# K4            print row
    ; K, e- @; K9 a) N& `; ~) g$ x( L* \1 Y) O- Q6 q% R  s
    2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。* o: s$ A- |; X9 R$ o
    1        cursor.execute("select user_id, user_name from users")2 M. e! y( s/ ]& b( z
    2        row = cursor.fetchone()
      _: Z7 x) `5 Z, b  V+ E3        print 'name:', row[1]          # access by column index* Q1 o4 R' d, S' B# W
    4        print 'name:', row.user_name   # or access by name
    # N7 r  _4 ?! G3 M" w$ n
    / [. \  H2 h) J3)如果所有的行都被检索完,那么fetchone将返回None.3 X) m; A5 J: F
    1        while 1:
    ( Y- }4 V- V- `% Q/ K# B( T4 ~2            row = cursor.fetchone()4 t" p& z9 _, P; _; _2 v( [
    3            if not row:8 a# h! n. H: U$ q6 H0 ?
    4                break
    3 F4 |  g& D' R. L$ W- v7 T5            print 'id:', row.user_id
    7 L/ T1 w) M; N1 P; R( ^- R! h4 K' m4 G( f. l( D( L
    4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)
    ! x: ~; g# Z' Y9 p$ L8 d1        cursor.execute("select user_id, user_name from users")( r: {8 S. F( d  t7 T
    2        rows = cursor.fetchall()
    ) H4 `/ b5 @* E, |! m3        for row in rows:
    2 t% p9 ~. F7 M- J3 g4            print row.user_id, row.user_name
    * O: j  h- O6 a% s) c: y" G! G" C, g& g7 G, F# L
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。0 d, y% q6 Q6 L
    1        cursor.execute("select user_id, user_name from users"):
    + z' ^/ f! _* |$ H8 r2        for row in cursor:; n% L3 _+ f% C
    3            print row.user_id, row.user_name/ s, ^( C# w- f  A% t

    . o4 v! |" s. j4 D6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:
    8 i5 w. }$ \0 ~1        for row in cursor.execute("select user_id, user_name from users"):2 K+ b( r  h$ P' k; t! N/ e
    2            print row.user_id, row.user_name' j. V% R+ @* o

    1 p5 L: }5 e5 |0 |7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:- ~- h, ?- {& ^# p- o1 u
    1        cursor.execute("""
    ! x4 N) ?% Q7 L4 v6 v2 K2                       select user_id, user_name
    1 l" J; [  _* l$ x3                         from users- _# U6 i6 F9 Q
    4                        where last_logon < '2001-01-01': M4 G. A/ U: r3 V6 v* C4 D- g9 C
    5                          and bill_overdue = 'y'( o7 @4 ~% _( `0 U
    6                       """)
    4 v7 z3 X1 b2 U# F/ {7 b9 N/ Y% i+ v& {5 |! ]: I
    3、参数. N. `; T* D3 L( C' b

    ' r' ^5 P3 @5 X8 c  |! \1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。
    3 A( ^! X6 _9 v; S6 N( P- z) h1        cursor.execute("""
    ( E( T4 c5 E" x0 q% u- l" x0 T2                       select user_id, user_name
    . }3 j1 A9 x; n3                         from users
    . Y" P: `8 x* K0 d' h4                        where last_logon < ?# o4 R2 |: _" _9 }# T
    5                          and bill_overdue = ?/ E9 h. O, J, x% E8 k4 k0 L
    6                       """, '2001-01-01', 'y')
    $ Q( O& H" y& U( a  D
    6 \5 v) _& A6 y8 Q. N1 O这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。6 O; ~9 T. B# b5 s8 y* |* z* q1 `
    9 f4 O; n* n: _) i. w, n
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:
    2 v0 i6 N( q4 g& _+ A( D5 ~1        cursor.execute("""
    . E: V9 @, e5 R6 U; x( A( O5 z2                       select user_id, user_name
    " s# X2 E9 _9 |3 S; Q1 @0 ~* e3                         from users$ n; f# d. P8 e( H) m1 A
    4                        where last_logon < ?
    1 V9 x7 I) K+ I! x, j$ ]' n5                          and bill_overdue = ?2 j7 s. \6 s9 r: j% v$ y0 x& R
    6                       """, ['2001-01-01', 'y'])7 c* x' F+ O5 x, h: f, F, S
    0 d2 o! ]) p/ t! O- h
    1        cursor.execute("select count(*) as user_count from users where age > ?", 21)
    8 g2 {( ?, @# }( F' z7 y2        row = cursor.fetchone()
    : K/ ?- Q5 o" z3        print '%d users' % row.user_count
    4 \6 g+ @6 L9 z; }1 B* K4 r3 ]* n0 `: y- L) }* P

    8 @" s+ B3 E3 O: x. V: Y$ t' o; B
    9 N1 o! J6 ~+ U" m. T# v; I4、数据插入1 h6 G$ }  |: F4 ?

    1 Z" [1 Z& F1 ~5 F1 F* y8 t' t1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。
    ( {: i* {# w5 {% R1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
    4 U+ T+ D* K4 n7 y7 V* X5 G7 [2        cnxn.commit()
      g9 x, Y" P: V$ v8 e
    5 M4 f: C$ |. w2 }4 |) \6 l7 ?1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
    0 H$ _6 D( _" w" |; y2        cnxn.commit()# q  }  S% c" a6 H2 N

    ( u0 d0 ~0 f; G9 z- a注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。- j3 u* c  ]3 V& M& U3 d" t: j

    ) s- i- C' D2 P5 U! f1 d5、数据修改和删除
    + m! W; a* m* S5 n3 N3 r! K0 Z
    / x$ o% A7 r- E& r4 G1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。
    5 v& K- k& b" J) r* P) }1        cursor.execute("delete from products where id <> ?", 'pyodbc')) _: U0 U. Q+ L. y' z
    2        print cursor.rowcount, 'products deleted'3 S% J4 K. v7 X
    3        cnxn.commit()" S& L$ a; V3 X# C+ \
    8 x6 `. L- e: ^. H0 n- G1 [
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)/ p' o2 f8 y8 Y' E: ?7 ?
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount  L0 w4 E+ C% U, @5 J7 n' E
    2        cnxn.commit()# Q3 y5 ]' Q  a: j
    5 S. H  g  I* I3 K0 C
    同样要注意调用cnxn.commit()函数, Y& z! U9 h* s* v5 E- _( j3 p

    0 u, c" C$ u# |6、小窍门9 b& `/ r' a. L- ^  }' ^; F
    " R( e1 K. O) K* S/ D" }4 `9 g
    1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:- B, s9 B1 e( z- h1 h/ l
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    7 z/ j1 p% q$ q2 \* r, p. A, U( D" d7 r, w7 F* t
    2)假如你使用的是三引号,那么你也可以这样使用:5 k; u; T2 {* i0 K/ \' N8 ?
    1        deleted = cursor.execute("""
    + W* z! R* E% |* O8 q) {2                                 delete
    - E1 b/ R' B8 k3 I* {/ h3                                   from products
    " V2 F* e; a9 z9 N* L! ]0 p4                                  where id <> 'pyodbc'9 m: ]5 O6 Y" H& c+ z+ E
    5                                 """).rowcount5 w2 e- K0 G4 G# V$ I8 h7 U/ K
    : B, O' i7 W) s, N; A! V
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)
    % I7 [( q3 P$ l, v! E1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    0 G3 F. D+ T7 r3 Z$ m4 T- N2        print '%s users' % row.user_count
    $ A2 x! s" H( d. b# M. Z( U0 F0 a
    ; m, I: B/ w7 b% Z7 o& k4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。2 n6 c) Z. A2 e: N8 p. X5 L
    1        count = cursor.execute("select count(*) from users").fetchone()[0]
      `6 U" `. ]9 K0 q8 I2        print '%s users' % count
    ) S- q- i/ y, N! I
    " t1 I$ M4 @0 E% ]& ~/ p5 p; y如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。" |2 G  q. p: U) d
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    5 W5 p  Z. B, h" A1 j& ~8 s9 K( o
    ) F0 h/ y. q* z9 V) q& i在这个例子里面,如果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.343672 second(s), 49 queries .

    回顶部