Вы находитесь на странице: 1из 13

Basic module usage Psycopg 2.5.

1 documentation

http://initd.org/psycopg/docs/usage.html

Basic module usage


The basic Psycopg usage is common to all the database adapters implementing the DB API 2.0 protocol. Here is an interactive session showing some o the basic commands!
>>> import psycopg2 # Connect to an existing database >>> conn = psycopg2.connect("dbname=test user=postgres") # Open a cursor to perform database operations >>> cur = conn.cursor() # Execute a command: this creates a new table >>> cur.execute("CREATE TABLE test (id serial PRIMARY KEY, num integer, data varchar);" # Pass data to fill a query placeholders and let Psycopg perform # the correct conversion (no more SQL injections!) >>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", ... (100, "abc'def")) # Query the database and obtain data as Python objects >>> cur.execute("SELECT * FROM test;") >>> cur.fetchone() (1, 100, "abc'def") # Make the changes to the database persistent >>> conn.commit() # Close communication with the database >>> cur.close() >>> conn.close()

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() .

Passing parameters to SQL queries


Psycopg casts Python variables to %&' literals by type. (any standard Python types are already adapted to the correct %&' representation. )"ample! the Python unction call!

1 de 13

04/07/2013 1 :07

Basic module usage Psycopg 2.5.1 documentation

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"))

is converted into the %&' command!


INSERT INTO some_table (an_int, a_date, a_string) VALUES (10, '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)})

,hen parameters are used$ in order to include a literal string.

in the #uery you can use the

%%

,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() .

The problem with the query parameters


The %&' representation or many data types is o ten not the same o the Python string representation. The classic e"ample is with single #uotes in strings! %&' uses them as

2 de 13

04/07/2013 1 :07

Basic module usage Psycopg 2.5.1 documentation

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

Adaptation of Python values to SQL types


(any standard Python types are adapted into %&' and returned as Python ob5ects when a #uery is e"ecuted. The ollowing table shows the de ault mapping between Python and Postgre%&' types! Python
None bool float int long Decimal str unicode

PostgreSQL
NULL bool real double smallint integer bigint numeric varchar text

See also Constants adaptation Numbers adaptation

Strings adaptation

3 de 13

04/07/2013 1 :07

Basic module usage Psycopg 2.5.1 documentation

http://initd.org/psycopg/docs/usage.html

Python
buffer memoryview bytearray bytes

PostgreSQL
bytea

See also Binary adaptation

Bu er protocol
date time datetime timedelta list tuple namedtuple dict

date time timestamp timestamptz interval ARRAY

Date/Time objects adaptation

6omposite types IN synta"


hstore range json uuid

Psycopg2s Range Anything7


uuid

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

and boolean values

True

and

False

are converted into the proper %&' literals!

>>> cur.mogrify("SELECT %s, %s, %s;", (None, True, False)) 'SELECT NULL, true, false;'

umbers adaptation
Python numeric ob5ects numerical representation!
int $ long $ float $ Decimal

are converted into a Postgre%&'

>>> 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

Basic module usage Psycopg 2.5.1 documentation

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

Basic module usage Psycopg 2.5.1 documentation

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)

and orget about this story.

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

ob5ect$ you can pass them to a bytea

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.

"ate#Time ob$ects adaptation


Python builtin datetime $ date $ time $ timedelta are converted into Postgre%&'2s timestamp[tz] $ date $ time $ interval data types. Time 4ones are supported too. The )geni" m".DateTime ob5ects are adapted the same way!
>>> dt = datetime.datetime.now() >>> dt datetime.datetime(2010, 2, 8, 1, 40, 27, 425337)

! de 13

04/07/2013 1 :07

Basic module usage Psycopg 2.5.1 documentation

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';"

See also: Postgre%&' date:time types

Time %ones handling


The Postgre%&' type timestamp with time zone -a./.a. timestamptz . is converted into Python datetime ob5ects with a tzinfo attribute set to a FixedOffsetTimezone instance.
>>> cur.execute("SET TIME ZONE 'Europe/Rome';") # UTC + 1 hour >>> cur.execute("SELECT '2010-01-01 10:30:45'::timestamptz;") >>> cur.fetchone()[0].tzinfo psycopg2.tz.FixedOffsetTimezone(offset=60, name=None)

*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() .

&nfinite dates handling


Postgre%&' can store the representation o an Cin initeD date$ timestamp$ or interval. In inite dates are not available to Python$ so these ob5ects are mapped to date.max $ datetime.max $ interval.max . +n ortunately the mapping cannot be bidirectional so these dates will be stored bac/ into the database with their values$ such as 9999-12-31 . It is possible to create an alternative adapter or dates and other ob5ects to map infinity $ or instance!
date.max

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

Basic module usage Psycopg 2.5.1 documentation

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

in the database anymore!

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

Basic module usage Psycopg 2.5.1 documentation

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

Basic module usage Psycopg 2.5.1 documentation

http://initd.org/psycopg/docs/usage.html

Server side cursors


,hen a database #uery is e"ecuted$ the Psycopg cursor usually etches all the records returned by the bac/end$ trans erring them to the client process. I the #uery returned an huge amount o data$ a proportionally large amount o memory will be allocated by the client. I the dataset is too large to be practically handled on the client side$ it is possible to create a ser,er side cursor. +sing this /ind o cursor it is possible to trans er to the client only a controlled amount o data$ so that a large dataset can be e"amined without /eeping it entirely in memory. %erver side cursor are created in Postgre%&' using the DECLARE command and subse#uently handled using MOVE $ FETCH and CLOSE commands. Psycopg wraps the database server side cursor in named cursors. A named cursor is created using the cursor() method speci ying the name parameter. %uch cursor will behave mostly li/e a regular cursor$ allowing the user to move in the dataset using the scroll() method and to read the data using fetchone() and fetchmany() methods. *ormally you can only scroll orward in a cursor! i you need to scroll bac/wards you should declare your cursor scrollable . *amed cursors are also iterable li/e regular cursors. *ote however that be ore Psycopg 2.? iteration was per ormed etching one record at time rom the bac/end$ resulting in a large overhead. The attribute itersize now controls how many records are etched at time during the iteration! the de ault value o 2000 allows to etch about @00IB per roundtrip assuming records o @0G20 columns o mi"ed number and stringsJ you may decrease this value i you are dealing with huge records. *amed cursors are usually created WITHOUT HOLD $ meaning they live only as long as the current transaction. Trying to etch rom a named cursor a ter a commit() or to create a named cursor when the connection transaction isolation level is set to AUTOCOMMIT will result in an e"ception. It is possible to create a WITH HOLD cursor by speci ying a True value or the withhold parameter to cursor() or by setting the withhold attribute to True be ore calling execute() on the cursor. It is e"tremely important to always close() such cursors$ otherwise they will continue to hold serverGside resources until the connection will be eventually closed. Also note that while WITH HOLD cursors li etime e"tends well a ter commit() $ calling rollback() will automatically close the cursor. Note: It is also possible to use a named cursor to consume a cursor created in some other way than using the DECLARE e"ecuted by execute() . 0or e"ample$ you may have a P':pg%&' unction returning a cursor!
CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS $$ BEGIN OPEN $1 FOR SELECT col FROM test; RETURN $1; END; $$ LANGUAGE plpgsql;

10 de 13

04/07/2013 1 :07

Basic module usage Psycopg 2.5.1 documentation

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

Thread and process safety


The Psycopg module and the connection ob5ects are thread-sa)e! many threads can access the same database either using separate sessions and creating a connection per thread or using the same connection and creating separate cursor s. In DB API 2.0 parlance$ Psycopg is le,el . thread sa)e. The di erence between the above two approaches is that$ using di erent connections$ the commands will be e"ecuted in di erent sessions and will be served by di erent server processes. 1n the other hand$ using many cursors on the same connection$ all the commands will be e"ecuted in the same session -and in the same transaction i the connection is not in autocommit mode.$ but they will be seriali4ed. The above observations are only valid or regular threads! they don2t apply to or/ed processes nor to green threads. libpq connections shouldn2t be used by a or/ed processes$ so when using a module such as multiprocessing or a or/ing web deploy method such as 0ast6KI ma/e sure to create the connections a)ter the or/. 6onnections shouldn2t be shared either by di erent green threads! see Support )or coroutine libraries or urther details.

