QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6270|回复: 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、连接数据库
    3 [0 Y, `# {. e* r2 y' m- U% J3 I# u
    . g3 I" }# V" w) U" \1)直接连接数据库和创建一个游标(cursor); s3 u7 P- ]" G) s$ d2 E
    1        cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=meWD=pass')0 T0 I8 q9 e7 \
    2        cursor = cnxn.cursor()
    , Z- q, B% G* W# v3 C! q% x* c3 l# p8 _
    2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。
    / }, C/ {5 ~! q1        cnxn = pyodbc.connect('DSN=testWD=password')
    + F: V8 x- O" P& X/ l* \5 e' E2        cursor = cnxn.cursor()3 V  C7 o' N; V, L. s( A
    & ^% u  U  J% U% s0 \+ B
    关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节
    7 j. M' {" I; n% Z% B0 p
    . n9 H( C4 r1 m% p2、数据查询(SQL语句为 select ...from..where)& w; M' i  g! b1 n. d7 N6 n
    - d6 m+ w) o9 N, ^: `3 A1 G; g
    1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchall和fetchmany将返回一个空列。
    : r1 N' o% u7 Z1        cursor.execute("select user_id, user_name from users")
    3 W0 c! l& ^% K. \5 K" n& ]/ V2        row = cursor.fetchone(): M2 ~. u/ r( J9 ^* ?
    3        if row:9 u/ D* R( g7 Q/ h$ _. g" u! ^
    4            print row
    2 d, O4 G( I! Y* \
    / D! y% F/ o" L" v1 ~9 H2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。4 _2 d8 U' [* |2 N* p2 v- w' E
    1        cursor.execute("select user_id, user_name from users"), n1 F5 ]$ c, u
    2        row = cursor.fetchone()
    + \9 l5 z" T7 M3        print 'name:', row[1]          # access by column index
    * O6 P" {% @- v6 A( o4        print 'name:', row.user_name   # or access by name
    * M  |+ u) o7 n6 D8 m/ K+ N8 {1 c# |# n( Z2 X- ~
    3)如果所有的行都被检索完,那么fetchone将返回None.
    : {6 E0 W2 g& O5 b; U% j+ l' ?1 s3 R1        while 1:
    3 G2 ?1 ?* \/ E/ n8 D1 V2            row = cursor.fetchone()6 Y& {; {8 Z  X8 M
    3            if not row:
    & E: k* R* x1 O" _$ I6 [. J4                break  J9 T3 \) J6 x1 {+ b/ e
    5            print 'id:', row.user_id0 g, V0 y$ l3 J6 O. B+ o1 ~

    # C6 `( h( m( g4 L: I8 b# g4 \. J; j4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)/ X; f( m0 y4 {" y
    1        cursor.execute("select user_id, user_name from users")" U. A! y" }1 k  d  U5 y/ }$ D
    2        rows = cursor.fetchall()
    1 t# s; K8 Q  f; w* U3        for row in rows:
      @/ Z8 l9 O* i# R# I* N4            print row.user_id, row.user_name
    7 O* B4 w& k9 W" {. l4 ^0 s! ^/ O0 ]2 e: ^2 y. e
    5)如果你打算一次读完所有数据,那么你可以使用cursor本身。* E  ^2 w/ N" _- P: T$ `
    1        cursor.execute("select user_id, user_name from users"):
    / T( |, `: L" L3 J) s9 M1 t& u2        for row in cursor:
    ! ~; k8 V' |6 ^& _4 C3            print row.user_id, row.user_name1 H4 r" U% e0 G3 r" L

    # a& o+ q! `' a6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:1 ]8 K7 ?+ ]# x, M
    1        for row in cursor.execute("select user_id, user_name from users"):
    6 H5 w/ p5 |! D. _. Y2            print row.user_id, row.user_name
    - m: \" s6 s0 r  c
    . a) a" @+ R8 t* K, S3 G3 ~! V7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:# S/ `+ t* P+ p' u9 F, V! Q3 Q5 A( U
    1        cursor.execute("""# n6 d# A) o6 K  A- o( j
    2                       select user_id, user_name' L& O1 x' `, W; V$ @- Y' E- }
    3                         from users
    7 T+ i' c) X+ B, p4                        where last_logon < '2001-01-01'
    5 G- t6 D2 G. x; i  d4 W' F5                          and bill_overdue = 'y'
    , A' ~8 w- c8 M: T3 a5 _6                       """)2 A3 ?! ~/ q  z/ e, g  Z& P

    ) T) t" q; H7 y; ?. c# X3、参数0 v0 R# n$ V! S2 J* r% q
    6 T2 R# |. d( f6 c6 Q- ]6 v
    1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。( k$ ^# A5 R) ~# R$ O1 e
    1        cursor.execute("""
    6 u- G- `7 R( G9 c3 {2                       select user_id, user_name
    & G1 D- ?. P8 k! W% A4 y( b- ^3                         from users
    6 ], r% ?& F# V' m+ o4                        where last_logon < ?1 [7 Y$ A7 i$ ~/ h8 ]4 E0 L& e+ O- L/ e
    5                          and bill_overdue = ?1 Z0 J9 F( M* x0 W4 u
    6                       """, '2001-01-01', 'y')
    ) Z0 K  E! C7 Y0 ^) p# g) B8 E5 [; X
    " [! q) R$ O0 h/ B这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。
    5 X8 ^3 _  _- O8 ]7 P9 V0 \( K6 i4 @
    3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:; f2 x5 h+ R& r$ x+ B8 Z+ D
    1        cursor.execute("""& v; x% E+ T# E. s
    2                       select user_id, user_name0 l- q5 x. `: n4 t$ S
    3                         from users
    " _# e9 V8 ~3 v4                        where last_logon < ?) p% Y: F" k  I" a6 v
    5                          and bill_overdue = ?
    7 ~6 ^+ X- a4 T4 B/ ?$ p6                       """, ['2001-01-01', 'y'])
    " Z5 c) U3 s5 B7 O3 v% }3 T& {; Q7 z
    ' L' Y9 \  o* r1        cursor.execute("select count(*) as user_count from users where age > ?", 21)8 Q% V  k; d- L! W
    2        row = cursor.fetchone()/ @9 n2 {- J5 n$ ]& B
    3        print '%d users' % row.user_count4 l1 o: J! v# O+ L7 i
    $ w8 n+ I* M9 x
    : B. `3 ^: U' f/ j

    7 M% O( j- A- N( F% x, L0 R- i4、数据插入
    ( `5 s' y/ ^. ^5 k5 @9 D( n2 b; b9 V" Q' d( k8 f! `, D* h/ i
    1)数据插入,把SQL插入语句传递给cursor的execute函数,可以伴随任何需要的参数。& z6 a6 D" o: t2 a4 D6 K3 l; m8 [
    1        cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")9 A; T0 P$ {/ l) [6 T5 j
    2        cnxn.commit()# b- Y6 Q6 T) E5 c3 G
    / _8 i  ?" l0 D0 Q' D
    1        cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
    9 u0 L1 P. y, Y$ e. L2        cnxn.commit()* o! i8 B# A- P' P

    . m# O) d) W* j  {2 y9 `注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。  G" r  n8 b) H: e4 d7 }
    7 s  A' v3 ^( ^
    5、数据修改和删除# v& s7 s7 ]2 t& [  l1 h$ A6 Y  \
    # f) o: {. ?$ G3 _3 x  G0 c
    1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。. i5 [9 `9 e: ?: v* u$ q3 N- a
    1        cursor.execute("delete from products where id <> ?", 'pyodbc')
    / i/ Q7 n1 J2 f) \2        print cursor.rowcount, 'products deleted'
    . f0 V/ F, F# w3        cnxn.commit()
    ; n" l* M/ @/ P. G+ u- `$ @5 N) x3 B3 }
    2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)
    1 x: v+ q# H! S$ J1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount
    1 Q% C! c) v" c& G5 W2        cnxn.commit()% H3 ~6 l3 q& A, i6 L. R; D2 H! `

    8 G3 W) r* K1 j0 j% n- h, w同样要注意调用cnxn.commit()函数
    ; ?, I5 V+ F, u* }: v( Q8 T7 s. ?
    , T* R# I! U# `" Z& s  D* A6、小窍门
    0 B8 V5 ~5 j5 }& Y5 g9 Z5 i+ P
    3 w, T! d: v- r+ k) o1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:3 q$ b6 L& ?: e" K- }9 [
    1        deleted = cursor.execute("delete from products where id <> 'pyodbc'").rowcount( f, A8 s$ E0 m+ C

    7 {% x- R  g; N, ^. F/ w- f$ C, G2)假如你使用的是三引号,那么你也可以这样使用:$ l& K1 B- Z: B
    1        deleted = cursor.execute("""' _5 O3 B* M, }
    2                                 delete9 L3 {% [! J( k3 U& o& @
    3                                   from products$ ~' n4 B- l0 c2 {
    4                                  where id <> 'pyodbc'" \; y  W" f9 g: _" e7 m9 {
    5                                 """).rowcount
    " H2 X( L6 e" J4 H+ e) r' X) o9 Y9 I2 {" {2 m+ n$ ]
    3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用“as”关键字来取个列名(下面SQL语句的“as name-count”)! Y& X( j( W) i, P- x6 H' E
    1        row = cursor.execute("select count(*) as user_count from users").fetchone()
    3 s$ J7 q+ Z' R+ N9 e2        print '%s users' % row.user_count
    8 A5 I( i! b/ r$ K* d5 K+ Y" R; N- w' o$ f! g' o$ f
    4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。5 _* J+ V- w9 P: l' b  q+ P
    1        count = cursor.execute("select count(*) from users").fetchone()[0]# }' M5 d  g: J" P0 O. F8 o
    2        print '%s users' % count5 m  ~7 ^. j3 |# I+ L; U9 B

    1 a) }. a" u- |5 ?+ l7 I( V如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。' W/ Z9 d& [9 T% g5 J) H* p
    1        maxid = cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]
    . C' J( W4 S$ @" T4 B7 V# ^# `9 p; y$ ~0 b2 U* v5 l# o5 _' m+ 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-9 04:08 , Processed in 0.292180 second(s), 50 queries .

    回顶部