From 654be4784cebb849bb2f8cd80b366bac1934e827 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Fri, 16 Nov 2018 17:06:06 +0000 Subject: [PATCH] Dropped examples dir (and some leftover reference to the sandbox dir) Close #645. --- MANIFEST.in | 1 - NEWS | 7 +- examples/binary.py | 90 -------------------- examples/copy_from.py | 174 -------------------------------------- examples/copy_to.py | 104 ----------------------- examples/cursor.py | 63 -------------- examples/dialtone.py | 137 ------------------------------ examples/dict.py | 65 -------------- examples/dt.py | 99 ---------------------- examples/encoding.py | 105 ----------------------- examples/fetch.py | 80 ------------------ examples/lastrowid.py | 59 ------------- examples/lobject.py | 91 -------------------- examples/mogrify.py | 47 ---------- examples/myfirstrecipe.py | 126 --------------------------- examples/notify.py | 45 ---------- examples/simple.py | 54 ------------ examples/somehackers.jpg | Bin 22565 -> 0 bytes examples/threads.py | 161 ----------------------------------- examples/typecast.py | 65 -------------- examples/tz.py | 69 --------------- examples/usercast.py | 126 --------------------------- examples/whereareyou.jpg | Bin 34980 -> 0 bytes psycopg2.cproj | 46 ---------- tox.ini | 2 +- 25 files changed, 4 insertions(+), 1812 deletions(-) delete mode 100644 examples/binary.py delete mode 100644 examples/copy_from.py delete mode 100644 examples/copy_to.py delete mode 100644 examples/cursor.py delete mode 100644 examples/dialtone.py delete mode 100644 examples/dict.py delete mode 100644 examples/dt.py delete mode 100644 examples/encoding.py delete mode 100644 examples/fetch.py delete mode 100644 examples/lastrowid.py delete mode 100644 examples/lobject.py delete mode 100644 examples/mogrify.py delete mode 100644 examples/myfirstrecipe.py delete mode 100644 examples/notify.py delete mode 100644 examples/simple.py delete mode 100644 examples/somehackers.jpg delete mode 100644 examples/threads.py delete mode 100644 examples/typecast.py delete mode 100644 examples/tz.py delete mode 100644 examples/usercast.py delete mode 100644 examples/whereareyou.jpg diff --git a/MANIFEST.in b/MANIFEST.in index bae0dbdd..3fcce43b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,6 @@ recursive-include psycopg *.c *.h *.manifest recursive-include lib *.py recursive-include tests *.py -recursive-include examples *.py somehackers.jpg whereareyou.jpg include doc/README.rst doc/SUCCESS doc/COPYING.LESSER doc/pep-0249.txt include doc/Makefile doc/requirements.txt recursive-include doc/src *.rst *.py *.css Makefile diff --git a/NEWS b/NEWS index 3c783c6b..90477661 100644 --- a/NEWS +++ b/NEWS @@ -1012,7 +1012,7 @@ What's new in psycopg 2.0 beta 7 What's new in psycopg 2.0 beta 6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* Support for named cursors (see examples/fetch.py). +* Support for named cursors. * Safer parsing of time intervals. @@ -1042,7 +1042,7 @@ What's new in psycopg 2.0 beta 5 * All classes have been renamed to exist in the psycopg2._psycopg module, to fix problems with automatic documentation generators like epydoc. -* NOTIFY is correctly trapped (see examples/notify.py for example code.) +* NOTIFY is correctly trapped. What's new in psycopg 2.0 beta 4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1159,8 +1159,7 @@ What's new in psycopg 1.99.10 What's new in psycopg 1.99.9 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* Added simple pooling code (psycopg.pool module); see the reworked - examples/threads.py for example code. +* Added simple pooling code (psycopg.pool module). * Added DECIMAL typecaster to convert postgresql DECIMAL and NUMERIC types (i.e, all types with an OID of NUMERICOID.) Note that the diff --git a/examples/binary.py b/examples/binary.py deleted file mode 100644 index df5d1eab..00000000 --- a/examples/binary.py +++ /dev/null @@ -1,90 +0,0 @@ -# binary.py - working with binary data -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) -from __future__ import print_function - -import sys -import psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -curs = conn.cursor() -try: - curs.execute("CREATE TABLE test_binary (id int4, name text, img bytea)") -except: - conn.rollback() - curs.execute("DROP TABLE test_binary") - curs.execute("CREATE TABLE test_binary (id int4, name text, img bytea)") -conn.commit() - -# first we try two inserts, one with an explicit Binary call and the other -# using a buffer on a file object. - -data1 = {'id':1, 'name':'somehackers.jpg', - 'img':psycopg2.Binary(open('somehackers.jpg').read())} -data2 = {'id':2, 'name':'whereareyou.jpg', - 'img':buffer(open('whereareyou.jpg').read())} - -curs.execute("""INSERT INTO test_binary - VALUES (%(id)s, %(name)s, %(img)s)""", data1) -curs.execute("""INSERT INTO test_binary - VALUES (%(id)s, %(name)s, %(img)s)""", data2) - -# now we try to extract the images as simple text strings - -print("Extracting the images as strings...") -curs.execute("SELECT * FROM test_binary") - -for row in curs.fetchall(): - name, ext = row[1].split('.') - new_name = name + '_S.' + ext - print(" writing %s to %s ..." % (name+'.'+ext, new_name), end=' ') - open(new_name, 'wb').write(row[2]) - print("done") - print(" python type of image data is", type(row[2])) - -# extract exactly the same data but using a binary cursor - -print("Extracting the images using a binary cursor:") - -curs.execute("""DECLARE zot CURSOR FOR - SELECT img, name FROM test_binary FOR READ ONLY""") -curs.execute("""FETCH ALL FROM zot""") - -for row in curs.fetchall(): - name, ext = row[1].split('.') - new_name = name + '_B.' + ext - print(" writing %s to %s ..." % (name+'.'+ext, new_name), end=' ') - open(new_name, 'wb').write(row[0]) - print("done") - print(" python type of image data is", type(row[0])) - -# this rollback is required because we can't drop a table with a binary cursor -# declared and still open -conn.rollback() - -curs.execute("DROP TABLE test_binary") -conn.commit() - -print("\nNow try to load the new images, to check it worked!") diff --git a/examples/copy_from.py b/examples/copy_from.py deleted file mode 100644 index 57986dbf..00000000 --- a/examples/copy_from.py +++ /dev/null @@ -1,174 +0,0 @@ -# copy_from.py -- example about copy_from -# -# Copyright (C) 2002 Tom Jenkins -# Copyright (C) 2005 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import os -import StringIO -import psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -curs = conn.cursor() -try: - curs.execute("CREATE TABLE test_copy (fld1 text, fld2 text, fld3 int4)") -except: - conn.rollback() - curs.execute("DROP TABLE test_copy") - curs.execute("CREATE TABLE test_copy (fld1 text, fld2 text, fld3 int4)") -conn.commit() - -# copy_from with default arguments, from open file - -io = open('copy_from.txt', 'wr') -data = ['Tom\tJenkins\t37\n', - 'Madonna\t\\N\t45\n', - 'Federico\tDi Gregorio\t\\N\n'] -io.writelines(data) -io.close() - -io = open('copy_from.txt', 'r') -curs.copy_from(io, 'test_copy') -print("1) Copy %d records from file object " % len(data) + - "using defaults (sep: \\t and null = \\N)") -io.close() - -curs.execute("SELECT * FROM test_copy") -rows = curs.fetchall() -print(" Select returned %d rows" % len(rows)) - -for r in rows: - print(" %s %s\t%s" % (r[0], r[1], r[2])) -curs.execute("delete from test_copy") -conn.commit() - -# copy_from using custom separator, from open file - -io = open('copy_from.txt', 'wr') -data = ['Tom:Jenkins:37\n', - 'Madonna:\N:45\n', - 'Federico:Di Gregorio:\N\n'] -io.writelines(data) -io.close() - -io = open('copy_from.txt', 'r') -curs.copy_from(io, 'test_copy', ':') -print("2) Copy %d records from file object using sep = :" % len(data)) -io.close() - -curs.execute("SELECT * FROM test_copy") -rows = curs.fetchall() -print(" Select returned %d rows" % len(rows)) - -for r in rows: - print(" %s %s\t%s" % (r[0], r[1], r[2])) -curs.execute("delete from test_copy") -conn.commit() - -# copy_from using custom null identifier, from open file - -io = open('copy_from.txt', 'wr') -data = ['Tom\tJenkins\t37\n', - 'Madonna\tNULL\t45\n', - 'Federico\tDi Gregorio\tNULL\n'] -io.writelines(data) -io.close() - -io = open('copy_from.txt', 'r') -curs.copy_from(io, 'test_copy', null='NULL') -print("3) Copy %d records from file object using null = NULL" % len(data)) -io.close() - -curs.execute("SELECT * FROM test_copy") -rows = curs.fetchall() -print(" Select using cursor returned %d rows" % len(rows)) - -for r in rows: - print(" %s %s\t%s" % (r[0], r[1], r[2])) -curs.execute("delete from test_copy") -conn.commit() - -# copy_from using custom separator and null identifier - -io = open('copy_from.txt', 'wr') -data = ['Tom:Jenkins:37\n', 'Madonna:NULL:45\n', 'Federico:Di Gregorio:NULL\n'] -io.writelines(data) -io.close() - -io = open('copy_from.txt', 'r') -curs.copy_from(io, 'test_copy', ':', 'NULL') -print("4) Copy %d records from file object " % len(data) + - "using sep = : and null = NULL") -io.close() - -curs.execute("SELECT * FROM test_copy") -rows = curs.fetchall() -print(" Select using cursor returned %d rows" % len(rows)) - -for r in rows: - print(" %s %s\t%s" % (r[0], r[1], r[2])) -curs.execute("delete from test_copy") -conn.commit() - -# anything can be used as a file if it has .read() and .readline() methods - -data = StringIO.StringIO() -data.write('\n'.join(['Tom\tJenkins\t37', - 'Madonna\t\N\t45', - 'Federico\tDi Gregorio\t\N'])) -data.seek(0) - -curs.copy_from(data, 'test_copy') -print("5) Copy 3 records from StringIO object using defaults") - -curs.execute("SELECT * FROM test_copy") -rows = curs.fetchall() -print(" Select using cursor returned %d rows" % len(rows)) - -for r in rows: - print(" %s %s\t%s" % (r[0], r[1], r[2])) -curs.execute("delete from test_copy") -conn.commit() - -# simple error test - -print("6) About to raise an error") -data = StringIO.StringIO() -data.write('\n'.join(['Tom\tJenkins\t37', - 'Madonna\t\N\t45', - 'Federico\tDi Gregorio\taaa'])) -data.seek(0) - -try: - curs.copy_from(data, 'test_copy') -except StandardError as err: - conn.rollback() - print(" Caught error (as expected):\n", err) - -conn.rollback() - -curs.execute("DROP TABLE test_copy") -os.unlink('copy_from.txt') -conn.commit() diff --git a/examples/copy_to.py b/examples/copy_to.py deleted file mode 100644 index d5cd0ff8..00000000 --- a/examples/copy_to.py +++ /dev/null @@ -1,104 +0,0 @@ -# copy_to.py -- example about copy_to -# -# Copyright (C) 2002 Tom Jenkins -# Copyright (C) 2005 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) -from __future__ import print_function - -import sys -import os -import StringIO -import psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -curs = conn.cursor() -try: - curs.execute("CREATE TABLE test_copy (fld1 text, fld2 text, fld3 int4)") -except: - conn.rollback() - curs.execute("DROP TABLE test_copy") - curs.execute("CREATE TABLE test_copy (fld1 text, fld2 text, fld3 int4)") -conn.commit() - -# demostrate copy_to functionality -data = [('Tom', 'Jenkins', '37'), - ('Madonna', None, '45'), - ('Federico', 'Di Gregorio', None)] -query = "INSERT INTO test_copy VALUES (%s, %s, %s)" -curs.executemany(query, data) -conn.commit() - -# copy_to using defaults -io = open('copy_to.txt', 'w') -curs.copy_to(io, 'test_copy') -print("1) Copy %d records into file object using defaults: " % len (data) + \ - "sep = \\t and null = \\N") -io.close() - -rows = open('copy_to.txt', 'r').readlines() -print(" File has %d rows:" % len(rows)) - -for r in rows: - print(" ", r, end=' ') - -# copy_to using custom separator -io = open('copy_to.txt', 'w') -curs.copy_to(io, 'test_copy', ':') -print("2) Copy %d records into file object using sep = :" % len(data)) -io.close() - -rows = open('copy_to.txt', 'r').readlines() -print(" File has %d rows:" % len(rows)) - -for r in rows: - print(" ", r, end=' ') - -# copy_to using custom null identifier -io = open('copy_to.txt', 'w') -curs.copy_to(io, 'test_copy', null='NULL') -print("3) Copy %d records into file object using null = NULL" % len(data)) -io.close() - -rows = open('copy_to.txt', 'r').readlines() -print(" File has %d rows:" % len(rows)) - -for r in rows: - print(" ", r, end=' ') - -# copy_to using custom separator and null identifier -io = open('copy_to.txt', 'w') -curs.copy_to(io, 'test_copy', ':', 'NULL') -print("4) Copy %d records into file object using sep = : and null ) NULL" % \ - len(data)) -io.close() - -rows = open('copy_to.txt', 'r').readlines() -print(" File has %d rows:" % len(rows)) - -for r in rows: - print(" ", r, end=' ') - -curs.execute("DROP TABLE test_copy") -os.unlink('copy_to.txt') -conn.commit() diff --git a/examples/cursor.py b/examples/cursor.py deleted file mode 100644 index 58c8cf67..00000000 --- a/examples/cursor.py +++ /dev/null @@ -1,63 +0,0 @@ -# cursor.py - how to subclass the cursor type -# -# Copyright (C) 2004-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 -import psycopg2.extensions - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - - -class NoDataError(psycopg2.ProgrammingError): - """Exception that will be raised by our cursor.""" - pass - -class Cursor(psycopg2.extensions.cursor): - """A custom cursor.""" - - def fetchone(self): - """Like fetchone but raise an exception if no data is available. - - Note that to have .fetchmany() and .fetchall() to raise the same - exception we'll have to override them too; even if internally psycopg - uses the same function to fetch rows, the code path from Python is - different. - """ - d = psycopg2.extensions.cursor.fetchone(self) - if d is None: - raise NoDataError("no more data") - return d - -curs = conn.cursor(cursor_factory=Cursor) -curs.execute("SELECT 1 AS foo") -print("Result of fetchone():", curs.fetchone()) - -# now let's raise the exception -try: - curs.fetchone() -except NoDataError as err: - print("Exception caught:", err) - -conn.rollback() diff --git a/examples/dialtone.py b/examples/dialtone.py deleted file mode 100644 index f588eff8..00000000 --- a/examples/dialtone.py +++ /dev/null @@ -1,137 +0,0 @@ -""" -This example/recipe has been contributed by Valentino Volonghi (dialtone) - -Mapping arbitrary objects to a PostgreSQL database with psycopg2 - -- Problem - -You need to store arbitrary objects in a PostgreSQL database without being -intrusive for your classes (don't want inheritance from an 'Item' or -'Persistent' object). - -- Solution -""" - -from datetime import datetime - -import psycopg2 -from psycopg2.extensions import adapt, register_adapter - -# Here is the adapter for every object that we may ever need to -# insert in the database. It receives the original object and does -# its job on that instance - -class ObjectMapper(object): - def __init__(self, orig, curs=None): - self.orig = orig - self.tmp = {} - self.items, self.fields = self._gatherState() - - def _gatherState(self): - adaptee_name = self.orig.__class__.__name__ - fields = sorted([(field, getattr(self.orig, field)) - for field in persistent_fields[adaptee_name]]) - items = [] - for item, value in fields: - items.append(item) - return items, fields - - def getTableName(self): - return self.orig.__class__.__name__ - - def getMappedValues(self): - tmp = [] - for i in self.items: - tmp.append("%%(%s)s"%i) - return ", ".join(tmp) - - def getValuesDict(self): - return dict(self.fields) - - def getFields(self): - return self.items - - def generateInsert(self): - qry = "INSERT INTO" - qry += " " + self.getTableName() + " (" - qry += ", ".join(self.getFields()) + ") VALUES (" - qry += self.getMappedValues() + ")" - return qry, self.getValuesDict() - -# Here are the objects -class Album(object): - id = 0 - def __init__(self): - self.creation_time = datetime.now() - self.album_id = self.id - Album.id = Album.id + 1 - self.binary_data = buffer('12312312312121') - -class Order(object): - id = 0 - def __init__(self): - self.items = ['rice','chocolate'] - self.price = 34 - self.order_id = self.id - Order.id = Order.id + 1 - -register_adapter(Album, ObjectMapper) -register_adapter(Order, ObjectMapper) - -# Describe what is needed to save on each object -# This is actually just configuration, you can use xml with a parser if you -# like to have plenty of wasted CPU cycles ;P. - -persistent_fields = {'Album': ['album_id', 'creation_time', 'binary_data'], - 'Order': ['order_id', 'items', 'price'] - } - -print(adapt(Album()).generateInsert()) -print(adapt(Album()).generateInsert()) -print(adapt(Album()).generateInsert()) -print(adapt(Order()).generateInsert()) -print(adapt(Order()).generateInsert()) -print(adapt(Order()).generateInsert()) - -""" -- Discussion - -Psycopg 2 has a great new feature: adaptation. The big thing about -adaptation is that it enables the programmer to glue most of the -code out there without many difficulties. - -This recipe tries to focus attention on a way to generate SQL queries to -insert completely new objects inside a database. As you can see objects do -not know anything about the code that is handling them. We specify all the -fields that we need for each object through the persistent_fields dict. - -The most important lines of this recipe are: - register_adapter(Album, ObjectMapper) - register_adapter(Order, ObjectMapper) - -In these lines we notify the system that when we call adapt with an Album instance -as an argument we want it to istantiate ObjectMapper passing the Album instance -as argument (self.orig in the ObjectMapper class). - -The output is something like this (for each call to generateInsert): - -('INSERT INTO Album (album_id, binary_data, creation_time) VALUES - (%(album_id)s, %(binary_data)s, %(creation_time)s)', - - {'binary_data': , - 'creation_time': datetime.datetime(2004, 9, 10, 20, 48, 29, 633728), - 'album_id': 1} -) - -This is a tuple of {SQL_QUERY, FILLING_DICT}, and all the quoting/converting -stuff (from python's datetime to postgres s and from python's buffer to -postgres' blob) is handled with the same adaptation process hunder the hood -by psycopg2. - -At last, just notice that ObjectMapper is working for both Album and Order -instances without any glitches at all, and both classes could have easily been -coming from closed source libraries or C coded ones (which are not easily -modified), whereas a common pattern in todays ORMs or OODBs is to provide -a basic 'Persistent' object that already knows how to store itself in the -database. -""" diff --git a/examples/dict.py b/examples/dict.py deleted file mode 100644 index b5d0b3a4..00000000 --- a/examples/dict.py +++ /dev/null @@ -1,65 +0,0 @@ -# dict.py - using DictCUrsor/DictRow -# -# Copyright (C) 2005-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 -import psycopg2.extras - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - - -curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) -curs.execute("SELECT 1 AS foo, 'cip' AS bar, date(now()) as zot") -print("Cursor's row factory is", curs.row_factory) - -data = curs.fetchone() -print("The type of the data row is", type(data)) -print("Some data accessed both as tuple and dict:") -print(" ", data['foo'], data['bar'], data['zot']) -print(" ", data[0], data[1], data[2]) - -# execute another query and demostrate we can still access the row -curs.execute("SELECT 2 AS foo") -print("The type of the data row is", type(data)) -print("Some more data accessed both as tuple and dict:") -print(" ", data['foo'], data['bar'], data['zot']) -print(" ", data[0], data[1], data[2]) - -curs = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) -curs.execute("SELECT 1 AS foo, 'cip' AS bar, date(now()) as zot") -print("Cursor's row factory is", curs.row_factory) - -data = curs.fetchone() -print("The type of the data row is", type(data)) -print("Some data accessed both as tuple and dict:") -print(" ", data['foo'], data['bar'], data['zot']) -print(" ", "No access using indices: this is a specialized cursor.") - -# execute another query and demostrate we can still access the row -curs.execute("SELECT 2 AS foo") -print("The type of the data row is", type(data)) -print("Some more data accessed both as tuple and dict:") -print(" ", data['foo'], data['bar'], data['zot']) -print(" ", "No access using indices: this is a specialized cursor.") diff --git a/examples/dt.py b/examples/dt.py deleted file mode 100644 index 34b25b3d..00000000 --- a/examples/dt.py +++ /dev/null @@ -1,99 +0,0 @@ -# datetime.py - example of using date and time types -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 -import mx.DateTime -import datetime - -from psycopg2.extensions import adapt - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -curs = conn.cursor() - -try: - curs.execute("""CREATE TABLE test_dt ( - k int4, d date, t time, dt timestamp, z interval)""") -except: - conn.rollback() - curs.execute("DROP TABLE test_dt") - curs.execute("""CREATE TABLE test_dt ( - k int4, d date, t time, dt timestamp, z interval)""") -conn.commit() - -# build and insert some data using mx.DateTime -mx1 = ( - 1, - mx.DateTime.Date(2004, 10, 19), - mx.DateTime.Time(0, 11, 17.015), - mx.DateTime.Timestamp(2004, 10, 19, 0, 11, 17.5), - mx.DateTime.DateTimeDelta(13, 15, 17, 59.9)) - -from psycopg2.extensions import adapt -import psycopg2.extras -print(adapt(mx1)) - -print("Inserting mx.DateTime values...") -curs.execute("INSERT INTO test_dt VALUES (%s, %s, %s, %s, %s)", mx1) - -# build and insert some values using the datetime adapters -dt1 = ( - 2, - datetime.date(2004, 10, 19), - datetime.time(0, 11, 17, 15000), - datetime.datetime(2004, 10, 19, 0, 11, 17, 500000), - datetime.timedelta(13, 15*3600+17*60+59, 900000)) - -print("Inserting Python datetime values...") -curs.execute("INSERT INTO test_dt VALUES (%s, %s, %s, %s, %s)", dt1) - -# now extract the row from database and print them -print("Extracting values inserted with mx.DateTime wrappers:") -curs.execute("SELECT d, t, dt, z FROM test_dt WHERE k = 1") -for n, x in zip(mx1[1:], curs.fetchone()): - try: - # this will work only if psycopg has been compiled with datetime - # as the default typecaster for date/time values - s = repr(n) + "\n -> " + str(adapt(n)) + \ - "\n -> " + repr(x) + "\n -> " + x.isoformat() - except: - s = repr(n) + "\n -> " + str(adapt(n)) + \ - "\n -> " + repr(x) + "\n -> " + str(x) - print(s) -print() - -print("Extracting values inserted with Python datetime wrappers:") -curs.execute("SELECT d, t, dt, z FROM test_dt WHERE k = 2") -for n, x in zip(dt1[1:], curs.fetchone()): - try: - # this will work only if psycopg has been compiled with datetime - # as the default typecaster for date/time values - s = repr(n) + "\n -> " + repr(x) + "\n -> " + x.isoformat() - except: - s = repr(n) + "\n -> " + repr(x) + "\n -> " + str(x) - print(s) -print() - -curs.execute("DROP TABLE test_dt") -conn.commit() diff --git a/examples/encoding.py b/examples/encoding.py deleted file mode 100644 index 693a88dd..00000000 --- a/examples/encoding.py +++ /dev/null @@ -1,105 +0,0 @@ -# encoding.py - show to change client encoding (and test it works) -# -*- encoding: utf8 -*- -# -# Copyright (C) 2004-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 -import psycopg2.extensions - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Initial encoding for this connection is", conn.encoding) - -print("\n** This example is supposed to be run in a UNICODE terminal! **\n") - -print("Available encodings:") -encs = psycopg2.extensions.encodings.items() -encs.sort() -for a, b in encs: - print(" ", a, "<->", b) - -print("Using STRING typecaster") -print("Setting backend encoding to LATIN1 and executing queries:") -conn.set_client_encoding('LATIN1') -curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", ('àèìòù',)) -x = curs.fetchone()[0] -print(" ->", unicode(x, 'latin-1').encode('utf-8'), type(x)) -curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) -x = curs.fetchone()[0] -print(" ->", unicode(x, 'latin-1').encode('utf-8'), type(x)) - -print("Setting backend encoding to UTF8 and executing queries:") -conn.set_client_encoding('UNICODE') -curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),)) -x = curs.fetchone()[0] -print(" ->", x, type(x)) -curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) -x = curs.fetchone()[0] -print(" ->", x, type(x)) - -print("Using UNICODE typecaster") -psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) - -print("Setting backend encoding to LATIN1 and executing queries:") -conn.set_client_encoding('LATIN1') -curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", ('àèìòù',)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) -curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) - -print("Setting backend encoding to UTF8 and executing queries:") -conn.set_client_encoding('UNICODE') -curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) -curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) - -print("Executing full UNICODE queries") - -print("Setting backend encoding to LATIN1 and executing queries:") -conn.set_client_encoding('LATIN1') -curs = conn.cursor() -curs.execute(u"SELECT %s::TEXT AS foo", ('àèìòù',)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) -curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù',)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) - -print("Setting backend encoding to UTF8 and executing queries:") -conn.set_client_encoding('UNICODE') -curs = conn.cursor() -curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) -curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù',)) -x = curs.fetchone()[0] -print(" ->", x.encode('utf-8'), ":", type(x)) diff --git a/examples/fetch.py b/examples/fetch.py deleted file mode 100644 index 56b00bef..00000000 --- a/examples/fetch.py +++ /dev/null @@ -1,80 +0,0 @@ -# fetch.py -- example about declaring cursors -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -curs = conn.cursor() -try: - curs.execute("CREATE TABLE test_fetch (val int4)") -except: - conn.rollback() - curs.execute("DROP TABLE test_fetch") - curs.execute("CREATE TABLE test_fetch (val int4)") -conn.commit() - -# we use this function to format the output - -def flatten(l): - """Flattens list of tuples l.""" - return map(lambda x: x[0], l) - -# insert 20 rows in the table - -for i in range(20): - curs.execute("INSERT INTO test_fetch VALUES(%s)", (i,)) -conn.commit() - -# does some nice tricks with the transaction and postgres cursors -# (remember to always commit or rollback before a DECLARE) -# -# we don't need to DECLARE ourselves, psycopg now supports named -# cursors (but we leave the code here, comments, as an example of -# what psycopg is doing under the hood) -# -#curs.execute("DECLARE crs CURSOR FOR SELECT * FROM test_fetch") -#curs.execute("FETCH 10 FROM crs") -#print "First 10 rows:", flatten(curs.fetchall()) -#curs.execute("MOVE -5 FROM crs") -#print "Moved back cursor by 5 rows (to row 5.)" -#curs.execute("FETCH 10 FROM crs") -#print "Another 10 rows:", flatten(curs.fetchall()) -#curs.execute("FETCH 10 FROM crs") -#print "The remaining rows:", flatten(curs.fetchall()) - -ncurs = conn.cursor("crs") -ncurs.execute("SELECT * FROM test_fetch") -print("First 10 rows:", flatten(ncurs.fetchmany(10))) -ncurs.scroll(-5) -print("Moved back cursor by 5 rows (to row 5.)") -print("Another 10 rows:", flatten(ncurs.fetchmany(10))) -print("Another one:", list(ncurs.fetchone())) -print("The remaining rows:", flatten(ncurs.fetchall())) -conn.rollback() - -curs.execute("DROP TABLE test_fetch") -conn.commit() diff --git a/examples/lastrowid.py b/examples/lastrowid.py deleted file mode 100644 index da209d61..00000000 --- a/examples/lastrowid.py +++ /dev/null @@ -1,59 +0,0 @@ -# lastrowid.py - example of using .lastrowid attribute -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys, psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -curs = conn.cursor() - -try: - curs.execute("CREATE TABLE test_oid (name text, surname text)") -except: - conn.rollback() - curs.execute("DROP TABLE test_oid") - curs.execute("CREATE TABLE test_oid (name text, surname text)") -conn.commit() - -data = ({'name':'Federico', 'surname':'Di Gregorio'}, - {'name':'Pierluigi', 'surname':'Di Nunzio'}) - -curs.execute("""INSERT INTO test_oid - VALUES (%(name)s, %(surname)s)""", data[0]) - -foid = curs.lastrowid -print("Oid for %(name)s %(surname)s" % data[0], "is", foid) - -curs.execute("""INSERT INTO test_oid - VALUES (%(name)s, %(surname)s)""", data[1]) -moid = curs.lastrowid -print("Oid for %(name)s %(surname)s" % data[1], "is", moid) - -curs.execute("SELECT * FROM test_oid WHERE oid = %s", (foid,)) -print("Oid", foid, "selected %s %s" % curs.fetchone()) - -curs.execute("SELECT * FROM test_oid WHERE oid = %s", (moid,)) -print("Oid", moid, "selected %s %s" % curs.fetchone()) - -curs.execute("DROP TABLE test_oid") -conn.commit() diff --git a/examples/lobject.py b/examples/lobject.py deleted file mode 100644 index 242208eb..00000000 --- a/examples/lobject.py +++ /dev/null @@ -1,91 +0,0 @@ -# lobject.py - lobject example -# -# Copyright (C) 2001-2006 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -# this will create a large object with a new random oid, we'll -# use it to make some basic tests about read/write and seek. -lobj = conn.lobject() -loid = lobj.oid -print("Created a new large object with oid", loid) - -print("Manually importing some binary data into the object:") -data = open("somehackers.jpg").read() -len = lobj.write(data) -print(" imported", len, "bytes of data") - -conn.commit() - -print("Trying to (re)open large object with oid", loid) -lobj = conn.lobject(loid) -print("Manually exporting the data from the lobject:") -data1 = lobj.read() -len = lobj.tell() -lobj.seek(0, 0) -data2 = lobj.read() -if data1 != data2: - print("ERROR: read after seek returned different data") -open("somehackers_lobject1.jpg", 'wb').write(data1) -print(" written", len, "bytes of data to somehackers_lobject1.jpg") - -lobj.unlink() -print("Large object with oid", loid, "removed") - -conn.commit() - -# now we try to use the import and export functions to do the same -lobj = conn.lobject(0, 'n', 0, "somehackers.jpg") -loid = lobj.oid -print("Imported a new large object with oid", loid) - -conn.commit() - -print("Trying to (re)open large object with oid", loid) -lobj = conn.lobject(loid, 'n') -print("Using export() to export the data from the large object:") -lobj.export("somehackers_lobject2.jpg") -print(" exported large object to somehackers_lobject2.jpg") - -lobj.unlink() -print("Large object with oid", loid, "removed") - -conn.commit() - -# this will create a very large object with a new random oid. -lobj = conn.lobject() -loid = lobj.oid -print("Created a new large object with oid", loid) - -print("Manually importing a lot of data into the object:") -data = "data" * 1000000 -len = lobj.write(data) -print(" imported", len, "bytes of data") - -conn.rollback() - -print("\nNow try to load the new images, to check it worked!") diff --git a/examples/mogrify.py b/examples/mogrify.py deleted file mode 100644 index c6e04b5b..00000000 --- a/examples/mogrify.py +++ /dev/null @@ -1,47 +0,0 @@ -# mogrify.py - test all possible simple type mogrifications -# -*- encoding: latin1 -*- -# -# Copyright (C) 2004-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details.. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys, psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) - -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -curs = conn.cursor() -curs.execute("SELECT %(foo)s AS foo", {'foo':'bar'}) -curs.execute("SELECT %(foo)s AS foo", {'foo':None}) -curs.execute("SELECT %(foo)s AS foo", {'foo':True}) -curs.execute("SELECT %(foo)s AS foo", {'foo':42}) -curs.execute("SELECT %(foo)s AS foo", {'foo':u'yatt�!'}) -curs.execute("SELECT %(foo)s AS foo", {'foo':u'bar'}) - -print(curs.mogrify("SELECT %(foo)s AS foo", {'foo':'bar'})) -print(curs.mogrify("SELECT %(foo)s AS foo", {'foo':None})) -print(curs.mogrify("SELECT %(foo)s AS foo", {'foo':True})) -print(curs.mogrify("SELECT %(foo)s AS foo", {'foo':42})) -print(curs.mogrify("SELECT %(foo)s AS foo", {'foo':u'yatt�!'})) -print(curs.mogrify("SELECT %(foo)s AS foo", {'foo':u'bar'})) - -conn.rollback() diff --git a/examples/myfirstrecipe.py b/examples/myfirstrecipe.py deleted file mode 100644 index 1390ad00..00000000 --- a/examples/myfirstrecipe.py +++ /dev/null @@ -1,126 +0,0 @@ -""" -Using a tuple as a bound variable in "SELECT ... IN (...)" clauses -in PostgreSQL using psycopg2 - -Some time ago someone asked on the psycopg mailing list how to have a -bound variable expand to the right SQL for an SELECT IN clause: - - SELECT * FROM atable WHERE afield IN (value1, value2, value3) - -with the values to be used in the IN clause to be passed to the cursor -.execute() method in a tuple as a bound variable, i.e.: - - in_values = ("value1", "value2", "value3") - curs.execute("SELECT ... IN %s", (in_values,)) - -psycopg 1 does support typecasting from Python to PostgreSQL (and back) -only for simple types and this problem has no elegant solution (short or -writing a wrapper class returning the pre-quoted text in an __str__ -method. - -But psycopg2 offers a simple and elegant solution by partially -implementing the Object Adaptation from PEP 246. psycopg2 moves -the type-casting logic into external adapters and a somehow -broken adapt() function. - -While the original adapt() takes 3 arguments, psycopg2's one only takes -1: the bound variable to be adapted. The result is an object supporting -a not-yet well defined protocol that we can call ISQLQuote: - - class ISQLQuote: - - def getquoted(self): - "Returns a quoted string representing the bound variable." - - def getbinary(self): - "Returns a binary quoted string representing the bound variable." - - def getbuffer(self): - "Returns the wrapped object itself." - - __str__ = getquoted - -Then one of the functions (usually .getquoted()) is called by psycopg2 at -the right time to obtain the right, sql-quoted representation for the -corresponding bound variable. - -The nice part is that the default, built-in adapters, derived from -psycopg 1 tyecasting code can be overridden by the programmer, simply -replacing them in the psycopg.extensions.adapters dictionary. - -Then the solution to the original problem is now obvious: write an -adapter that adapts tuple objects into the right SQL string, by calling -recursively adapt() on each element. - -psycopg2 development can be tracked on the psycopg mailing list: - - http://lists.initd.org/mailman/listinfo/psycopg - -""" - -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -import psycopg2 -import psycopg2.extensions -from psycopg2.extensions import adapt as psycoadapt -from psycopg2.extensions import register_adapter - -class AsIs(object): - """An adapter that just return the object 'as is'. - - psycopg 1.99.9 has some optimizations that make impossible to call - adapt() without adding some basic adapters externally. This limitation - will be lifted in a future release. - """ - def __init__(self, obj): - self.__obj = obj - def getquoted(self): - return self.__obj - -class SQL_IN(object): - """Adapt a tuple to an SQL quotable object.""" - - def __init__(self, seq): - self._seq = seq - - def prepare(self, conn): - pass - - def getquoted(self): - # this is the important line: note how every object in the - # list is adapted and then how getquoted() is called on it - - qobjs = [str(psycoadapt(o).getquoted()) for o in self._seq] - - return '(' + ', '.join(qobjs) + ')' - - __str__ = getquoted - - -# add our new adapter class to psycopg list of adapters -register_adapter(tuple, SQL_IN) -register_adapter(float, AsIs) -register_adapter(int, AsIs) - -# usually we would call: -# -# conn = psycopg.connect("...") -# curs = conn.cursor() -# curs.execute("SELECT ...", (("this", "is", "the", "tuple"),)) -# -# but we have no connection to a database right now, so we just check -# the SQL_IN class by calling psycopg's adapt() directly: - -if __name__ == '__main__': - print("Note how the string will be SQL-quoted, but the number will not:") - print(psycoadapt(("this is an 'sql quoted' str\\ing", 1, 2.0))) diff --git a/examples/notify.py b/examples/notify.py deleted file mode 100644 index eb0f2fa5..00000000 --- a/examples/notify.py +++ /dev/null @@ -1,45 +0,0 @@ -# notify.py - example of getting notifies -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import select -import psycopg2 -from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) -curs = conn.cursor() - -curs.execute("listen test") - -print("Waiting for 'NOTIFY test'") -while 1: - if select.select([conn],[],[],5)==([],[],[]): - print("Timeout") - else: - conn.poll() - while conn.notifies: - print("Got NOTIFY:", conn.notifies.pop()) diff --git a/examples/simple.py b/examples/simple.py deleted file mode 100644 index 08191eaa..00000000 --- a/examples/simple.py +++ /dev/null @@ -1,54 +0,0 @@ -# simple.py - very simple example of plain DBAPI-2.0 usage -# -# currently used as test-me-stress-me script for psycopg 2.0 -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -class SimpleQuoter(object): - def sqlquote(x=None): - return "'bar'" - -import sys -import psycopg2 - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -curs = conn.cursor() -curs.execute("SELECT 1 AS foo") -print(curs.fetchone()) -curs.execute("SELECT 1 AS foo") -print(curs.fetchmany()) -curs.execute("SELECT 1 AS foo") -print(curs.fetchall()) - -conn.rollback() - -sys.exit(0) - -curs.execute("SELECT 1 AS foo", async=1) - -curs.execute("SELECT %(foo)s AS foo", {'foo':'bar'}) -curs.execute("SELECT %(foo)s AS foo", {'foo':None}) -curs.execute("SELECT %(foo)f AS foo", {'foo':42}) -curs.execute("SELECT %(foo)s AS foo", {'foo':SimpleQuoter()}) diff --git a/examples/somehackers.jpg b/examples/somehackers.jpg deleted file mode 100644 index 8bb6e013f8859dbeff0e11a88c4c3ff641aa79dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22565 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 Tvu)H-lCbpplUdhZK0p82LvO}& diff --git a/examples/threads.py b/examples/threads.py deleted file mode 100644 index 49a495c7..00000000 --- a/examples/threads.py +++ /dev/null @@ -1,161 +0,0 @@ -# threads.py -- example of multiple threads using psycopg -# -*- encoding: latin1 -*- -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## some others parameters -INSERT_THREADS = ('A', 'B', 'C') -SELECT_THREADS = ('1', '2') - -ROWS = 1000 - -COMMIT_STEP = 20 -SELECT_SIZE = 10000 -SELECT_STEP = 500 -SELECT_DIV = 250 - -# the available modes are: -# 0 - one connection for all inserts and one for all select threads -# 1 - connections generated using the connection pool - -MODE = 1 - -## don't modify anything below this line (except for experimenting) - -import sys, psycopg2, threading -from psycopg2.pool import ThreadedConnectionPool -from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT - -if len(sys.argv) > 1: - DSN = sys.argv[1] -if len(sys.argv) > 2: - MODE = int(sys.argv[2]) - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -curs = conn.cursor() - -try: - curs.execute("""CREATE TABLE test_threads ( - name text, value1 int4, value2 float)""") -except: - conn.rollback() - curs.execute("DROP TABLE test_threads") - curs.execute("""CREATE TABLE test_threads ( - name text, value1 int4, value2 float)""") -conn.commit() - - -## this function inserts a big number of rows and creates and destroys -## a large number of cursors - -def insert_func(conn_or_pool, rows): - name = threading.currentThread().getName() - - if MODE == 0: - conn = conn_or_pool - else: - conn = conn_or_pool.getconn() - - for i in range(rows): - if divmod(i, COMMIT_STEP)[1] == 0: - conn.commit() - if MODE == 1: - conn_or_pool.putconn(conn) - s = name + ": COMMIT STEP " + str(i) - print(s) - if MODE == 1: - conn = conn_or_pool.getconn() - c = conn.cursor() - try: - c.execute("INSERT INTO test_threads VALUES (%s, %s, %s)", - (str(i), i, float(i))) - except psycopg2.ProgrammingError as err: - print(name, ": an error occurred; skipping this insert") - print(err) - conn.commit() - -## a nice select function that prints the current number of rows in the -## database (and transfer them, putting some pressure on the network) - -def select_func(conn_or_pool, z): - name = threading.currentThread().getName() - - if MODE == 0: - conn = conn_or_pool - conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) - - for i in range(SELECT_SIZE): - if divmod(i, SELECT_STEP)[1] == 0: - try: - if MODE == 1: - conn = conn_or_pool.getconn() - conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) - c = conn.cursor() - c.execute("SELECT * FROM test_threads WHERE value2 < %s", - (int(i/z),)) - l = c.fetchall() - if MODE == 1: - conn_or_pool.putconn(conn) - s = name + ": number of rows fetched: " + str(len(l)) - print(s) - except psycopg2.ProgrammingError as err: - print(name, ": an error occurred; skipping this select") - print(err) - -## create the connection pool or the connections -if MODE == 0: - conn_insert = psycopg2.connect(DSN) - conn_select = psycopg2.connect(DSN) -else: - m = len(INSERT_THREADS) + len(SELECT_THREADS) - n = m/2 - conn_insert = conn_select = ThreadedConnectionPool(n, m, DSN) - -## create the threads -threads = [] - -print("Creating INSERT threads:") -for name in INSERT_THREADS: - t = threading.Thread(None, insert_func, 'Thread-'+name, - (conn_insert, ROWS)) - t.setDaemon(0) - threads.append(t) - -print("Creating SELECT threads:") -for name in SELECT_THREADS: - t = threading.Thread(None, select_func, 'Thread-'+name, - (conn_select, SELECT_DIV)) - t.setDaemon(0) - threads.append(t) - -## really start the threads now -for t in threads: - t.start() - -# and wait for them to finish -for t in threads: - t.join() - print(t.getName(), "exited OK") - - -conn.commit() -curs.execute("SELECT count(name) FROM test_threads") -print("Inserted", curs.fetchone()[0], "rows.") - -curs.execute("DROP TABLE test_threads") -conn.commit() diff --git a/examples/typecast.py b/examples/typecast.py deleted file mode 100644 index e6eda6c1..00000000 --- a/examples/typecast.py +++ /dev/null @@ -1,65 +0,0 @@ -# typecast.py - example of per-cursor and per-connection typecasters. -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -class SimpleQuoter(object): - def sqlquote(x=None): - return "'bar'" - -import sys -import psycopg2 -import psycopg2.extensions - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Encoding for this connection is", conn.encoding) - -curs = conn.cursor() -curs.execute("SELECT 'text'::text AS foo") -textoid = curs.description[0][1] -print("Oid for the text datatype is", textoid) - -def castA(s, curs): - if s is not None: return "(A) " + s -TYPEA = psycopg2.extensions.new_type((textoid,), "TYPEA", castA) - -def castB(s, curs): - if s is not None: return "(B) " + s -TYPEB = psycopg2.extensions.new_type((textoid,), "TYPEB", castB) - -curs = conn.cursor() -curs.execute("SELECT 'some text.'::text AS foo") -print("Some text from plain connection:", curs.fetchone()[0]) - -psycopg2.extensions.register_type(TYPEA, conn) -curs = conn.cursor() -curs.execute("SELECT 'some text.'::text AS foo") -print("Some text from connection with typecaster:", curs.fetchone()[0]) - -curs = conn.cursor() -psycopg2.extensions.register_type(TYPEB, curs) -curs.execute("SELECT 'some text.'::text AS foo") -print("Some text from cursor with typecaster:", curs.fetchone()[0]) - -curs = conn.cursor() -curs.execute("SELECT 'some text.'::text AS foo") -print("Some text from connection with typecaster again:", curs.fetchone()[0]) diff --git a/examples/tz.py b/examples/tz.py deleted file mode 100644 index 1726a6c2..00000000 --- a/examples/tz.py +++ /dev/null @@ -1,69 +0,0 @@ -# tz.py - example of datetime objects with time zones -# -*- encoding: utf8 -*- -# -# Copyright (C) 2004-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 -import datetime - -from psycopg2.tz import ZERO, LOCAL, FixedOffsetTimezone - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -curs = conn.cursor() - -try: - curs.execute("CREATE TABLE test_tz (t timestamp with time zone)") -except: - conn.rollback() - curs.execute("DROP TABLE test_tz") - curs.execute("CREATE TABLE test_tz (t timestamp with time zone)") -conn.commit() - -d = datetime.datetime(1971, 10, 19, 22, 30, 0, tzinfo=LOCAL) -curs.execute("INSERT INTO test_tz VALUES (%s)", (d,)) -print("Inserted timestamp with timezone:", d) -print("Time zone:", d.tzinfo.tzname(d), "offset:", d.tzinfo.utcoffset(d)) - -tz = FixedOffsetTimezone(-5*60, "EST") -d = datetime.datetime(1971, 10, 19, 22, 30, 0, tzinfo=tz) -curs.execute("INSERT INTO test_tz VALUES (%s)", (d,)) -print("Inserted timestamp with timezone:", d) -print("Time zone:", d.tzinfo.tzname(d), "offset:", d.tzinfo.utcoffset(d)) - -curs.execute("SELECT * FROM test_tz") -d = curs.fetchone()[0] -curs.execute("INSERT INTO test_tz VALUES (%s)", (d,)) -print("Inserted SELECTed timestamp:", d) -print("Time zone:", d.tzinfo.tzname(d), "offset:", d.tzinfo.utcoffset(d)) - -curs.execute("SELECT * FROM test_tz") -for d in curs: - u = d[0].utcoffset() or ZERO - print("UTC time: ", d[0] - u) - print("Local time:", d[0]) - print("Time zone:", d[0].tzinfo.tzname(d[0]), d[0].tzinfo.utcoffset(d[0])) - - -curs.execute("DROP TABLE test_tz") -conn.commit() diff --git a/examples/usercast.py b/examples/usercast.py deleted file mode 100644 index b9050427..00000000 --- a/examples/usercast.py +++ /dev/null @@ -1,126 +0,0 @@ -# usercast.py -- example of user defined typecasters -# -*- encoding: latin-1 -*- -# -# Copyright (C) 2001-2010 Federico Di Gregorio -# -# psycopg2 is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# psycopg2 is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. - -## put in DSN your DSN string - -DSN = 'dbname=test' - -## don't modify anything below this line (except for experimenting) - -import sys -import psycopg2 -import psycopg2.extensions -import whrandom - -# importing psycopg.extras will give us a nice tuple adapter: this is wrong -# because the adapter is meant to be used in SQL IN clauses while we use -# tuples to represent points but it works and the example is about Rect, not -# "Point" -import psycopg2.extras - -if len(sys.argv) > 1: - DSN = sys.argv[1] - -print("Opening connection using dsn:", DSN) -conn = psycopg2.connect(DSN) -print("Initial encoding for this connection is", conn.encoding) - -curs = conn.cursor() -try: - curs.execute("CREATE TABLE test_cast (p1 point, p2 point, b box)") -except: - conn.rollback() - curs.execute("DROP TABLE test_cast") - curs.execute("CREATE TABLE test_cast (p1 point, p2 point, b box)") -conn.commit() - -# this is the callable object we use as a typecast (the typecast is -# usually a function, but we use a class, just to demonstrate the -# flexibility of the psycopg casting system - -class Rect(object): - """Very simple rectangle. - - Note that we use this type as a data holder, as an adapter of itself for - the ISQLQuote protocol used by psycopg's adapt() (see __confrom__ below) - and eventually as a type-caster for the data extracted from the database - (that's why __init__ takes the curs argument.) - """ - - def __init__(self, s=None, curs=None): - """Init the rectangle from the optional string s.""" - self.x = self.y = self.width = self.height = 0.0 - if s: self.from_string(s) - - def __conform__(self, proto): - """This is a terrible hack, just ignore proto and return self.""" - if proto == psycopg2.extensions.ISQLQuote: - return self - - def from_points(self, x0, y0, x1, y1): - """Init the rectangle from points.""" - if x0 > x1: (x0, x1) = (x1, x0) - if y0 > y1: (y0, y1) = (y1, y0) - self.x = x0 - self.y = y0 - self.width = x1 - x0 - self.height = y1 - y0 - - def from_string(self, s): - """Init the rectangle from a string.""" - seq = eval(s) - self.from_points(seq[0][0], seq[0][1], seq[1][0], seq[1][1]) - - def getquoted(self): - """Format self as a string usable by the db to represent a box.""" - s = "'((%d,%d),(%d,%d))'" % ( - self.x, self.y, self.x + self.width, self.y + self.height) - return s - - def show(self): - """Format a description of the box.""" - s = "X: %d\tY: %d\tWidth: %d\tHeight: %d" % ( - self.x, self.y, self.width, self.height) - return s - -# here we select from the empty table, just to grab the description -curs.execute("SELECT b FROM test_cast WHERE 0=1") -boxoid = curs.description[0][1] -print("Oid for the box datatype is", boxoid) - -# and build the user cast object -BOX = psycopg2.extensions.new_type((boxoid,), "BOX", Rect) -psycopg2.extensions.register_type(BOX) - -# now insert 100 random data (2 points and a box in each row) -for i in range(100): - p1 = (whrandom.randint(0,100), whrandom.randint(0,100)) - p2 = (whrandom.randint(0,100), whrandom.randint(0,100)) - b = Rect() - b.from_points(whrandom.randint(0,100), whrandom.randint(0,100), - whrandom.randint(0,100), whrandom.randint(0,100)) - curs.execute("INSERT INTO test_cast VALUES ('%(p1)s', '%(p2)s', %(box)s)", - {'box':b, 'p1':p1, 'p2':p2}) -print("Added 100 boxed to the database") - -# select and print all boxes with at least one point inside -curs.execute("SELECT b FROM test_cast WHERE p1 @ b OR p2 @ b") -boxes = curs.fetchall() -print("Found %d boxes with at least a point inside:" % len(boxes)) -for box in boxes: - print(" ", box[0].show()) - -curs.execute("DROP TABLE test_cast") -conn.commit() diff --git a/examples/whereareyou.jpg b/examples/whereareyou.jpg deleted file mode 100644 index f508c0ba11e52031d7ce839da4f149a3f86a4b47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34980 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 - - - - - - - - - - - - - - - - - - - - @@ -131,7 +111,6 @@ - @@ -172,33 +151,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tox.ini b/tox.ini index e504fdcb..b54bb764 100644 --- a/tox.ini +++ b/tox.ini @@ -8,4 +8,4 @@ whitelist_externals = make [flake8] max-line-length = 85 ignore = E128, W503, E741 -exclude = build, doc, examples, tests/dbapi20.py +exclude = build, doc, tests/dbapi20.py