Академический Документы
Профессиональный Документы
Культура Документы
1 documentation
http://initd.org/psycopg/docs/usage.html
The main entry points o Psycopg are! The unction connect() creates a new database session and returns a new connection instance. The class connection encapsulates a database session. It allows to! create new cursor s using the cursor() method to e"ecute database commands and #ueries$ terminate transactions using the methods commit() or rollback() . The class cursor allows interaction with the database! send commands to the database using methods such as execute() and executemany() $ retrieve data rom the database by iteration or using methods such as fetchone() $ fetchmany() $ fetchall() .
1 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
>>> cur.execute( ... """INSERT INTO some_table (an_int, a_date, a_string) ... VALUES (%s, %s, %s);""", ... (10, datetime.date(2005, 11, 18), "O'Reilly"))
*amed arguments are supported too using %(name)s placeholders. +sing named arguments the values can be passed to the #uery in any order and many placeholders can use the same values!
>>> cur.execute( ... """INSERT INTO some_table (an_int, a_date, another_date, a_string) ... VALUES (%(int)s, %(date)s, %(date)s, %(str)s);""", ... {'int': 10, 'str': "O'Reilly", 'date': datetime.date(2005, 11, 18)})
%%
,hile the mechanism resembles regular Python strings manipulation$ there are a ew subtle di erences you should care about when passing parameters to a #uery! The Python string operator % is not used! the execute() method accepts a tuple or dictionary o values as second parameter. Never use % or + to merge values into #ueries. The variables placeholder must always be a %s $ even i a di erent placeholder -such as a %d or integers or %f or loats. may loo/ more appropriate!
>>> cur.execute("INSERT INTO numbers VALUES (%d)", (42,)) # WRONG >>> cur.execute("INSERT INTO numbers VALUES (%s)", (42,)) # correct
0or positional variables binding$ the second argument must always be a sequence$ even i it contains a single variable. And remember that Python re#uires a comma to create a single element tuple!
>>> >>> >>> >>> cur.execute("INSERT cur.execute("INSERT cur.execute("INSERT cur.execute("INSERT INTO INTO INTO INTO foo foo foo foo VALUES VALUES VALUES VALUES (%s)", (%s)", (%s)", (%s)", "bar") ("bar")) ("bar",)) ["bar"]) # # # # WRONG WRONG correct correct
1nly variable values should be bound via this method! it shouldn2t be used to set table or ield names. 0or these elements$ ordinary string ormatting should be used be ore running execute() .
2 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
string constants bounds and re#uires them to be escaped$ whereas in Python single #uotes can be le t unescaped in strings bounded by double #uotes. 0or this reason a na3ve approach to the composition o #uery strings$ e.g. using string concatenation$ is a recipe or terrible problems!
>>> SQL = "INSERT INTO authors (name) VALUES ('%s');" # NEVER DO THIS >>> data = ("O'Reilly", ) >>> cur.execute(SQL % data) # THIS WILL FAIL MISERABLY ProgrammingError: syntax error at or near "Reilly" LINE 1: INSERT INTO authors (name) VALUES ('O'Reilly') ^
I the variable containing the data to be sent to the database comes rom an untrusted source -e.g. a orm published on a web site. an attac/er could easily cra t a mal ormed string$ either gaining access to unauthori4ed data or per orming destructive operations on the database. This orm o attac/ is called %&' in5ection and is /nown to be one o the most widespread orms o attac/ to servers. Be ore continuing$ please print this page as a memo and hang it onto your des/. Psycopg can automatically convert Python ob5ects to and rom %&' literals! using this eature your code will be more robust and reliable. ,e must stress this point! Warning: *ever$ never$ NEVER use Python string concatenation - + . or string parameters interpolation - % . to pass variables to a %&' #uery string. *ot even at gunpoint. The correct way to pass variables in a %&' command is using the second argument o the execute() method!
>>> SQL = "INSERT INTO authors (name) VALUES (%s);" # Note: no quotes >>> data = ("O'Reilly", ) >>> cur.execute(SQL, data) # Note: no % operator
PostgreSQL
NULL bool real double smallint integer bigint numeric varchar text
Strings adaptation
3 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
Python
buffer memoryview bytearray bytes
PostgreSQL
bytea
Bu er protocol
date time datetime timedelta list tuple namedtuple dict
Lists adaptation Tuples adaptation Composite types casting Hstore data type ange data types !S"N adaptation ##$D data type
The mapping is airly customi4able! see %dapting new &ython types to S'L synta( and Type casting o) S'L types into &ython objects. 8ou can also ind a ew other speciali4ed adapters in the psycopg2.extras module.
Constants adaptation
Python
None
True
and
False
>>> cur.mogrify("SELECT %s, %s, %s;", (None, True, False)) 'SELECT NULL, true, false;'
umbers adaptation
Python numeric ob5ects numerical representation!
int $ long $ float $ Decimal
>>> cur.mogrify("SELECT %s, %s, %s, %s;", (10, 10L, 10.0, Decimal("10.00"))) 'SELECT 10, 10, 10.0, 10.00;'
9eading rom the database$ integer types are converted into int $ loating point types are converted into float $ numeric : decimal are converted into Decimal . Note: %ometimes you may pre er to receive numeric data as float instead$ or per ormance reason or ease o manipulation! you can con igure an adapter to cast &ostgreS'L numeric to &ython )loat. This o course may imply a loss o precision. See also: Postgre%&' numeric types
Strings adaptation
4 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
Python str and unicode are converted into the %&' string synta". unicode ob5ects - str in Python ;. are encoded in the connection encoding be ore sending to the bac/end! trying to send a character not supported by the encoding will result in an error. Data is usually received as str -i*e* it is decoded on Python ;$ le t encoded on Python 2.. However it is possible to receive unicode on Python 2 too! see #nicode handling.
!nicode handling
Psycopg can e"change +nicode data with a Postgre%&' database. Python unicode ob5ects are automatically encoded in the client encoding de ined on the database connection -the Postgre%&' encoding$ available in connection.encoding $ is translated into a Python codec using the encodings mapping.!
>>> print u, type(u) <type 'unicode'> >>> cur.execute("INSERT INTO test (num, data) VALUES (%s,%s);", (74, u))
,hen reading data rom the database$ in Python 2 the strings returned are usually < bit ob5ects encoded in the database client encoding!
>>> print conn.encoding UTF8 >>> cur.execute("SELECT data FROM test WHERE num = 74") >>> x = cur.fetchone()[0] >>> print x, type(x), repr(x) <type 'str'> '\xc3\xa0\xc3\xa8\xc3\xac\xc3\xb2\xc3\xb9\xe2\x82\xac' >>> conn.set_client_encoding('LATIN9') >>> cur.execute("SELECT data FROM test WHERE num = 74") >>> x = cur.fetchone()[0] >>> print type(x), repr(x) <type 'str'> '\xe0\xe8\xec\xf2\xf9\xa4'
str
In Python ; instead the strings are automatically decoded in the connection encoding $ as the str ob5ect can represent +nicode characters. In Python 2 you must register a typecaster in order to receive unicode ob5ects!
>>> psycopg2.extensions.register_type(psycopg2.extensions.UNICODE, cur) >>> cur.execute("SELECT data FROM test WHERE num = 74") >>> x = cur.fetchone()[0] >>> print x, type(x), repr(x) <type 'unicode'> u'\xe0\xe8\xec\xf2\xf9\u20ac'
In the above e"ample$ the UNICODE typecaster is registered only on the cursor. It is also possible to register typecasters on the connection or globally! see the unction register_type() and Type casting o) S'L types into &ython objects or details. Note: In Python 2$ i you want to uni ormly receive all your database input in +nicode$
5 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
you can register the related typecasters globally as soon as Psycopg is imported!
import psycopg2 import psycopg2.extensions psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
Binary adaptation
Python types representing binary ob5ects are converted into Postgre%&' binary string synta"$ suitable or bytea ields. %uch types are buffer -only available in Python 2.$ memoryview -available rom Python 2.=.$ bytearray -available rom Python 2.>. and bytes -only rom Python ;! the name is available rom Python 2.> but it2s only an alias or the type str .. Any ob5ect implementing the 9evised Bu er Protocol should be usable as binary type where the protocol is supported -i.e. rom Python 2.>.. 9eceived data is returned as buffer -in Python 2. or memoryview -in Python ;.. 6hanged in version 2.?! only strings were supported be ore. 6hanged in version 2.?.@! can parse the Ahe"2 ormat rom B.0 servers without relying on the version o the client library. Note: In Python 2$ i you have binary data in a ield using the psycopg2.Binary wrapper!
str
mypic = open('picture.png', 'rb').read() curs.execute("insert into blobs (file) values (%s)", (psycopg2.Binary(mypic),))
Warning: %ince version B.0 Postgre%&' uses by de ault a new Che"D ormat to emit bytea ields. %tarting rom Psycopg 2.?.@ the ormat is correctly supported. I you use a previous version you will need some e"tra care when receiving bytea rom Postgre%&'! you must have at least libp# B.0 installed on the client or alternatively you can set the byteaEoutput con iguration parameter to escape $ either in the server con iguration ile or in the client session -using a #uery such as SET bytea_output TO escape; . be ore receiving binary data.
! de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
>>> cur.mogrify("SELECT %s, %s, %s;", (dt, dt.date(), dt.time())) "SELECT '2010-02-08T01:40:27.425337', '2010-02-08', '01:40:27.425337';" >>> cur.mogrify("SELECT %s;", (dt - datetime.datetime(2010,1,1),)) "SELECT '38 days 6027.425337 seconds';"
*ote that only time 4ones with an integer number o minutes are supported! this is a limitation o the Python datetime module. A ew historical time 4ones had seconds in the +T6 o set! these time 4ones will have the o set rounded to the nearest minute$ with an error o up to ;0 seconds.
>>> cur.execute("SET TIME ZONE 'Asia/Calcutta';") # offset was +5:53:20 >>> cur.execute("SELECT '1930-01-01 10:30:45'::timestamptz;") >>> cur.fetchone()[0].tzinfo psycopg2.tz.FixedOffsetTimezone(offset=353, name=None)
6hanged in version 2.2.2! time4ones with seconds are supported -with rounding.. Previously such time4ones raised an error. In order to deal with them in previous versions use psycopg2.extras.register_tstz_w_secs() .
to
class InfDateAdapter: def __init__(self, wrapped): self.wrapped = wrapped def getquoted(self): if self.wrapped == datetime.date.max: return "'infinity'::date" elif self.wrapped == datetime.date.min: return "'-infinity'::date" else: return psycopg2.extensions.DateFromPy(self.wrapped).getquoted()
7 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
psycopg2.extensions.register_adapter(datetime.date, InfDateAdapter)
1 course it will not be possible to write the value o infinity will be stored instead.
date.max
Lists adaptation
Python lists are converted into Postgre%&' ARRAY s!
>>> cur.mogrify("SELECT %s;", ([10, 20, 30], )) 'SELECT ARRAY[10,20,30];'
Note: 8ou can use a Python list as the argument o the IN operator using the Postgre%&' A*8 operator.
ids = [10, 20, 30] cur.execute("SELECT * FROM data WHERE id = ANY(%s);", (ids,))
0urthermore ANY can also wor/ with empty lists$ whereas IN () is a %&' synta" error. Note: 9eading bac/ rom Postgre%&'$ arrays are converted to lists o Python ob5ects as e"pected$ but only i the items are o a /nown type. Arrays o un/nown types are returned as represented by the database -e.g. {a,b,c} .. I you want to convert the items into Python ob5ects you can easily create a typecaster or array o) un+nown types.
Tuples adaptation
Python tuples are converted into a synta" suitable or the %&' IN operator and to represent a composite type!
>>> cur.mogrify("SELECT %s IN %s;", (10, (10, 20, 30))) 'SELECT 10 IN (10, 20, 30);'
Note: %&' doesn2t allow an empty list in the IN operator$ so your code should guard against empty tuples. Alternatively you can use a &ython list. I you want Postgre%&' composite types to be converted into a Python tuple:namedtuple you can use the register_composite() unction. *ew in version 2.0.>! the tuple IN adaptation. 6hanged in version 2.0.@?! the tuple IN adapter is always active. In previous releases it was necessary to import the extensions module to have it registered. 6hanged in version 2.;! namedtuple instances are adapted li/e regular tuples and can thus be used to represent composite types.
" de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
Transactions control
In Psycopg transactions are handled by the connection class. By de ault$ the irst time a command is sent to the database -using one o the cursor s created by the connection.$ a new transaction is created. The ollowing database commands will be e"ecuted in the conte"t o the same transaction F not only the commands issued by the irst cursor$ but the ones issued by all the cursors created by the same connection. %hould any command ail$ the transaction will be aborted and no urther command will be e"ecuted until a call to the rollback() method. The connection is responsible or terminating its transaction$ calling either the commit() or rollback() method. 6ommitted changes are immediately made persistent into the database. 6losing the connection using the close() method or destroying the connection ob5ect -using del or letting it all out o scope. will result in an implicit rollbac/. It is possible to set the connection in autocommit mode! this way all the commands e"ecuted will be immediately committed and no rollbac/ is possible. A ew commands -e.g. CREATE DATABASE $ VACUUM .... re#uire to be run outside any transaction! in order to be able to run these commands rom Psycopg$ the connection must be in autocommit mode! you can use the autocommit property - set_isolation_level() in older versions.. Warning: By de ault even a simple SELECT will start a transaction! in longGrunning programs$ i no urther action is ta/en$ the session will remain Cidle in transactionD$ a condition non desiderable or several reasons -loc/s are held by the session$ tables bloat..... 0or long lived scripts$ either ma/e sure to terminate a transaction as soon as possible or use an autocommit connection. A ew other transaction properties can be set sessionGwide by the connection ! or instance it is possible to have readGonly transactions or change the isolation level. %ee the set_session() method or all the details.
with
statement
%tarting rom version 2.H$ psycopg22s connections and cursors are conte(t managers and can be used with the with statement!
with psycopg2.connect(DSN) as conn: with conn.cursor() as curs: curs.execute(SQL)
,hen a connection e"its the with bloc/$ i no e"ception has been raised by the bloc/$ the transaction is committed. In case o e"ception the transaction is rolled bac/. In no case the connection is closed! a connection can be used in more than a with statement and each with bloc/ is e ectively wrapped in a transaction. ,hen a cursor e"its the with bloc/ it is closed$ releasing any resource eventually associated with it. The state o the transaction is not a ected.
de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
10 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
8ou can read the cursor content by calling the unction with a regular$ nonGnamed$ Psycopg cursor!
cur1 = conn.cursor() cur1.callproc('reffunc', ['curname'])
and then use a named cursor in the same transaction to Csteal the cursorD!
cur2 = conn.cursor('curname') for record in cur2: # or cur2.fetchone, fetchmany... # do something with record pass
9eads data )rom a ileGli/e ob5ect appending them to a database table - COPY table FROM file synta".. The source ile must have both read() and readline() method.
copy_to()
,rites the content o a table to a ileGli/e ob5ect - COPY table TO file synta".. The target ile must have a write() method.
copy_expert()
11 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
Allows to handle more speci ic cases and to use all the COPY eatures available in Postgre%&'. Please re er to the documentation o the single methods or details and e"amples.
12 de 13
04/07/2013 1 :07
http://initd.org/psycopg/docs/usage.html
to recogni4e the components o transactions produced by a Mava program. 0or urther details see the documentation or the above methods.
13 de 13
04/07/2013 1 :07