!sing C'P( T' and C'P( )*'+


Psycopg cursor ob5ects provide an inter ace to the e icient Postgre%&' COPY command to move data rom iles to tables and bac/. The methods e"posed are!
copy_from()

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

Basic module usage Psycopg 2.5.1 documentation

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.

Access to PostgreSQL large ob$ects


Postgre%&' o ers support or large ob5ects$ which provide streamGstyle access to user data that is stored in a special largeGob5ect structure. They are use ul with data values too large to be manipulated conveniently as a whole. Psycopg allows access to the large ob5ect using the lobject class. 1b5ects are generated using the connection.lobject() actory method. Data can be retrieved either as bytes or as +nicode strings. Psycopg large ob5ect support e icient import:e"port with lo_import() and lo_export() libp# unctions. ile system iles using the

Two,Phase Commit protocol support


*ew in version 2.;. Psycopg e"poses the twoGphase commit eatures available since Postgre%&' <.@ implementing the two-phase commit e(tensions proposed by the DB API 2.0. The DB API 2.0 model o twoGphase commit is inspired by the LA speci ication$ according to which transaction IDs are ormed rom three components! a ormat ID -nonGnegative ;2 bit integer. a global transaction ID -string not longer than >? bytes. a branch #uali ier -string not longer than >? bytes. 0or a particular global transaction$ the irst two components will be the same or all the resources. )very resource will be assigned a di erent branch #uali ier. According to the DB API 2.0 speci ication$ a transaction ID is created using the connection.xid() method. 1nce you have a transaction id$ a distributed transaction can be started with connection.tpc_begin() $ prepared using tpc_prepare() and completed using tpc_commit() or tpc_rollback() . Transaction IDs can also be retrieved rom the database using tpc_recover() and completed using the above tpc_commit() and tpc_rollback() . Postgre%&' doesn2t ollow the LA standard though$ and the ID or a Postgre%&' prepared transaction can be any string up to 200 characters long. Psycopg2s Xid ob5ects can represent both LAGstyle transactions IDs -such as the ones created by the xid() method. and Postgre%&' transaction IDs identi ied by an unparsed string. The ormat in which the Lids are converted into strings passed to the database is the same employed by the Postgre%&' MDB6 driver! this should allow interoperation between tools written in Python and in Mava. 0or e"ample a recovery tool written in Python would be able

12 de 13

04/07/2013 1 :07

Basic module usage Psycopg 2.5.1 documentation

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

Вам также может понравиться