Compare commits

..

No commits in common. "master" and "2_4_1" have entirely different histories.

290 changed files with 82169 additions and 28810 deletions

4
.github/FUNDING.yml vendored
View File

@ -1,4 +0,0 @@
github:
- dvarrazzo
custom:
- "https://www.paypal.me/dvarrazzo"

View File

@ -1,23 +0,0 @@
---
name: Problem installing psycopg2
about: Report a case in which psycopg2 failed to install on your platform
title: ''
labels: ''
assignees: ''
---
**This is a bug tracker**
If you have a question, such has "how do you do X with Python/PostgreSQL/psycopg2" please [write to the mailing list](https://lists.postgresql.org/manage/) or [open a question](https://github.com/psycopg/psycopg2/discussions) instead.
**Before opening this ticket, please confirm that:**
- [ ] I am running the latest version of pip, i.e. typing ``pip --version`` you get [this version](https://pypi.org/project/pip/).
- [ ] I have read the [installation documentation](https://www.psycopg.org/docs/install.html) and the [frequently asked questions](https://www.psycopg.org/docs/faq.html)
- [ ] If install failed, I typed `pg_config` on the command line and I obtained an output instead of an error.
**Please complete the following information:**
- OS:
- Psycopg version:
- Python version:
- PostgreSQL version:
- pip version

View File

@ -1,27 +0,0 @@
---
name: Problem using psycopg2
about: Report a case in which psycopg2 is not working as expected
title: ''
labels: ''
assignees: ''
---
**This is a bug tracker**
If you have a question, such has "how do you do X with Python/PostgreSQL/psycopg2" please [write to the mailing list](https://lists.postgresql.org/manage/) or [open a question](https://github.com/psycopg/psycopg2/discussions) instead.
**Please complete the following information:**
- OS:
- Psycopg version:
- Python version:
- PostgreSQL version:
- pip version
**Describe the bug**
Please let us know:
1: what you did
2: what you expected to happen
3: what happened instead
If possible, provide a script reproducing the issue.

View File

@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"

View File

@ -1,18 +0,0 @@
name: Build documentation
on:
push:
branches:
# This should match the DOC_BRANCH value in the psycopg-website Makefile
- master
jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Trigger docs build
uses: peter-evans/repository-dispatch@v3
with:
repository: psycopg/psycopg-website
event-type: psycopg2-commit
token: ${{ secrets.ACCESS_TOKEN }}

View File

@ -1,266 +0,0 @@
---
name: Build packages
on:
- workflow_dispatch
env:
PIP_BREAK_SYSTEM_PACKAGES: "1"
LIBPQ_VERSION: "16.0"
OPENSSL_VERSION: "1.1.1w"
jobs:
sdist: # {{{
if: true
strategy:
fail-fast: false
matrix:
include:
- package_name: psycopg2
- package_name: psycopg2-binary
runs-on: ubuntu-latest
steps:
- name: Checkout repos
uses: actions/checkout@v4
- name: Build sdist
run: ./scripts/build/build_sdist.sh
env:
PACKAGE_NAME: ${{ matrix.package_name }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: sdist-${{ matrix.package_name }}
path: |
dist/*.tar.gz
env:
PSYCOPG2_TESTDB: postgres
PSYCOPG2_TESTDB_HOST: 172.17.0.1
PSYCOPG2_TESTDB_USER: postgres
PSYCOPG2_TESTDB_PASSWORD: password
PSYCOPG2_TEST_FAST: 1
services:
postgresql:
image: postgres:16
env:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
# }}}
linux: # {{{
if: true
strategy:
fail-fast: false
matrix:
platform: [manylinux, musllinux]
arch: [x86_64, i686, aarch64, ppc64le]
pyver: [cp38, cp39, cp310, cp311, cp312, cp313]
runs-on: ubuntu-latest
steps:
- name: Checkout repos
uses: actions/checkout@v4
- name: Set up QEMU for multi-arch build
uses: docker/setup-qemu-action@v3
- name: Cache libpq build
uses: actions/cache@v4
with:
path: /tmp/libpq.build
key: libpq-${{ env.LIBPQ_VERSION }}-${{ matrix.platform }}-${{ matrix.arch }}
- name: Build wheels
uses: pypa/cibuildwheel@v2.23.2
env:
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_I686_IMAGE: manylinux2014
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux2014
CIBW_MANYLINUX_PPC64LE_IMAGE: manylinux2014
CIBW_BUILD: ${{matrix.pyver}}-${{matrix.platform}}_${{matrix.arch}}
CIBW_ARCHS_LINUX: auto aarch64 ppc64le
CIBW_BEFORE_ALL_LINUX: ./scripts/build/wheel_linux_before_all.sh
CIBW_REPAIR_WHEEL_COMMAND: >-
./scripts/build/strip_wheel.sh {wheel}
&& auditwheel repair -w {dest_dir} {wheel}
CIBW_TEST_COMMAND: >-
export PYTHONPATH={project} &&
python -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')"
CIBW_ENVIRONMENT_PASS_LINUX: LIBPQ_VERSION OPENSSL_VERSION
CIBW_ENVIRONMENT: >-
PACKAGE_NAME=psycopg2-binary
LIBPQ_BUILD_PREFIX=/host/tmp/libpq.build
PATH="$LIBPQ_BUILD_PREFIX/bin:$PATH"
LD_LIBRARY_PATH="$LIBPQ_BUILD_PREFIX/lib:$LIBPQ_BUILD_PREFIX/lib64"
PSYCOPG2_TESTDB=postgres
PSYCOPG2_TESTDB_HOST=172.17.0.1
PSYCOPG2_TESTDB_USER=postgres
PSYCOPG2_TESTDB_PASSWORD=password
PSYCOPG2_TEST_FAST=1
- uses: actions/upload-artifact@v4
with:
name: linux-${{matrix.pyver}}-${{matrix.platform}}_${{matrix.arch}}
path: ./wheelhouse/*.whl
services:
postgresql:
image: postgres:16
env:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
# }}}
macos: # {{{
runs-on: macos-latest
if: true
strategy:
fail-fast: false
matrix:
# These archs require an Apple M1 runner: [arm64, universal2]
arch: [x86_64, arm64]
pyver: [cp39, cp310, cp311, cp312, cp313]
steps:
- name: Checkout repos
uses: actions/checkout@v4
- name: Cache libpq build
uses: actions/cache@v4
with:
path: /tmp/libpq.build
key: libpq-${{ env.LIBPQ_VERSION }}-macos-${{ matrix.arch }}
- name: Build wheels
uses: pypa/cibuildwheel@v2.23.2
env:
CIBW_BUILD: ${{matrix.pyver}}-macosx_${{matrix.arch}}
CIBW_ARCHS_MACOS: ${{matrix.arch}}
MACOSX_ARCHITECTURE: ${{matrix.arch}}
CIBW_BEFORE_ALL_MACOS: ./scripts/build/wheel_macos_before_all.sh
CIBW_TEST_COMMAND: >-
export PYTHONPATH={project} &&
python -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')"
CIBW_ENVIRONMENT: >-
PG_VERSION=16
PACKAGE_NAME=psycopg2-binary
PSYCOPG2_TESTDB=postgres
PATH="/tmp/libpq.build/bin:$PATH"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: macos-${{matrix.pyver}}-macos-${{matrix.arch}}
path: ./wheelhouse/*.whl
# }}}
windows: # {{{
runs-on: windows-latest
if: true
strategy:
fail-fast: false
matrix:
arch: [win_amd64]
pyver: [cp38, cp39, cp310, cp311, cp312, cp313]
package_name: [psycopg2, psycopg2-binary]
defaults:
run:
shell: bash
steps:
# there are some other libpq in PATH
- name: Drop spurious libpq in the path
run: rm -rf c:/tools/php C:/Strawberry/c/bin
- name: Checkout repo
uses: actions/checkout@v4
- name: Start PostgreSQL service for test
run: |
$PgSvc = Get-Service "postgresql*"
Set-Service $PgSvc.Name -StartupType manual
$PgSvc.Start()
shell: powershell
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v7
with:
script: |
const path = require('path')
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
core.addPath(path.join(process.env.VCPKG_INSTALLATION_ROOT, 'installed/x64-windows-release/lib'));
core.addPath(path.join(process.env.VCPKG_INSTALLATION_ROOT, 'installed/x64-windows-release/bin'));
- name: Create the binary package source tree
run: >-
sed -i 's/^setup(name="psycopg2"/setup(name="${{matrix.package_name}}"/'
setup.py
if: ${{ matrix.package_name != 'psycopg2' }}
- name: Build wheels
uses: pypa/cibuildwheel@v2.23.2
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" # cache vcpkg
CIBW_BUILD: ${{matrix.pyver}}-${{matrix.arch}}
CIBW_ARCHS_WINDOWS: AMD64 x86
CIBW_BEFORE_BUILD_WINDOWS: '.\scripts\build\wheel_win32_before_build.bat'
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >-
delvewheel repair -w {dest_dir}
--no-mangle "libiconv-2.dll;libwinpthread-1.dll" {wheel}
CIBW_TEST_COMMAND: >-
set PYTHONPATH={project} &&
python -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')"
# Note: no fast test because we don't run Windows tests
CIBW_ENVIRONMENT_WINDOWS: >-
PSYCOPG2_TESTDB=postgres
PSYCOPG2_TESTDB_USER=postgres
PSYCOPG2_TESTDB_HOST=localhost
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: windows-${{ matrix.package_name }}-${{matrix.pyver}}-${{matrix.arch}}
path: ./wheelhouse/*.whl
# }}}
merge: # {{{
runs-on: ubuntu-latest
needs:
- sdist
- linux
- macos
- windows
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: psycopg2-artifacts
delete-merged: true
# }}}

View File

@ -1,79 +0,0 @@
name: Tests
env:
PIP_BREAK_SYSTEM_PACKAGES: "1"
on:
push:
pull_request:
jobs:
linux:
runs-on: ubuntu-latest
if: true
strategy:
fail-fast: false
matrix:
include:
- {python: "3.8", postgres: "12"}
- {python: "3.9", postgres: "13"}
- {python: "3.10", postgres: "14"}
- {python: "3.11", postgres: "15"}
- {python: "3.12", postgres: "16"}
- {python: "3.13", postgres: "17"}
# Opposite extremes of the supported Py/PG range, other architecture
- {python: "3.8", postgres: "17", architecture: "x86"}
- {python: "3.9", postgres: "16", architecture: "x86"}
- {python: "3.10", postgres: "15", architecture: "x86"}
- {python: "3.11", postgres: "14", architecture: "x86"}
- {python: "3.12", postgres: "13", architecture: "x86"}
- {python: "3.13", postgres: "12", architecture: "x86"}
env:
PSYCOPG2_TESTDB: postgres
PSYCOPG2_TESTDB_HOST: 127.0.0.1
PSYCOPG2_TESTDB_USER: postgres
PSYCOPG2_TESTDB_PASSWORD: password
services:
postgresql:
image: postgres:${{ matrix.postgres }}
env:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
# Can enable to test an unreleased libpq version.
- name: install libpq 16
if: false
run: |
set -x
rel=$(lsb_release -c -s)
echo "deb http://apt.postgresql.org/pub/repos/apt ${rel}-pgdg main 16" \
| sudo tee -a /etc/apt/sources.list.d/pgdg.list
sudo apt-get -qq update
pqver=$(apt-cache show libpq5 | grep ^Version: | head -1 \
| awk '{print $2}')
sudo apt-get -qq -y install "libpq-dev=${pqver}" "libpq5=${pqver}"
- name: Install tox
run: pip install "tox < 4"
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Run tests
env:
MATRIX_PYTHON: ${{ matrix.python }}
run: tox -e ${MATRIX_PYTHON%-dev}
timeout-minutes: 5

14
.gitignore vendored
View File

@ -4,15 +4,9 @@ MANIFEST
*.pidb *.pidb
*.pyc *.pyc
*.sw[po] *.sw[po]
*.egg-info/
dist/* dist/*
/build build/*
doc/src/_build/*
doc/html/*
doc/psycopg2.txt
env env
env?
.idea
.tox
.vscode/
/rel
/wheels
/packages
/wheelhouse

View File

@ -6,7 +6,7 @@ For the win32 port:
Jason Erickson <jerickso@indian.com> Jason Erickson <jerickso@indian.com>
Additional Help: Additional Help:
Peter Fein contributed a logging connection/cursor class that even if it Peter Fein contributed a logging connection/cursor class that even if it
was not used directly heavily influenced the implementation currently in was not used directly heavily influenced the implementation currently in
psycopg2.extras. psycopg2.extras.

2455
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

105
INSTALL
View File

@ -1,4 +1,103 @@
Installation instructions are included in the docs. Compiling and installing psycopg
********************************
** Important note: if you plan to use psyopg2 in a multithreaed application
make sure that your libpq has been compiled with the --with-thread-safety
option. psycopg2 will work correctly even with a non-thread-safe libpq but
libpq will leak memory.
psycopg2 uses distutils for its build process, so most of the process is
executed by the setup.py script. Before building psycopg look at
setup.cfg file and change any settings to follow your system (or taste);
then:
python setup.py build
to build in the local directory; and:
python setup.py install
to install system-wide.
Common errors and build problems
================================
One of the most common errors is trying to build psycopg without the right
development headers for PostgreSQL, Python or both. If you get errors, look
for the following messages and then take the appropriate action:
libpq-fe.h: No such file or directory
PostgreSQL headers are not properly installed on your system or are
installed in a non default path. First make sure they are installed, then
check setup.cfg and make sure pg_config points to a valid pg_config
executable. If you don't have a working pg_config try to play with the
include_dirs variable (and note that a working pg_config is better.)
Running the test suite
======================
The included Makefile allows to run all the tests included in the
distribution. Just use:
make
make check
The tests are run against a database called psycopg2_test on unix socket
and standard port. You can configure a different database to run the test
by setting the environment variables:
- PSYCOPG2_TESTDB
- PSYCOPG2_TESTDB_HOST
- PSYCOPG2_TESTDB_PORT
- PSYCOPG2_TESTDB_USER
The database should be created before running the tests.
The standard Python unittest is used to run the tests. But if unittest2 is
found it will be used instead, with the result of having more informations
about skipped tests.
Building the documentation
==========================
In order to build the documentation included in the distribution, use
make env
make docs
The first command will install all the dependencies (Sphinx, Docutils) in
an 'env' directory in the project tree. The second command will build both
the html format (in the 'doc/html' directory) and in plain text
(doc/psycopg2.txt)
Using setuptools and EasyInstall
================================
If setuptools are installed on your system you can easily create an egg for
psycopg and install it. Download the source distribution (if you're reading
this file you probably already have) and then edit setup.cfg to your taste
and build from the source distribution top-level directory using:
easy_install .
Compiling under Windows with mingw32
====================================
You can compile psycopg under Windows platform with mingw32
(http://www.mingw.org/) compiler. MinGW is also shipped with IDEs such as
Dev-C++ (http://www.bloodshed.net/devcpp.html) and Code::Blocks
(http://www.codeblocks.org). gcc binaries should be in your PATH.
You need a PostgreSQL with include and libary files installed. At least v8.0
is required.
First you need to create a libpython2X.a as described in
http://starship.python.net/crew/kernr/mingw32/Notes.html. Then run:
python setup.py build_ext --compiler=mingw32 install
Please check the 'doc/src/install.rst' file or online at
<https://www.psycopg.org/docs/install.html>.

19
LICENSE
View File

@ -1,5 +1,5 @@
psycopg2 and the LGPL psycopg2 and the LGPL
--------------------- =====================
psycopg2 is free software: you can redistribute it and/or modify it psycopg2 is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published under the terms of the GNU Lesser General Public License as published
@ -25,14 +25,19 @@ statement from all source files in the program, then also delete it here.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with psycopg2 (see the doc/ directory.) along with psycopg2 (see the doc/ directory.)
If not, see <https://www.gnu.org/licenses/>. If not, see <http://www.gnu.org/licenses/>.
Alternative licenses Alternative licenses
-------------------- ====================
The following BSD-like license applies (at your option) to the files following If you prefer you can use the Zope Database Adapter ZPsycopgDA (i.e.,
the pattern ``psycopg/adapter*.{h,c}`` and ``psycopg/microprotocol*.{h,c}``: every file inside the ZPsycopgDA directory) user the ZPL license as
published on the Zope web site, http://www.zope.org/Resources/ZPL.
Also, the following BSD-like license applies (at your option) to the
files following the pattern psycopg/adapter*.{h,c} and
psycopg/microprotocol*.{h,c}:
Permission is granted to anyone to use this software for any purpose, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it including commercial applications, and to alter it and redistribute it
@ -42,8 +47,8 @@ the pattern ``psycopg/adapter*.{h,c}`` and ``psycopg/microprotocol*.{h,c}``:
claim that you wrote the original software. If you use this claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation software in a product, an acknowledgment in the product documentation
would be appreciated but is not required. would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not 2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software. be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.

View File

@ -1,9 +1,16 @@
recursive-include psycopg *.c *.h *.manifest recursive-include psycopg *.c *.h *.manifest
recursive-include lib *.py recursive-include lib *.py
recursive-include tests *.py recursive-include tests *.py
include doc/README.rst doc/SUCCESS doc/COPYING.LESSER doc/pep-0249.txt recursive-include ZPsycopgDA *.py *.gif *.dtml
include doc/Makefile doc/requirements.txt recursive-include psycopg2da *
recursive-include examples *.py somehackers.jpg whereareyou.jpg
recursive-include debian *
recursive-include doc README HACKING SUCCESS COPYING* ChangeLog-1.x pep-0249.txt
recursive-include doc *.txt *.html *.css *.js Makefile
recursive-include doc/src *.rst *.py *.css Makefile recursive-include doc/src *.rst *.py *.css Makefile
recursive-include doc/html *
prune doc/src/_build
recursive-include scripts *.py *.sh recursive-include scripts *.py *.sh
include AUTHORS README.rst INSTALL LICENSE NEWS include scripts/maketypes.sh scripts/buildtypes.py
include MANIFEST.in setup.py setup.cfg Makefile include AUTHORS README INSTALL LICENSE NEWS ChangeLog
include PKG-INFO MANIFEST.in MANIFEST setup.py setup.cfg Makefile

View File

@ -6,11 +6,12 @@
# #
# Build the documentation:: # Build the documentation::
# #
# make env (once) # make env
# make docs # make docs
# #
# Create a source package:: # Create a source package::
# #
# make env # required to build the documentation
# make sdist # make sdist
# #
# Run the test:: # Run the test::
@ -20,6 +21,9 @@
PYTHON := python$(PYTHON_VERSION) PYTHON := python$(PYTHON_VERSION)
PYTHON_VERSION ?= $(shell $(PYTHON) -c 'import sys; print ("%d.%d" % sys.version_info[:2])') PYTHON_VERSION ?= $(shell $(PYTHON) -c 'import sys; print ("%d.%d" % sys.version_info[:2])')
BUILD_DIR = $(shell pwd)/build/lib.$(PYTHON_VERSION) BUILD_DIR = $(shell pwd)/build/lib.$(PYTHON_VERSION)
ENV_DIR = $(shell pwd)/env/py-$(PYTHON_VERSION)
ENV_BIN = $(ENV_DIR)/bin
ENV_LIB = $(ENV_DIR)/lib
SOURCE_C := $(wildcard psycopg/*.c psycopg/*.h) SOURCE_C := $(wildcard psycopg/*.c psycopg/*.h)
SOURCE_PY := $(wildcard lib/*.py) SOURCE_PY := $(wildcard lib/*.py)
@ -29,7 +33,8 @@ SOURCE := $(SOURCE_C) $(SOURCE_PY) $(SOURCE_TESTS) $(SOURCE_DOC)
PACKAGE := $(BUILD_DIR)/psycopg2 PACKAGE := $(BUILD_DIR)/psycopg2
PLATLIB := $(PACKAGE)/_psycopg.so PLATLIB := $(PACKAGE)/_psycopg.so
PURELIB := $(patsubst lib/%,$(PACKAGE)/%,$(SOURCE_PY)) PURELIB := $(patsubst lib/%,$(PACKAGE)/%,$(SOURCE_PY)) \
$(patsubst tests/%,$(PACKAGE)/tests/%,$(SOURCE_TESTS))
BUILD_OPT := --build-lib=$(BUILD_DIR) BUILD_OPT := --build-lib=$(BUILD_DIR)
BUILD_EXT_OPT := --build-lib=$(BUILD_DIR) BUILD_EXT_OPT := --build-lib=$(BUILD_DIR)
@ -42,7 +47,10 @@ endif
VERSION := $(shell grep PSYCOPG_VERSION setup.py | head -1 | sed -e "s/.*'\(.*\)'/\1/") VERSION := $(shell grep PSYCOPG_VERSION setup.py | head -1 | sed -e "s/.*'\(.*\)'/\1/")
SDIST := dist/psycopg2-$(VERSION).tar.gz SDIST := dist/psycopg2-$(VERSION).tar.gz
.PHONY: check clean EASY_INSTALL = PYTHONPATH=$(ENV_LIB) $(ENV_BIN)/easy_install-$(PYTHON_VERSION) -d $(ENV_LIB) -s $(ENV_BIN)
EZ_SETUP = $(ENV_BIN)/ez_setup.py
.PHONY: env check clean
default: package default: package
@ -50,20 +58,36 @@ all: package sdist
package: $(PLATLIB) $(PURELIB) package: $(PLATLIB) $(PURELIB)
docs: docs-html docs: docs-html docs-txt
docs-html: doc/html/genindex.html docs-html: doc/html/genindex.html
docs-txt: doc/psycopg2.txt
# for PyPI documentation # for PyPI documentation
docs-zip: doc/docs.zip docs-zip: doc/docs.zip
sdist: $(SDIST) sdist: $(SDIST)
env: # The environment is currently required to build the documentation.
$(MAKE) -C doc $@ # It is not clean by 'make clean'
env: easy_install
mkdir -p $(ENV_BIN)
mkdir -p $(ENV_LIB)
$(EASY_INSTALL) docutils
$(EASY_INSTALL) sphinx
easy_install: ez_setup
PYTHONPATH=$(ENV_LIB) $(PYTHON) $(EZ_SETUP) -d $(ENV_LIB) -s $(ENV_BIN) setuptools
ez_setup:
mkdir -p $(ENV_BIN)
mkdir -p $(ENV_LIB)
wget -O $(EZ_SETUP) http://peak.telecommunity.com/dist/ez_setup.py
check: check:
PYTHONPATH=$(BUILD_DIR) $(PYTHON) -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')" --verbose PYTHONPATH=$(BUILD_DIR):$(PYTHONPATH) $(PYTHON) -c "from psycopg2 import tests; tests.unittest.main(defaultTest='tests.test_suite')" --verbose
testdb: testdb:
@echo "* Creating $(TESTDB)" @echo "* Creating $(TESTDB)"
@ -89,16 +113,24 @@ $(PACKAGE)/tests/%.py: tests/%.py
$(PYTHON) setup.py build_py $(BUILD_OPT) $(PYTHON) setup.py build_py $(BUILD_OPT)
touch $@ touch $@
$(SDIST): $(SOURCE) $(SDIST): docs MANIFEST $(SOURCE)
$(PYTHON) setup.py sdist $(SDIST_OPT) $(PYTHON) setup.py sdist $(SDIST_OPT)
MANIFEST: MANIFEST.in $(SOURCE)
# Run twice as MANIFEST.in includes MANIFEST
$(PYTHON) setup.py sdist --manifest-only
$(PYTHON) setup.py sdist --manifest-only
# docs depend on the build as it partly use introspection. # docs depend on the build as it partly use introspection.
doc/html/genindex.html: $(PLATLIB) $(PURELIB) $(SOURCE_DOC) doc/html/genindex.html: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
$(MAKE) -C doc html PYTHONPATH=$(ENV_LIB):$(BUILD_DIR) $(MAKE) SPHINXBUILD=$(ENV_BIN)/sphinx-build -C doc html
doc/psycopg2.txt: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
PYTHONPATH=$(ENV_LIB):$(BUILD_DIR) $(MAKE) SPHINXBUILD=$(ENV_BIN)/sphinx-build -C doc text
doc/docs.zip: doc/html/genindex.html doc/docs.zip: doc/html/genindex.html
(cd doc/html && zip -r ../docs.zip *) (cd doc/html && zip -r ../docs.zip *)
clean: clean:
rm -rf build rm -rf build MANIFEST
$(MAKE) -C doc clean $(MAKE) -C doc clean

1462
NEWS

File diff suppressed because it is too large Load Diff

38
README Normal file
View File

@ -0,0 +1,38 @@
psycopg2 - Python-PostgreSQL Database Adapter
********************************************
psycopg2 is a PostgreSQL database adapter for the Python programming
language. psycopg2 was written with the aim of being very small and fast,
and stable as a rock.
psycopg2 is different from the other database adapter because it was
designed for heavily multi-threaded applications that create and destroy
lots of cursors and make a conspicuous number of concurrent INSERTs or
UPDATEs. psycopg2 also provide full asycronous operations and support
for coroutine libraries.
psycopg2 can compile and run on Linux, FreeBSD, Solaris, MacOS X and
Windows architecture. It supports Python versions from 2.4 onwards and
PostgreSQL versions from 7.4 onwards.
psycopg2 is free software ("free as in freedom" but I like beer too.)
It is licensed under the GNU Lesser General Public License, version 3 or
later plus an exception to allow OpenSSL (libpq) linking; see LICENSE for
more details.
Documentation
-------------
Start by reading the INSTALL file. More information about psycopg2 extensions
to the DBAPI-2.0 is available in the files located in the doc/ direcory.
Example code can be found in the examples/ directory. If you make any changes
to the code make sure to run the unit tests localed in tests/.
Online documentation can be found at: http://initd.org/psycopg/
If you stumble upon any bugs, please tell us at: http://psycopg.lighthouseapp.com/
Contributors
------------
For a list of contributors to the project, see the AUTHORS file.

View File

@ -1,80 +0,0 @@
psycopg2 - Python-PostgreSQL Database Adapter
=============================================
Psycopg is the most popular PostgreSQL database adapter for the Python
programming language. Its main features are the complete implementation of
the Python DB API 2.0 specification and the thread safety (several threads can
share the same connection). It was designed for heavily multi-threaded
applications that create and destroy lots of cursors and make a large number
of concurrent "INSERT"s or "UPDATE"s.
Psycopg 2 is mostly implemented in C as a libpq wrapper, resulting in being
both efficient and secure. It features client-side and server-side cursors,
asynchronous communication and notifications, "COPY TO/COPY FROM" support.
Many Python types are supported out-of-the-box and adapted to matching
PostgreSQL data types; adaptation can be extended and customized thanks to a
flexible objects adaptation system.
Psycopg 2 is both Unicode and Python 3 friendly.
.. Note::
The psycopg2 package is still widely used and actively maintained, but it
is not expected to receive new features.
`Psycopg 3`__ is the evolution of psycopg2 and is where `new features are
being developed`__: if you are starting a new project you should probably
start from 3!
.. __: https://pypi.org/project/psycopg/
.. __: https://www.psycopg.org/psycopg3/docs/index.html
Documentation
-------------
Documentation is included in the ``doc`` directory and is `available online`__.
.. __: https://www.psycopg.org/docs/
For any other resource (source code repository, bug tracker, mailing list)
please check the `project homepage`__.
.. __: https://psycopg.org/
Installation
------------
Building Psycopg requires a few prerequisites (a C compiler, some development
packages): please check the install_ and the faq_ documents in the ``doc`` dir
or online for the details.
If prerequisites are met, you can install psycopg like any other Python
package, using ``pip`` to download it from PyPI_::
$ pip install psycopg2
or using ``setup.py`` if you have downloaded the source package locally::
$ python setup.py build
$ sudo python setup.py install
You can also obtain a stand-alone package, not requiring a compiler or
external libraries, by installing the `psycopg2-binary`_ package from PyPI::
$ pip install psycopg2-binary
The binary package is a practical choice for development and testing but in
production it is advised to use the package built from sources.
.. _PyPI: https://pypi.org/project/psycopg2/
.. _psycopg2-binary: https://pypi.org/project/psycopg2-binary/
.. _install: https://www.psycopg.org/docs/install.html#install-from-source
.. _faq: https://www.psycopg.org/docs/faq.html#faq-compile
:Build status: |gh-actions|
.. |gh-actions| image:: https://github.com/psycopg/psycopg2/actions/workflows/tests.yml/badge.svg
:target: https://github.com/psycopg/psycopg2/actions/workflows/tests.yml
:alt: Build status

360
ZPsycopgDA/DA.py Normal file
View File

@ -0,0 +1,360 @@
# ZPsycopgDA/DA.py - ZPsycopgDA Zope product: Database Connection
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
ALLOWED_PSYCOPG_VERSIONS = ('2.4-beta1', '2.4-beta2', '2.4', '2.4.1')
import sys
import time
import db
import re
import Acquisition
import Shared.DC.ZRDB.Connection
from db import DB
from Globals import HTMLFile
from ExtensionClass import Base
from App.Dialogs import MessageDialog
from DateTime import DateTime
# ImageFile is deprecated in Zope >= 2.9
try:
from App.ImageFile import ImageFile
except ImportError:
# Zope < 2.9. If PIL's installed with a .pth file, we're probably
# hosed.
from ImageFile import ImageFile
# import psycopg and functions/singletons needed for date/time conversions
import psycopg2
from psycopg2 import NUMBER, STRING, ROWID, DATETIME
from psycopg2.extensions import INTEGER, LONGINTEGER, FLOAT, BOOLEAN, DATE
from psycopg2.extensions import TIME, INTERVAL
from psycopg2.extensions import new_type, register_type
# add a new connection to a folder
manage_addZPsycopgConnectionForm = HTMLFile('dtml/add',globals())
def manage_addZPsycopgConnection(self, id, title, connection_string,
zdatetime=None, tilevel=2,
encoding='', check=None, REQUEST=None):
"""Add a DB connection to a folder."""
self._setObject(id, Connection(id, title, connection_string,
zdatetime, check, tilevel, encoding))
if REQUEST is not None: return self.manage_main(self, REQUEST)
# the connection object
class Connection(Shared.DC.ZRDB.Connection.Connection):
"""ZPsycopg Connection."""
_isAnSQLConnection = 1
id = 'Psycopg2_database_connection'
database_type = 'Psycopg2'
meta_type = title = 'Z Psycopg 2 Database Connection'
icon = 'misc_/conn'
def __init__(self, id, title, connection_string,
zdatetime, check=None, tilevel=2, encoding='UTF-8'):
self.zdatetime = zdatetime
self.id = str(id)
self.edit(title, connection_string, zdatetime,
check=check, tilevel=tilevel, encoding=encoding)
def factory(self):
return DB
## connection parameters editing ##
def edit(self, title, connection_string,
zdatetime, check=None, tilevel=2, encoding='UTF-8'):
self.title = title
self.connection_string = connection_string
self.zdatetime = zdatetime
self.tilevel = tilevel
self.encoding = encoding
if check: self.connect(self.connection_string)
manage_properties = HTMLFile('dtml/edit', globals())
def manage_edit(self, title, connection_string,
zdatetime=None, check=None, tilevel=2, encoding='UTF-8',
REQUEST=None):
"""Edit the DB connection."""
self.edit(title, connection_string, zdatetime,
check=check, tilevel=tilevel, encoding=encoding)
if REQUEST is not None:
msg = "Connection edited."
return self.manage_main(self,REQUEST,manage_tabs_message=msg)
def connect(self, s):
try:
self._v_database_connection.close()
except:
pass
# check psycopg version and raise exception if does not match
if psycopg2.__version__.split(' ')[0] not in ALLOWED_PSYCOPG_VERSIONS:
raise ImportError("psycopg version mismatch (imported %s)" %
psycopg2.__version__)
self._v_connected = ''
dbf = self.factory()
# TODO: let the psycopg exception propagate, or not?
self._v_database_connection = dbf(
self.connection_string, self.tilevel, self.get_type_casts(), self.encoding)
self._v_database_connection.open()
self._v_connected = DateTime()
return self
def get_type_casts(self):
# note that in both cases order *is* important
if self.zdatetime:
return ZDATETIME, ZDATE, ZTIME
else:
return DATETIME, DATE, TIME
## browsing and table/column management ##
manage_options = Shared.DC.ZRDB.Connection.Connection.manage_options
# + (
# {'label': 'Browse', 'action':'manage_browse'},)
#manage_tables = HTMLFile('dtml/tables', globals())
#manage_browse = HTMLFile('dtml/browse', globals())
info = None
def table_info(self):
return self._v_database_connection.table_info()
def __getitem__(self, name):
if name == 'tableNamed':
if not hasattr(self, '_v_tables'): self.tpValues()
return self._v_tables.__of__(self)
raise KeyError, name
def tpValues(self):
res = []
conn = self._v_database_connection
for d in conn.tables(rdb=0):
try:
name = d['TABLE_NAME']
b = TableBrowser()
b.__name__ = name
b._d = d
b._c = c
try:
b.icon = table_icons[d['TABLE_TYPE']]
except:
pass
r.append(b)
except:
pass
return res
## database connection registration data ##
classes = (Connection,)
meta_types = ({'name':'Z Psycopg 2 Database Connection',
'action':'manage_addZPsycopgConnectionForm'},)
folder_methods = {
'manage_addZPsycopgConnection': manage_addZPsycopgConnection,
'manage_addZPsycopgConnectionForm': manage_addZPsycopgConnectionForm}
__ac_permissions__ = (
('Add Z Psycopg Database Connections',
('manage_addZPsycopgConnectionForm', 'manage_addZPsycopgConnection')),)
# add icons
misc_={'conn': ImageFile('icons/DBAdapterFolder_icon.gif', globals())}
for icon in ('table', 'view', 'stable', 'what', 'field', 'text', 'bin',
'int', 'float', 'date', 'time', 'datetime'):
misc_[icon] = ImageFile('icons/%s.gif' % icon, globals())
## zope-specific psycopg typecasters ##
# convert an ISO timestamp string from postgres to a Zope DateTime object
def _cast_DateTime(iso, curs):
if iso:
if iso in ['-infinity', 'infinity']:
return iso
else:
return DateTime(iso)
# convert an ISO date string from postgres to a Zope DateTime object
def _cast_Date(iso, curs):
if iso:
if iso in ['-infinity', 'infinity']:
return iso
else:
return DateTime(iso)
# Convert a time string from postgres to a Zope DateTime object.
# NOTE: we set the day as today before feeding to DateTime so
# that it has the same DST settings.
def _cast_Time(iso, curs):
if iso:
if iso in ['-infinity', 'infinity']:
return iso
else:
return DateTime(time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(time.time())[:3]+
time.strptime(iso[:8], "%H:%M:%S")[3:]))
# NOTE: we don't cast intervals anymore because they are passed
# untouched to Zope.
def _cast_Interval(iso, curs):
return iso
ZDATETIME = new_type((1184, 1114), "ZDATETIME", _cast_DateTime)
ZINTERVAL = new_type((1186,), "ZINTERVAL", _cast_Interval)
ZDATE = new_type((1082,), "ZDATE", _cast_Date)
ZTIME = new_type((1083,), "ZTIME", _cast_Time)
## table browsing helpers ##
class TableBrowserCollection(Acquisition.Implicit):
pass
class Browser(Base):
def __getattr__(self, name):
try:
return self._d[name]
except KeyError:
raise AttributeError, name
class values:
def len(self):
return 1
def __getitem__(self, i):
try:
return self._d[i]
except AttributeError:
pass
self._d = self._f()
return self._d[i]
class TableBrowser(Browser, Acquisition.Implicit):
icon = 'what'
Description = check = ''
info = HTMLFile('table_info', globals())
menu = HTMLFile('table_menu', globals())
def tpValues(self):
v = values()
v._f = self.tpValues_
return v
def tpValues_(self):
r=[]
tname=self.__name__
for d in self._c.columns(tname):
b=ColumnBrowser()
b._d=d
try: b.icon=field_icons[d['Type']]
except: pass
b.TABLE_NAME=tname
r.append(b)
return r
def tpId(self): return self._d['TABLE_NAME']
def tpURL(self): return "Table/%s" % self._d['TABLE_NAME']
def Name(self): return self._d['TABLE_NAME']
def Type(self): return self._d['TABLE_TYPE']
manage_designInput=HTMLFile('designInput',globals())
def manage_buildInput(self, id, source, default, REQUEST=None):
"Create a database method for an input form"
args=[]
values=[]
names=[]
columns=self._columns
for i in range(len(source)):
s=source[i]
if s=='Null': continue
c=columns[i]
d=default[i]
t=c['Type']
n=c['Name']
names.append(n)
if s=='Argument':
values.append("<dtml-sqlvar %s type=%s>'" %
(n, vartype(t)))
a='%s%s' % (n, boboType(t))
if d: a="%s=%s" % (a,d)
args.append(a)
elif s=='Property':
values.append("<dtml-sqlvar %s type=%s>'" %
(n, vartype(t)))
else:
if isStringType(t):
if find(d,"\'") >= 0: d=join(split(d,"\'"),"''")
values.append("'%s'" % d)
elif d:
values.append(str(d))
else:
raise ValueError, (
'no default was given for <em>%s</em>' % n)
class ColumnBrowser(Browser):
icon='field'
def check(self):
return ('\t<input type=checkbox name="%s.%s">' %
(self.TABLE_NAME, self._d['Name']))
def tpId(self): return self._d['Name']
def tpURL(self): return "Column/%s" % self._d['Name']
def Description(self):
d=self._d
if d['Scale']:
return " %(Type)s(%(Precision)s,%(Scale)s) %(Nullable)s" % d
else:
return " %(Type)s(%(Precision)s) %(Nullable)s" % d
table_icons={
'TABLE': 'table',
'VIEW':'view',
'SYSTEM_TABLE': 'stable',
}
field_icons={
NUMBER.name: 'i',
STRING.name: 'text',
DATETIME.name: 'date',
INTEGER.name: 'int',
FLOAT.name: 'float',
BOOLEAN.name: 'bin',
ROWID.name: 'int'
}

29
ZPsycopgDA/__init__.py Normal file
View File

@ -0,0 +1,29 @@
# ZPsycopgDA/__init__.py - ZPsycopgDA Zope product
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
__doc__ = "ZPsycopg Database Adapter Registration."
__version__ = '2.0'
import DA
def initialize(context):
context.registerClass(
DA.Connection,
permission = 'Add Z Psycopg 2 Database Connections',
constructors = (DA.manage_addZPsycopgConnectionForm,
DA.manage_addZPsycopgConnection),
icon = 'icons/DBAdapterFolder_icon.gif')

198
ZPsycopgDA/db.py Normal file
View File

@ -0,0 +1,198 @@
# ZPsycopgDA/db.py - query execution
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
from Shared.DC.ZRDB.TM import TM
from Shared.DC.ZRDB import dbi_db
from ZODB.POSException import ConflictError
import site
import pool
import psycopg2
from psycopg2.extensions import INTEGER, LONGINTEGER, FLOAT, BOOLEAN, DATE, TIME
from psycopg2.extensions import TransactionRollbackError, register_type
from psycopg2 import NUMBER, STRING, ROWID, DATETIME
# the DB object, managing all the real query work
class DB(TM, dbi_db.DB):
_p_oid = _p_changed = _registered = None
def __init__(self, dsn, tilevel, typecasts, enc='utf-8'):
self.dsn = dsn
self.tilevel = tilevel
self.typecasts = typecasts
self.encoding = enc
self.failures = 0
self.calls = 0
self.make_mappings()
def getconn(self, create=True):
conn = pool.getconn(self.dsn)
conn.set_isolation_level(int(self.tilevel))
conn.set_client_encoding(self.encoding)
for tc in self.typecasts:
register_type(tc, conn)
return conn
def putconn(self, close=False):
try:
conn = pool.getconn(self.dsn, False)
except AttributeError:
pass
pool.putconn(self.dsn, conn, close)
def getcursor(self):
conn = self.getconn()
return conn.cursor()
def _finish(self, *ignored):
try:
conn = self.getconn(False)
conn.commit()
self.putconn()
except AttributeError:
pass
def _abort(self, *ignored):
try:
conn = self.getconn(False)
conn.rollback()
self.putconn()
except AttributeError:
pass
def open(self):
# this will create a new pool for our DSN if not already existing,
# then get and immediately release a connection
self.getconn()
self.putconn()
def close(self):
# FIXME: if this connection is closed we flush all the pool associated
# with the current DSN; does this makes sense?
pool.flushpool(self.dsn)
def sortKey(self):
return 1
def make_mappings(self):
"""Generate the mappings used later by self.convert_description()."""
self.type_mappings = {}
for t, s in [(INTEGER,'i'), (LONGINTEGER, 'i'), (NUMBER, 'n'),
(BOOLEAN,'n'), (ROWID, 'i'),
(DATETIME, 'd'), (DATE, 'd'), (TIME, 'd')]:
for v in t.values:
self.type_mappings[v] = (t, s)
def convert_description(self, desc, use_psycopg_types=False):
"""Convert DBAPI-2.0 description field to Zope format."""
items = []
for name, typ, width, ds, p, scale, null_ok in desc:
m = self.type_mappings.get(typ, (STRING, 's'))
items.append({
'name': name,
'type': use_psycopg_types and m[0] or m[1],
'width': width,
'precision': p,
'scale': scale,
'null': null_ok,
})
return items
## tables and rows ##
def tables(self, rdb=0, _care=('TABLE', 'VIEW')):
self._register()
c = self.getcursor()
c.execute(
"SELECT t.tablename AS NAME, 'TABLE' AS TYPE "
" FROM pg_tables t WHERE tableowner <> 'postgres' "
"UNION SELECT v.viewname AS NAME, 'VIEW' AS TYPE "
" FROM pg_views v WHERE viewowner <> 'postgres' "
"UNION SELECT t.tablename AS NAME, 'SYSTEM_TABLE\' AS TYPE "
" FROM pg_tables t WHERE tableowner = 'postgres' "
"UNION SELECT v.viewname AS NAME, 'SYSTEM_TABLE' AS TYPE "
"FROM pg_views v WHERE viewowner = 'postgres'")
res = []
for name, typ in c.fetchall():
if typ in _care:
res.append({'TABLE_NAME': name, 'TABLE_TYPE': typ})
self.putconn()
return res
def columns(self, table_name):
self._register()
c = self.getcursor()
try:
r = c.execute('SELECT * FROM "%s" WHERE 1=0' % table_name)
except:
return ()
self.putconn()
return self.convert_description(c.description, True)
## query execution ##
def query(self, query_string, max_rows=None, query_data=None):
self._register()
self.calls = self.calls+1
desc = ()
res = []
nselects = 0
c = self.getcursor()
try:
for qs in [x for x in query_string.split('\0') if x]:
try:
if query_data:
c.execute(qs, query_data)
else:
c.execute(qs)
except TransactionRollbackError:
# Ha, here we have to look like we are the ZODB raising conflict errrors, raising ZPublisher.Publish.Retry just doesn't work
#logging.debug("Serialization Error, retrying transaction", exc_info=True)
raise ConflictError("TransactionRollbackError from psycopg2")
except psycopg2.OperationalError:
#logging.exception("Operational error on connection, closing it.")
try:
# Only close our connection
self.putconn(True)
except:
#logging.debug("Something went wrong when we tried to close the pool", exc_info=True)
pass
if c.description is not None:
nselects += 1
if c.description != desc and nselects > 1:
raise psycopg2.ProgrammingError(
'multiple selects in single query not allowed')
if max_rows:
res = c.fetchmany(max_rows)
else:
res = c.fetchall()
desc = c.description
self.failures = 0
except StandardError, err:
self._abort()
raise err
return self.convert_description(desc), res

106
ZPsycopgDA/dtml/add.dtml Normal file
View File

@ -0,0 +1,106 @@
<dtml-var manage_page_header>
<dtml-var "manage_form_title(this(), _,
form_title='Add Z Psycopg 2 Database Connection',
help_product='ZPsycopgDA',
help_topic='ZPsycopgDA-Method-Add.stx'
)">
<p class="form-help">
A Zope Psycopg 2 Database Connection is used to connect and execute
queries on a PostgreSQL database.
</p>
<p class="form-help">
In the form below <em>Connection String</em> (also called the Data Source Name
or DSN for short) is a string... (TODO: finish docs)
</p>
<form action="manage_addZPsycopgConnection" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40"
value="Psycopg2_database_connection" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40"
value="Z Psycopg 2 Database Connection"/>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Connection string
</div>
</td>
<td align="left" valign="top">
<input type="text" name="connection_string" size="40" value="" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Connect immediately
</div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="check" value="YES" checked="YES" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Use Zope's internal DateTime
</div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="zdatetime" value="YES" checked="YES" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Transaction isolation level
</div>
</td>
<td align="left" valign="top">
<select name="tilevel:int">
<option value="1">Read committed</option>
<option value="2" selected="YES">Serializable</option>
</select>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Encoding
</div>
</td>
<td align="left" valign="top">
<input type="text" name="encoding" size="40" value="" />
</td>
</tr>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-element">
<input class="form-element" type="submit" name="submit" value=" Add " />
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>

View File

@ -0,0 +1,11 @@
<html>
<head><title><dtml-var title_or_id >tables</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<dtml-var manage_tabs>
<dtml-tree header="info">
<IMG SRC="<dtml-var SCRIPT_NAME >/misc_/ZPsycopgDA/<dtml-var icon>"
ALT="<dtml-var Type>" BORDER="0">
<dtml-var Name><dtml-var Description>
</dtml-tree>
</body>
</html>

78
ZPsycopgDA/dtml/edit.dtml Normal file
View File

@ -0,0 +1,78 @@
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="manage_edit" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40"
value="&dtml-title;"/>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Connection string
</div>
</td>
<td align="left" valign="top">
<input type="text" name="connection_string" size="40"
value="&dtml-connection_string;" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Use Zope's internal DateTime
</div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="zdatetime" value="YES"
<dtml-if expr="zdatetime">checked="YES"</dtml-if> />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Transaction isolation level
</div>
</td>
<td align="left" valign="top">
<select name="tilevel:int">
<option value="1"
<dtml-if expr="tilevel==1">selected="YES"</dtml-if>>
Read committed</option>
<option value="2"
<dtml-if expr="tilevel==2">selected="YES"</dtml-if>>
Serializable</option>
</select>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Encoding
</div>
</td>
<td align="left" valign="top">
<input type="text" name="encoding" size="40"
value="&dtml-encoding;" />
</td>
</tr>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value=" Save Changes " />
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>

View File

@ -0,0 +1,7 @@
<dtml-var standard_html_header>
<dtml-var TABLE_TYPE><dtml-if TABLE_OWNER>
owned by <dtml-var TABLE_OWNER></dtml-if>
<dtml-if REMARKS><br><dtml-var REMARKS></dtml-if>
<dtml-var standard_html_footer>

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

BIN
ZPsycopgDA/icons/bin.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

BIN
ZPsycopgDA/icons/date.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

BIN
ZPsycopgDA/icons/field.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

BIN
ZPsycopgDA/icons/float.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

BIN
ZPsycopgDA/icons/int.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 B

BIN
ZPsycopgDA/icons/stable.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

BIN
ZPsycopgDA/icons/table.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
ZPsycopgDA/icons/text.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 B

BIN
ZPsycopgDA/icons/time.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

BIN
ZPsycopgDA/icons/view.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 B

BIN
ZPsycopgDA/icons/what.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

49
ZPsycopgDA/pool.py Normal file
View File

@ -0,0 +1,49 @@
# ZPsycopgDA/pool.py - ZPsycopgDA Zope product: connection pooling
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
# All the connections are held in a pool of pools, directly accessible by the
# ZPsycopgDA code in db.py.
import threading
import psycopg2.pool
_connections_pool = {}
_connections_lock = threading.Lock()
def getpool(dsn, create=True):
_connections_lock.acquire()
try:
if not _connections_pool.has_key(dsn) and create:
_connections_pool[dsn] = \
psycopg2.pool.PersistentConnectionPool(4, 200, dsn)
finally:
_connections_lock.release()
return _connections_pool[dsn]
def flushpool(dsn):
_connections_lock.acquire()
try:
_connections_pool[dsn].closeall()
del _connections_pool[dsn]
finally:
_connections_lock.release()
def getconn(dsn, create=True):
return getpool(dsn, create=create).getconn()
def putconn(dsn, conn, close=False):
getpool(dsn).putconn(conn, close=close)

7
debian/README.zpsycopgda2 vendored Normal file
View File

@ -0,0 +1,7 @@
ZPsycopgDA (in the Debian zope-psycopgda package) is a Zope Database
Adapter based on the psycopg Python/PostgreSQL driver. You'll find
more information and documentation in the pythonX.Y-psycopg package,
where X.Y is the version of your installed Python.
Details for ZPsycopgDA for Zope are found in the documentation of
the python2.3-psycopg package.

676
debian/changelog vendored Normal file
View File

@ -0,0 +1,676 @@
psycopg2 (2.0.7-2) unstable; urgency=medium
* ZPsycopgDA/DA.py: updated the patch. (Closes: #478860)
-- Fabio Tranchitella <kobold@debian.org> Thu, 01 May 2008 17:43:54 +0200
psycopg2 (2.0.7-1) unstable; urgency=low
* New upstream release. (Closes: #476101)
* debian/control: bumped Standard-Versions to 3.7.3.
-- Fabio Tranchitella <kobold@debian.org> Tue, 15 Apr 2008 10:05:51 +0200
psycopg2 (2.0.6-4) unstable; urgency=low
[ Sandro Tosi ]
* debian/control
- uniforming Vcs-Browser field
[ Fabio Tranchitella ]
* Provides a encoding parameter when adding a ZPsycopgDA instance using the
ZMI. (Closes: #475123)
-- Fabio Tranchitella <kobold@debian.org> Wed, 09 Apr 2008 19:51:10 +0200
psycopg2 (2.0.6-3) unstable; urgency=low
[ Piotr Ożarowski ]
* XS-Vcs-Svn field renamed to Vcs-Svn
* Vcs-Browser field added
[ Fabio Tranchitella ]
* Mention DB-API 2.0 compatibility in the long description.
(Closes: #430763)
-- Fabio Tranchitella <kobold@debian.org> Thu, 08 Nov 2007 15:07:05 +0100
psycopg2 (2.0.6-2) unstable; urgency=low
* Build a python-psycopg-dbg package
-- Scott Kitterman <scott@kitterman.com> Tue, 03 Jul 2007 16:55:48 -0400
psycopg2 (2.0.6-1) unstable; urgency=low
* New upstream release.
* psycopg2da: removed, merged upstream.
-- Fabio Tranchitella <kobold@debian.org> Sat, 09 Jun 2007 22:38:23 +0200
psycopg2 (2.0.5.1-7) UNRELEASED; urgency=low
* debian/watch: added.
-- Fabio Tranchitella <kobold@debian.org> Fri, 9 Feb 2007 12:35:55 +0100
psycopg2 (2.0.5.1-6) unstable; urgency=high
* debian/zope-psycopgda2.dzproduct: requires Zope 2.9 or higher: previous
versions use python2.3 which is not supported anymore in psycopg.
-- Fabio Tranchitella <kobold@debian.org> Mon, 15 Jan 2007 11:39:15 +0100
psycopg2 (2.0.5.1-5) unstable; urgency=medium
* Do not run dh_pycentral on zope-psycopgda2. (Closes: #400846)
-- Fabio Tranchitella <kobold@debian.org> Wed, 29 Nov 2006 09:04:09 +0100
psycopg2 (2.0.5.1-4) unstable; urgency=medium
* Fixed a bug in psycopg2da.
* debian/control: bumped build-dependency on zope-debhelper.
* Added XS-Vcs-Svn field
-- Fabio Tranchitella <kobold@debian.org> Fri, 24 Nov 2006 13:50:11 +0100
psycopg2 (2.0.5.1-3) unstable; urgency=low
* psycopgda: imported upstream psycopg2da database adapter from SVN, which
builds a new binary package, python-psycopg2da.
-- Fabio Tranchitella <kobold@debian.org> Fri, 10 Nov 2006 08:56:05 +0100
psycopg2 (2.0.5.1-2) unstable; urgency=low
* debian/control: added again a dependency on python-egenix-mxdatetime.
(Closes: #389636)
-- Fabio Tranchitella <kobold@debian.org> Tue, 3 Oct 2006 10:25:22 +0200
psycopg2 (2.0.5.1-1) unstable; urgency=low
* New upstream release.
-- Fabio Tranchitella <kobold@debian.org> Tue, 19 Sep 2006 08:22:36 +0200
psycopg2 (2.0.4-1) unstable; urgency=low
* New upstream release.
* debian/control:
+ removed dependency on python-egenix-mxdatetime.
+ added ${shlibs:Depends} for the python-psycopg2 package.
(Closes: #381462)
-- Fabio Tranchitella <kobold@debian.org> Wed, 9 Aug 2006 10:28:30 +0200
psycopg2 (2.0.2-1) unstable; urgency=low
* New upstream major release, new source package. (Closes: #377956)
-- Fabio Tranchitella <kobold@debian.org> Sun, 16 Jul 2006 21:43:41 +0200
psycopg (1.1.21-8) unstable; urgency=low
* debian/zope-psycopgda.dzproduct: added 2.9 to the list of supported
zope versions. (Closes: #376538)
-- Fabio Tranchitella <kobold@debian.org> Fri, 14 Jul 2006 10:19:54 +0200
psycopg (1.1.21-7) unstable; urgency=low
* Moved dh_installzope within an arch-indep target. (Closes: #373842)
-- Fabio Tranchitella <kobold@debian.org> Fri, 16 Jun 2006 09:37:23 +0200
psycopg (1.1.21-6) unstable; urgency=low
* Python policy transition. (Closes: #373482)
-- Fabio Tranchitella <kobold@debian.org> Thu, 15 Jun 2006 19:09:36 +0200
psycopg (1.1.21-5) unstable; urgency=high
* ypemod.c, new_psyco_bufferobject():
- Escape quotes psycopg.Binary() results as '', not as \', since the
latter does not work any more with some client encodings with the latest
PostgreSQL (in some multi-byte encodings you can exploit \' escaping to
inject SQL code, see CVE-2006-2314). (Closes: #369230)
Thanks to Martin Pitt and Ubuntu security team for the patch.
-- Fabio Tranchitella <kobold@debian.org> Tue, 30 May 2006 22:15:06 +0200
psycopg (1.1.21-4) unstable; urgency=low
* debian/rules: remove *.o in the clean target. (Closes: #352835)
-- Fabio Tranchitella <kobold@debian.org> Thu, 16 Feb 2006 12:06:53 +0000
psycopg (1.1.21-3) unstable; urgency=low
* debian/control: removed build-dependency on postgresql-server-dev-8.0,
as suggested by Martin Pitt. (Closes: #339640)
-- Fabio Tranchitella <kobold@debian.org> Fri, 18 Nov 2005 08:44:26 +0000
psycopg (1.1.21-2) unstable; urgency=low
* debian/control: zope-psycopgda should depend on the same version of the
psycopg python module. (Closes: #336765)
-- Fabio Tranchitella <kobold@debian.org> Wed, 2 Nov 2005 12:07:33 +0000
psycopg (1.1.21-1) unstable; urgency=low
* New maintainer; Thanks Federico for your work, and be sure that I'll
take care of this package.
* New upstream release (Closes: #321592, #320618, #333638)
* debian/python2.4-psycopg.dirs: added. (Closes: #319509, #329115)
* debian/control: dropped support for python2.1 and
python2.2. (Closes: #333639)
* debian/control: Standards-Version bumped to 3.6.2, no changes required.
* debian/rules: make use of dh_installzope from zope-debhelper to build the
zope-psycopgda package.
(Closes: #158669, #323599, #268975, #292247, #327415)
* debian/control: added build-depends on postgresql-server-dev-8.0.
(Closes: #333638)
* Re-packaged upstream tarball replacing some broken images.
(Closes: #292008, #305392)
-- Fabio Tranchitella <kobold@debian.org> Fri, 28 Oct 2005 11:24:37 +0000
psycopg (1.1.19-1) unstable; urgency=low
* New upstream release.
* Applied patch from Martin Krafft to build Zope 2.7 packages.
* Modified to use the new PostgreSQL packages.
* Added python 2.4 package (Closes: #301403).
* Upstream applied various Ubuntu patches (Closes: #301947, #300893).
-- Federico Di Gregorio <fog@debian.org> Sat, 16 Jul 2005 20:47:08 +0200
psycopg (1.1.18-1) unstable; urgency=low
* New upstream release.
* 1.1.16 fixed rowcount bug (closes: #266299).
-- Federico Di Gregorio <fog@debian.org> Wed, 5 Jan 2005 21:05:15 +0100
psycopg (1.1.17-1) unstable; urgency=high
* Urgency is still high because 1.1.16 was never uploaded.
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Thu, 19 Nov 2004 01:14:30 +0200
psycopg (1.1.16-1) unstable; urgency=high
* New upstream release.
* Tagged with urgency=high because fix a grave bug (rowcount) introduced
in 1.1.15.
* Upstream fix: does not segfault when using COPY TO/COPY FROM in
.execute() (closes: #279222).
-- Federico Di Gregorio <fog@debian.org> Sat, 30 Oct 2004 02:35:30 +0200
psycopg (1.1.15-1) unstable; urgency=low
* New upstream release.
* Definitely fixed (ah ah) time interval problems (closes: #259213).
-- Federico Di Gregorio <fog@initd.org> Thu, 29 Jul 2004 23:43:59 +0200
psycopg (1.1.14-1) unstable; urgency=low
* New upstream release.
* Don't put two copies of changelog in every package anymore
(closes: #256662).
* Updated test script works as expected (closes: #231391).
* Changes from NMU incorporated in 1.1.12:
- zpsycopgda depends on python2.2-psycopg (closes: #227420, #227147).
- compiled with postgresql in unstable (close: #220527).
-- Federico Di Gregorio <fog@initd.org> Fri, 9 Jul 2004 23:01:40 +0200
psycopg (1.1.13-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Fri, 21 May 2004 10:33:54 +0200
psycopg (1.1.12-1) unstable; urgency=low
* New upstream release (the "martin you won't have this package"
release.)
* Integrated changes from NMU releases.
-- Federico Di Gregorio <fog@debian.org> Sun, 16 May 2004 10:14:47 +0200
psycopg (1.1.10-1.2) unstable; urgency=low
* Non-maintainer upload. Thinking about taking this package over...
* Changed dependency on pyscopgda Python module to Python version 2.2.
(closes: #227147, #227420)
* Added Lintian overrides for image-in-/usr/lib warnings -- Zope needs
these images...
-- martin f. krafft <madduck@debian.org> Thu, 15 Apr 2004 23:30:40 +0200
psycopg (1.1.10-1.1) unstable; urgency=low
* Non-maintainer upload.
* No changes - this upload is simply a rebuild against the current unstable
instead of experimental postgresql-dev.
(closes: #219927, #220141, #220173, #220527)
-- Peter Hawkins <peterh@debian.org> Sun, 28 Dec 2003 10:57:30 +1100
psycopg (1.1.10-1) unstable; urgency=low
* Added download location to debian/copyright file (Closes: #215880).
-- Federico Di Gregorio <fog@initd.org> Sat, 8 Nov 2003 23:32:40 +0100
psycopg (1.1.9-1) unstable; urgency=low
* New upstream release.
* Bug was agains an old 1.0.x version of psycopg (Closes: #208702).
-- Federico Di Gregorio <fog@initd.org> Wed, 10 Sep 2003 13:04:42 +0200
psycopg (1.1.8-1) unstable; urgency=low
* New upstream release.
* Integrated NMU from Matthias Klose (closes: #205746).
-- Federico Di Gregorio <fog@debian.org> Fri, 1 Aug 2003 11:50:57 +0200
psycopg (1.1.5.1-1.1) unstable; urgency=low
* NMU
* Update for python2.3 as the default python version (closes: #205746).
-- Matthias Klose <doko@debian.org> Fri, 22 Aug 2003 00:02:25 +0200
psycopg (1.1.7-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Sat, 26 Jul 2003 15:03:39 +0200
psycopg (1.1.6-1) unstable; urgency=low
* New upstream release.
* Upstream applied patch from BTS (Closes: #200161).
-- Federico Di Gregorio <fog@initd.org> Sun, 13 Jul 2003 23:36:04 +0200
psycopg (1.1.5.1-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@initd.org> Mon, 23 Jun 2003 00:37:33 +0200
psycopg (1.1.5-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@initd.org> Sun, 22 Jun 2003 21:30:01 +0200
psycopg (1.1.4-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Wed, 7 May 2003 15:21:31 +0200
psycopg (1.1.3-1) unstable; urgency=low
* New upstream release.
* Changed section in debian/control (-> python).
-- Federico Di Gregorio <fog@debian.org> Wed, 2 Apr 2003 10:33:36 +0200
psycopg (1.1.2-1) unstable; urgency=low
* New upstream release.
* Started to track the 1.1.x branch.
-- Federico Di Gregorio <fog@debian.org> Tue, 25 Feb 2003 01:06:08 +0100
psycopg (1.0.15.1-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Fri, 14 Feb 2003 16:09:50 +0100
psycopg (1.0.15-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Wed, 12 Feb 2003 23:49:51 +0100
psycopg (1.0.14-1) unstable; urgency=low
* Applied patch from John Goerzen to fix memory leak in executemany()
and callproc() (Closes: #169284).
* New upstream release (Closes: #170297).
-- Federico Di Gregorio <fog@debian.org> Mon, 25 Nov 2002 16:50:37 +0100
psycopg (1.0.13-1) unstable; urgency=low
* New upstream release.
* Python 2.3 package added (Closes: #160831)
* IntegrityError raised when needed (upstream, Closes: #165791)
* Packages are lintian clean again.
-- Federico Di Gregorio <fog@debian.org> Fri, 25 Oct 2002 11:54:19 +0200
psycopg (1.0.12-1) unstable; urgency=low
* New upstream release.
* Fixed wrong url in RELEASE-1.0. (Closes: #153840)
-- Federico Di Gregorio <fog@debian.org> Fri, 13 Sep 2002 13:16:36 +0200
psycopg (1.0.11.1-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Mon, 26 Aug 2002 10:41:54 +0200
psycopg (1.0.11-1) unstable; urgency=low
* New upstream release.
* The dummy python-psycopg package now depends on the new default debian
python (2.2) and on python2.2-psycopg.
* Removed support for python 1.5 (support for 2.3 has to wait for egenix
packages.)
-- Federico Di Gregorio <fog@debian.org> Fri, 23 Aug 2002 11:25:01 +0200
psycopg (1.0.10-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@initd.org> Mon, 22 Jul 2002 02:04:59 +0200
psycopg (1.0.9-1) unstable; urgency=low
* Resolved section override (main->interpreters).
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Thu, 20 Jun 2002 14:00:42 +0200
psycopg (1.0.8-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Tue, 23 Apr 2002 22:42:22 +0200
psycopg (1.0.7.1-2) unstable; urgency=low
* Moved to main.
-- Federico Di Gregorio <fog@debian.org> Fri, 19 Apr 2002 10:06:58 +0200
psycopg (1.0.7.1-1) unstable; urgency=low
* New upstream release.
* Fixed a bug in ./configure; closes: #141774.
-- Federico Di Gregorio <fog@debian.org> Mon, 8 Apr 2002 18:54:24 +0200
psycopg (1.0.7-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Fri, 29 Mar 2002 14:24:45 +0100
psycopg (1.0.6-1) unstable; urgency=low
* New upstream release.
* Builds with new libpq libraries and header layout.
-- Federico Di Gregorio <fog@debian.org> Thu, 7 Mar 2002 11:59:40 +0100
psycopg (1.0.5-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Mon, 4 Mar 2002 14:43:13 +0100
psycopg (1.0.4-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Wed, 20 Feb 2002 20:37:16 +0100
psycopg (1.0.3-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Fri, 8 Feb 2002 15:17:44 +0100
psycopg (1.0.2-1) unstable; urgency=low
* New upstream release.
* Added package for python2.2 (Closes: #132650).
-- Federico Di Gregorio <fog@debian.org> Fri, 8 Feb 2002 00:45:07 +0100
psycopg (1.0.1-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Sun, 20 Jan 2002 18:27:22 +0100
psycopg (1.0-4) unstable; urgency=low
* Added build depend on plain python, to really close the %£$! #121229
bug this time (Closes: #121229).
-- Federico Di Gregorio <fog@debian.org> Wed, 28 Nov 2001 10:50:06 +0100
psycopg (1.0-3) unstable; urgency=low
* Added explicit build depends on python 1.5 & 2.1 (Closes: #121229).
* Fixed bad dependency on python1.5-egenix-mxdatetime.
-- Federico Di Gregorio <fog@debian.org> Mon, 26 Nov 2001 17:18:41 +0100
psycopg (1.0-2) unstable; urgency=low
* Fixed dependencies as per python policy.
* Added default, unversioned psycopg package (python-psycopg).
* Added non-US/main and rebuilt after REJECT.
-- Federico Di Gregorio <fog@debian.org> Fri, 16 Nov 2001 01:14:54 +0100
psycopg (1.0-1) unstable; urgency=low
* New upstream release. 1.0!
* Now we build versioned packages for python 1.5 and 2.1.
-- Federico Di Gregorio <fog@debian.org> Tue, 13 Nov 2001 19:24:39 +0100
psycopg (0.99.7-1) unstable; urgency=low
* New upstream release fixing some little bugs.
* This version requires the mx DateTime packages that are not yet in
debian... waiting for them I'll distribute both psycopg and unofficial
packages on the initd psycopg page.
-- Federico Di Gregorio <fog@debian.org> Tue, 18 Sep 2001 23:28:51 +0200
psycopg (0.99.6-2) unstable; urgency=low
* Added suggested build-depends (Closes: #112112).
* Applied patch by Michael Weber to configure.in, to look for a compiler
(Closes: #112024).
-- Federico Di Gregorio <fog@debian.org> Thu, 13 Sep 2001 10:49:37 +0200
psycopg (0.99.6-1) unstable; urgency=low
* Added Build-depends line (Closes: #89798).
* Now zope-psycopgda requires python-psycopg, zope on debian still runs
with python 1.x only (Closes: #108890).
* Moved package to non-US (psycopg depends on postgresql that is in
non-US, sic).
-- Federico Di Gregorio <fog@debian.org> Mon, 3 Sep 2001 13:02:11 +0200
psycopg (0.99.5-1) unstable; urgency=low
* New upstream release with bound variables quoting (Closes: #102843).
* The build process set the correct path to DateTime module
(Closes: #102838).
* Removes .pyc files in prerm (Closes: #104382)
-- Federico Di Gregorio <fog@debian.org> Thu, 12 Jul 2001 12:56:38 +0200
psycopg (0.99.4-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Mon, 2 Jul 2001 15:33:29 +0200
psycopg (0.99.3-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Wed, 20 Jun 2001 12:55:47 +0200
psycopg (0.99.2-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Tue, 5 Jun 2001 15:37:50 +0200
psycopg (0.99.1-1) unstable; urgency=low
* New upstream release.
-- Federico Di Gregorio <fog@debian.org> Tue, 5 Jun 2001 12:46:18 +0200
psycopg (0.5.5-1) unstable; urgency=low
* New upstream release (ok, *we* are the upstream authors, but after
putting the -1 in the version i am supposed to say "new upstream
version" when the non-debian versions changes, right? ouch...)
-- Federico Di Gregorio <fog@debian.org> Fri, 1 Jun 2001 17:18:52 +0200
psycopg (0.5.4-1) unstable; urgency=low
* Another bugfixing release.
* Added debian revision to be able to release multiple versions with the
same upstream version.
-- Federico Di Gregorio <fog@debian.org> Fri, 18 May 2001 19:32:59 +0200
psycopg (0.5.3) unstable; urgency=low
* Some bugs fixed, new release.
-- Federico Di Gregorio <fog@debian.org> Fri, 4 May 2001 16:19:09 +0200
psycopg (0.5.2) unstable; urgency=low
* New bugfixing release.
-- Federico Di Gregorio <fog@debian.org> Fri, 27 Apr 2001 09:52:16 +0200
psycopg (0.5.1) unstable; urgency=low
* New bugfixing release.
-- Federico Di Gregorio <fog@debian.org> Tue, 3 Apr 2001 11:13:26 +0200
psycopg (0.5.0) unstable; urgency=low
* New release.
-- Federico Di Gregorio <fog@debian.org> Fri, 30 Mar 2001 12:54:42 +0200
psycopg (0.4.7) unstable; urgency=low
* New release.
* Lots of small bug fixes (see detailed ChangeLog.)
* Includes beginning of DBAPI-2.0 testsuite.
-- Federico Di Gregorio <fog@debian.org> Fri, 16 Mar 2001 18:29:03 +0100
psycopg (0.4.6) unstable; urgency=low
* New release.
* Fixed a little bug in debian/rules (does not create an examples
directory inside examples.)
-- Federico Di Gregorio <fog@debian.org> Wed, 14 Mar 2001 01:00:26 +0100
psycopg (0.4.5) unstable; urgency=low
* New upstream (mmm... but one of the upstream authors it is
*me*... mmm...) release.
-- Federico Di Gregorio <fog@debian.org> Mon, 12 Mar 2001 11:41:42 +0100
psycopg (0.4.4) unstable; urgency=low
* New release.
* Fixed Sections in debian/control.
-- Federico Di Gregorio <fog@debian.org> Fri, 9 Mar 2001 10:11:02 +0100
psycopg (0.4.3) unstable; urgency=low
* New release.
* Fixed typo in connectionAdd.dtml (Closes: #88817)
-- Federico Di Gregorio <fog@debian.org> Wed, 7 Mar 2001 15:54:35 +0100
psycopg (0.4.2) unstable; urgency=low
* New release (fixes bugs in ZPsycopgDA.)
-- Federico Di Gregorio <fog@debian.org> Mon, 5 Mar 2001 13:33:39 +0100
psycopg (0.4.1) unstable; urgency=low
* New release.
* we now create packages for both versions of python in debian
(1.5 and 2.0, packages python-* and python2-*)
-- Federico Di Gregorio <fog@debian.org> Fri, 2 Mar 2001 12:10:52 +0100
psycopg (0.4) unstable; urgency=low
* News release.
* Now debian/rules build the Zope Database Adapter zope-psycopgda too.
* Source name changed from python-psycopg to psycopg.
-- Federico Di Gregorio <fog@debian.org> Tue, 27 Feb 2001 15:11:04 +0100
python-psycopg (0.3) unstable; urgency=low
* New release. Tons of bugs fixed and new features, see ChangeLog for
details.
-- Federico Di Gregorio <fog@debian.org> Mon, 26 Feb 2001 21:22:23 +0100
python-psycopg (0.2) unstable; urgency=low
* New release. Fixed lots of bugs and memory leaks.
-- Federico Di Gregorio <fog@debian.org> Fri, 16 Feb 2001 11:04:17 +0100
python-psycopg (0.1) unstable; urgency=low
* Initial release.
-- Federico Di Gregorio <fog@debian.org> Mon, 12 Feb 2001 14:46:53 +0100

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
5

64
debian/control vendored Normal file
View File

@ -0,0 +1,64 @@
Source: psycopg2
Section: python
Priority: optional
Build-Depends: debhelper (>= 5.0.37.2), python-all-dev, python-all-dbg, python-central (>= 0.5.0), python (>= 2.3.5-7), python-egenix-mx-base-dev, autoconf, libpq-dev
Build-Depends-Indep: zope-debhelper (>= 0.3.4)
Maintainer: Fabio Tranchitella <kobold@debian.org>
Standards-Version: 3.7.3
XS-Python-Version: all
Vcs-Svn: svn://svn.debian.org/python-modules/packages/psycopg2/trunk/
Vcs-Browser: http://svn.debian.org/wsvn/python-modules/packages/psycopg2/trunk/?op=log
Package: python-psycopg2
Architecture: any
Section: python
Depends: ${python:Depends}, ${shlibs:Depends}, python-egenix-mxdatetime
Provides: ${python:Provides}
XB-Python-Version: ${python:Versions}
Description: Python module for PostgreSQL
psycopg is a PostgreSQL database adapter for the Python programming language
(just like pygresql and popy.) This is version 2, a complete rewrite of the
original code to provide new-style classes for connection and cursor objects
and other sweet candies. Like the original, psycopg 2 was written with the
aim of being very small and fast, and stable as a rock.
.
psycopg is different from the other database adapter because it was designed
for heavily multi-threaded applications that create and destroy lots of
cursors and make a conspicuous number of concurrent INSERTs or UPDATEs.
psycopg 2 also provides full asycronous operations for the really brave
programmer.
.
The main advantages of psycopg2 are that it supports the full Python DBAPI-2.0
and being thread safe at level 2. It also includes some extensions to the
standard DBAPI-2.0 to allow for better thread performance.
Package: python-psycopg2-dbg
Priority: extra
Architecture: any
Section: python
Depends: python-psycopg2 (= ${binary:Version}), python-dbg, python-egenix-mxdatetime-dbg, ${shlibs:Depends}
Description: Python module for PostgreSQL (debug extension)
psycopg is a PostgreSQL database adapter for the Python programming language
(just like pygresql and popy.) This is version 2, a complete rewrite of the
original code to provide new-style classes for connection and cursor objects
and other sweet candies. Like the original, psycopg 2 was written with the
aim of being very small and fast, and stable as a rock.
.
This package contains the extensions built for the Python debug interpreter.
Package: zope-psycopgda2
Architecture: all
Section: python
Depends: ${zope:Depends}, python-psycopg2 (>= ${source:Version})
Description: Zope database adapter based on python-psycopg2
The package contains the PostgreSQL database adapter for Zope 2.7, 2.8 and
2.9 based on the psycopg2 Python module.
Package: python-psycopg2da
Architecture: all
Section: python
Depends: ${zope:Depends}, python-psycopg2 (>= ${source:Version})
XB-Python-Version: ${zope:PythonVersion}
Description: Zope database adapter based on python-psycopg2 -- zope3 version
The package contains the PostgreSQL database adapter for Zope 3 based on
the psycopg2 Python module.

112
debian/copyright vendored Normal file
View File

@ -0,0 +1,112 @@
This package was debianized by Fabio Tranchitella <kobold@debian.org> on
Sun, 16 Jul 2006 21:10:01 +0200.
psycopg2 can be downloaded from its homepage:
http://initd.org/projects/psycopg
The tarball has been re-packed to get rid of the upstream debian/ directory:
no other changes have been made to the tarball.
Copyright:
Copyright (C) 2001-2006 Federico Di Gregorio <fog@debian.org>
Copyright (C) 2001 Michele Comitini <mcm@initd.org>
For psycopg2da:
Copyright (C) 2006 Fabio Tranchitella <kobold@debian.org>
For the files doc/copy_from.py and doc/copy_to.py:
Copyright (C) 2001-2005 Federico Di Gregorio <fog@debian.org>
Copyright (C) 2002 Tom Jenkins <tjenkins@devis.com>
For the file tests/dbapi20.py:
Copyright (C) 2003 Ian Bicking <ianb@colorstudy.com>
For the file scripts/ext2html.py:
Copyright (C) 2003 Daniele Varrazzo <daniele.varrazzo@gmail.com>
License for psycopg2, ZPsycopgDA and psycopg2da:
psycopg is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
On Debian GNU/Linux systems, the complete text of the GNU General
Public License can be found in '/usr/share/common-licenses/GPL'.
As a special exception, specific permission is granted for the GPLed
code in this distribition to be linked to OpenSSL and PostgreSQL libpq
without invoking GPL clause 2(b).
Note that the GPL was chosen to avoid proprietary adapters based on
psycopg code. Using psycopg in a proprietary product (even bundling
psycopg with the proprietary product) is fine as long as:
1. psycopg is called from Python only using only the provided API
(i.e., no linking with C code and no C modules based on it); and
2. all the other points of the GPL are respected (you offer a copy
of psycopg's source code, and so on.)
License for the files tests/dbapi20.py and scripts/ext2html.py:
These modules have been placed in the public domain.
Alternative licenses for ZPsycopgDA:
If you prefer you can use the Zope Database Adapter ZPsycopgDA (i.e.,
every file inside the ZPsycopgDA directory) user the ZPL license as
published on the Zope web site, http://www.zope.org/Resources/ZPL.
Alternative licenses for psycopg2da:
If you prefer you can use the Zope3 Database Adapter psycopg2da (i.e.,
every file inside the psycopg2da directory) user the ZPL license as
published on the Zope web site, http://www.zope.org/Resources/ZPL.
Alternative licenses for psycopg/adapter*.{j,c} and
psycopg/microprotocol*.{h.c}:
Also, the following BSD-like license applies (at your option) to the
files following the pattern psycopg/adapter*.{h,c} and
psycopg/microprotocol*.{h,c}:
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
psycopg 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 General Public License for more details.
Proprietary licenses:
A non-exclusive license is available for companies that want to include
psycopg in their proprietary products without respecting the spirit of the
GPL. The price of the license is one day of development done by the author,
at the consulting fee he applies to his usual customers at the day of the
request.
Please contact the upstream author (Federico Di Gregorio <fog@debian.org>)
for more information about this license.

1
debian/pycompat vendored Normal file
View File

@ -0,0 +1 @@
2

3
debian/python-psycopg2da.dzproduct vendored Normal file
View File

@ -0,0 +1,3 @@
Name: psycopg2da
ZopeVersions: 3
Global: yes

93
debian/rules vendored Executable file
View File

@ -0,0 +1,93 @@
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
PYVERS=$(shell pyversions -r debian/control)
configure: configure-stamp
configure-stamp:
dh_testdir
rm -f configure
touch configure-stamp
build: configure build-stamp
build-stamp:
dh_testdir
for python in $(PYVERS); do \
$$python setup.py build ; \
done
for python in $(PYVERS); do \
$$python-dbg setup.py build ; \
done
touch build-stamp
clean: configure
dh_testdir
dh_testroot
rm -fr *-stamp build
for python in $(PYVERS); do \
$$python setup.py clean ; \
done
dh_clean
install-arch: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# psycopg2
for python in $(PYVERS); do \
$$python setup.py install \
--root=$(CURDIR)/debian/python-psycopg2 --no-compile; \
done
for python in $(PYVERS); do \
$$python-dbg setup.py install \
--root=$(CURDIR)/debian/python-psycopg2-dbg --no-compile; \
done
find debian/python-*-dbg ! -type d ! -name '*.so' | xargs rm -f
find debian/python-*-dbg -depth -empty -exec rmdir {} \;
install-indep: build
# Zope package
dh_installzope -p zope-psycopgda2 ZPsycopgDA
# Zope3 package
dh_installzope -p python-psycopg2da psycopg2da
# Build architecture-independent files here.
binary-indep: build install-indep
dh_testdir
dh_testroot
dh_installdocs -i AUTHORS
dh_installchangelogs -i
dh_link -i
dh_compress -i
dh_fixperms -i
dh_pycentral -p python-psycopg2da
dh_installdeb -i
dh_gencontrol -i
dh_md5sums -i
dh_builddeb -i
# Build architecture-dependent files here.
binary-arch: build install-arch
dh_testdir
dh_testroot
dh_installdocs -a README AUTHORS doc tests
dh_installchangelogs -a ChangeLog
dh_link -a
dh_strip -ppython-psycopg2 --dbg-package=python-psycopg2-dbg
rm -rf debian/python-psycopg2-dbg/usr/share/doc/python-psycopg2-dbg
ln -s python-psycopg2 debian/python-psycopg2-dbg/usr/share/doc/python-psycopg2-dbg
dh_compress -a
dh_fixperms -a
dh_makeshlibs -a
dh_pycentral -a
dh_python -a
dh_installdeb -a
dh_shlibdeps -a
dh_gencontrol -a
dh_md5sums -a
dh_builddeb -a
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

2
debian/watch vendored Normal file
View File

@ -0,0 +1,2 @@
version=3
http://www.initd.org/pub/software/psycopg/psycopg2-([0-9][0-9\.\-]*).tar.gz debian uupdate

4
debian/zope-psycopgda2.dzproduct vendored Normal file
View File

@ -0,0 +1,4 @@
Name: ZPsycopgDA
Directory: ZPsycopgDA:2
Package: zope-psycopgda2
ZopeVersions: >= 2.9

8
doc/.gitignore vendored
View File

@ -1,8 +0,0 @@
env
src/_build/*
html/*
psycopg2.txt
src/sqlstate_errors.rst
# Added by psycopg-website to customize published docs
src/_templates/layout.html

676
doc/COPYING Normal file
View File

@ -0,0 +1,676 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -1,7 +1,7 @@
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -10,7 +10,7 @@
the terms and conditions of version 3 of the GNU General Public the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below. License, supplemented by the additional permissions listed below.
0. Additional Definitions. 0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License, and the "GNU GPL" refers to version 3 of the GNU
@ -111,7 +111,7 @@ the following:
a copy of the Library already present on the user's computer a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked of the Library that is interface-compatible with the Linked
Version. Version.
e) Provide Installation Information, but only if you would otherwise e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the be required to provide such information under section 6 of the

1744
doc/ChangeLog-1.x Normal file

File diff suppressed because it is too large Load Diff

43
doc/HACKING Normal file
View File

@ -0,0 +1,43 @@
General information
*******************
Some help to people wanting to hack on psycopg. First of all, note that
*every* function in the psycopg module source code is prefixed by one of the
following words:
psyco is used for function directly callable from python (i.e., functions
in the psycopg module itself.) the only notable exception is the
source code for the module itself, that uses "psyco" even for C-only
functions.
conn is used for functions related to connection objects.
curs is used for functions related to cursor objects.
typecast is used for typecasters and utility function related to
typecaster creation and registration.
Pythonic definition of types and functions available from python are defined
in *_type.c files. Internal functions, callable only from C are located in
*_int.c files and extensions to the DBAPI can be found in the *_ext.c files.
Patches
*******
If you submit a patch, please send a diff generated with the "-u" switch.
Also note that I don't like that much cosmetic changes (like renaming
already existing variables) and I will rewrap the patch to 78 columns
anyway, so it is much better if you do that beforehand.
The type system
***************
Simple types, like integers and strings, are converted to python base types
(the conversion functions are in typecast_base.c). Complex types are
converted to ad-hoc types, defined in the typeobj_*.{c,h} files. The
conversion function are in the other typecast_*.c files. typecast.c defines
the basic utility functions (available through the psycopg module) used when
defining new typecasters from C and python.

View File

@ -1,39 +1,23 @@
.PHONY: env help clean html package doctest .PHONY: help clean html text doctest
docs: html docs: html text
check: doctest check: doctest
# The environment is currently required to build the documentation. help:
# It is not clean by 'make clean' cd src && $(MAKE) $@
PYTHON := python$(PYTHON_VERSION) html:
PYTHON_VERSION ?= $(shell $(PYTHON) -c 'import sys; print("%d.%d" % sys.version_info[:2])') cd src && $(MAKE) $@
BUILD_DIR = $(shell pwd)/../build/lib.$(PYTHON_VERSION)
SPHINXBUILD ?= $$(pwd)/env/bin/sphinx-build
SPHOPTS = SPHINXBUILD=$(SPHINXBUILD)
html: package src/sqlstate_errors.rst
$(MAKE) $(SPHOPTS) -C src $@
cp -r src/_build/html . cp -r src/_build/html .
src/sqlstate_errors.rst: ../psycopg/sqlstate_errors.h $(BUILD_DIR) text:
./env/bin/python src/tools/make_sqlstate_docs.py $< > $@ cd src && $(MAKE) $@
cd src && tools/stitch_text.py index.rst _build/text > ../psycopg2.txt
$(BUILD_DIR):
$(MAKE) PYTHON=$(PYTHON) -C .. package
doctest: doctest:
$(MAKE) PYTHON=$(PYTHON) -C .. package cd src && $(MAKE) $@
$(MAKE) $(SPHOPTS) -C src $@
clean: clean:
$(MAKE) $(SPHOPTS) -C src $@ cd src && $(MAKE) $@
rm -rf html src/sqlstate_errors.rst rm -rf html psycopg2.txt
env: requirements.txt
$(PYTHON) -m venv env
./env/bin/pip install -r requirements.txt
echo "$$(pwd)/../build/lib.$(PYTHON_VERSION)" \
> env/lib/python$(PYTHON_VERSION)/site-packages/psycopg.pth

42
doc/README Normal file
View File

@ -0,0 +1,42 @@
How to build psycopg documentation
----------------------------------
- Install Sphinx, maybe in a virtualenv. Tested with Sphinx 0.6.4::
~$ virtualenv pd
New python executable in pd/bin/python
Installing setuptools............done.
~$ cd pd
~/pd$ source bin/activate
(pd)~/pd$
- Install Sphinx in the env::
(pd)~/pd$ easy_install sphinx
Searching for sphinx
Reading http://pypi.python.org/simple/sphinx/
Reading http://sphinx.pocoo.org/
Best match: Sphinx 0.6.4
...
Finished processing dependencies for sphinx
- Build psycopg2 and ensure the package can be imported (it will be used for
reading the version number, autodocs etc.)::
(pd)~/pd/psycopg2$ python setup.py build
(pd)~/pd/psycopg2$ python setup.py install
running install
...
creating ~/pd/lib/python2.6/site-packages/psycopg2
...
- Move to the ``doc`` dir and run ``make`` from there::
(pd)~/pd/psycopg2$ cd doc/
(pd)~/pd/psycopg2/doc$ make
Running Sphinx v0.6.4
...
You should have the rendered documentation in ``./html`` and the text file
``psycopg2.txt`` now.

View File

@ -1,20 +0,0 @@
How to build psycopg documentation
----------------------------------
Building the documentation usually requires building the library too for
introspection, so you will need the same prerequisites_. The only extra
prerequisite is virtualenv_: the packages needed to build the docs will be
installed when building the env.
.. _prerequisites: https://www.psycopg.org/docs/install.html#install-from-source
.. _virtualenv: https://virtualenv.pypa.io/en/latest/
Build the env once with::
make env
Then you can build the documentation with::
make
You should find the rendered documentation in the ``html`` directory.

View File

@ -1,10 +1,10 @@
From: Jack Moffitt <jack@xiph.org> From: Jack Moffitt <jack@xiph.org>
To: Psycopg Mailing List <psycopg@lists.initd.org> To: Psycopg Mailing List <psycopg@lists.initd.org>
Subject: Re: [Psycopg] preparing for 1.0 Subject: Re: [Psycopg] preparing for 1.0
Date: 22 Oct 2001 11:16:21 -0600 Date: 22 Oct 2001 11:16:21 -0600
www.vorbis.com is serving from 5-10k pages per day with psycopg serving www.vorbis.com is serving from 5-10k pages per day with psycopg serving
data for most of that. data for most of that.
I plan to use it for several of our other sites, so that number will I plan to use it for several of our other sites, so that number will
increase. increase.
@ -19,11 +19,11 @@ jack.
From: Yury Don <gercon@vpcit.ru> From: Yury Don <gercon@vpcit.ru>
To: Psycopg Mailing List <psycopg@lists.initd.org> To: Psycopg Mailing List <psycopg@lists.initd.org>
Subject: Re: [Psycopg] preparing for 1.0 Subject: Re: [Psycopg] preparing for 1.0
Date: 23 Oct 2001 09:53:11 +0600 Date: 23 Oct 2001 09:53:11 +0600
We use psycopg and psycopg zope adapter since fisrt public We use psycopg and psycopg zope adapter since fisrt public
release (it seems version 0.4). Now it works on 3 our sites and in intranet release (it seems version 0.4). Now it works on 3 our sites and in intranet
applications. We had few problems, but all problems were quickly applications. We had few problems, but all problems were quckly
solved. The strong side of psycopg is that it's code is well organized solved. The strong side of psycopg is that it's code is well organized
and easy to understand. When I found a problem with non-ISO datestyle in first and easy to understand. When I found a problem with non-ISO datestyle in first
version of psycopg, it took for me 15 or 20 minutes to learn code and version of psycopg, it took for me 15 or 20 minutes to learn code and
@ -32,7 +32,7 @@ to solve the problem, even thouth my knowledge of c were poor.
BTW, segfault with dictfetchall on particular data set (see [Psycopg] BTW, segfault with dictfetchall on particular data set (see [Psycopg]
dictfetchXXX() problems) disappeared in 0.99.8pre2. dictfetchXXX() problems) disappeared in 0.99.8pre2.
-- --
Best regards, Best regards,
Yury Don Yury Don
@ -42,7 +42,7 @@ To: Federico Di Gregorio <fog@debian.org>
Cc: Psycopg Mailing List <psycopg@lists.initd.org> Cc: Psycopg Mailing List <psycopg@lists.initd.org>
Subject: Re: [Psycopg] preparing for 1.0 Subject: Re: [Psycopg] preparing for 1.0
Date: 23 Oct 2001 08:25:52 -0400 Date: 23 Oct 2001 08:25:52 -0400
The US Govt Department of Labor's Office of Disability Employment The US Govt Department of Labor's Office of Disability Employment
Policy's DisabilityDirect website is run on zope and zpsycopg. Policy's DisabilityDirect website is run on zope and zpsycopg.
@ -50,7 +50,7 @@ Policy's DisabilityDirect website is run on zope and zpsycopg.
From: Scott Leerssen <sleerssen@racemi.com> From: Scott Leerssen <sleerssen@racemi.com>
To: Federico Di Gregorio <fog@debian.org> To: Federico Di Gregorio <fog@debian.org>
Subject: Re: [Psycopg] preparing for 1.0 Subject: Re: [Psycopg] preparing for 1.0
Date: 23 Oct 2001 09:56:10 -0400 Date: 23 Oct 2001 09:56:10 -0400
Racemi's load management software infrastructure uses psycopg to handle Racemi's load management software infrastructure uses psycopg to handle
complex server allocation decisions, plus storage and access of complex server allocation decisions, plus storage and access of
@ -66,10 +66,10 @@ From: Andre Schubert <andre.schubert@geyer.kabeljournal.de>
To: Federico Di Gregorio <fog@debian.org> To: Federico Di Gregorio <fog@debian.org>
Cc: Psycopg Mailing List <psycopg@lists.initd.org> Cc: Psycopg Mailing List <psycopg@lists.initd.org>
Subject: Re: [Psycopg] preparing for 1.0 Subject: Re: [Psycopg] preparing for 1.0
Date: 23 Oct 2001 11:46:07 +0200 Date: 23 Oct 2001 11:46:07 +0200
i have changed the psycopg version to 0.99.8pre2 on all devel-machines i have changed the psycopg version to 0.99.8pre2 on all devel-machines
and all segfaults are gone. after my holiday i wil change to 0.99.8pre2 and all segfaults are gone. after my holiday i wil change to 0.99.8pre2
or 1.0 on our production-server. or 1.0 on our production-server.
this server contains several web-sites which are all connected to this server contains several web-sites which are all connected to
postgres over ZPsycopgDA. postgres over ZPsycopgDA.
@ -81,7 +81,7 @@ From: Fred Wilson Horch <fhorch@ecoaccess.org>
To: <psycopg@lists.initd.org> To: <psycopg@lists.initd.org>
Subject: [Psycopg] Success story for psycopg Subject: [Psycopg] Success story for psycopg
Date: 23 Oct 2001 10:59:17 -0400 Date: 23 Oct 2001 10:59:17 -0400
Due to various quirks of PyGreSQL and PoPy, EcoAccess has been looking for Due to various quirks of PyGreSQL and PoPy, EcoAccess has been looking for
a reliable, fast and relatively bug-free Python-PostgreSQL interface for a reliable, fast and relatively bug-free Python-PostgreSQL interface for
our project. our project.
@ -98,7 +98,7 @@ reports and feature requests, and we're looking forward to using psycopg
as the Python interface for additional database-backed web applications. as the Python interface for additional database-backed web applications.
Keep up the good work! Keep up the good work!
-- --
Fred Wilson Horch mailto:fhorch@ecoaccess.org Fred Wilson Horch mailto:fhorch@ecoaccess.org
Executive Director, EcoAccess http://ecoaccess.org/ Executive Director, EcoAccess http://ecoaccess.org/

View File

@ -9,15 +9,15 @@ Replaces: 248
Release-Date: 07 Apr 1999 Release-Date: 07 Apr 1999
Introduction Introduction
This API has been defined to encourage similarity between the This API has been defined to encourage similarity between the
Python modules that are used to access databases. By doing this, Python modules that are used to access databases. By doing this,
we hope to achieve a consistency leading to more easily understood we hope to achieve a consistency leading to more easily understood
modules, code that is generally more portable across databases, modules, code that is generally more portable across databases,
and a broader reach of database connectivity from Python. and a broader reach of database connectivity from Python.
The interface specification consists of several sections: The interface specification consists of several sections:
* Module Interface * Module Interface
* Connection Objects * Connection Objects
* Cursor Objects * Cursor Objects
@ -25,7 +25,7 @@ Introduction
* Type Objects and Constructors * Type Objects and Constructors
* Implementation Hints * Implementation Hints
* Major Changes from 1.0 to 2.0 * Major Changes from 1.0 to 2.0
Comments and questions about this specification may be directed Comments and questions about this specification may be directed
to the SIG for Database Interfacing with Python to the SIG for Database Interfacing with Python
(db-sig@python.org). (db-sig@python.org).
@ -41,7 +41,7 @@ Introduction
basis for new interfaces. basis for new interfaces.
Module Interface Module Interface
Access to the database is made available through connection Access to the database is made available through connection
objects. The module must provide the following constructor for objects. The module must provide the following constructor for
these: these:
@ -51,17 +51,17 @@ Module Interface
Constructor for creating a connection to the database. Constructor for creating a connection to the database.
Returns a Connection Object. It takes a number of Returns a Connection Object. It takes a number of
parameters which are database dependent. [1] parameters which are database dependent. [1]
These module globals must be defined: These module globals must be defined:
apilevel apilevel
String constant stating the supported DB API level. String constant stating the supported DB API level.
Currently only the strings '1.0' and '2.0' are allowed. Currently only the strings '1.0' and '2.0' are allowed.
If not given, a DB-API 1.0 level interface should be If not given, a DB-API 1.0 level interface should be
assumed. assumed.
threadsafety threadsafety
Integer constant stating the level of thread safety the Integer constant stating the level of thread safety the
@ -81,33 +81,33 @@ Module Interface
or other external sources that are beyond your control. or other external sources that are beyond your control.
paramstyle paramstyle
String constant stating the type of parameter marker String constant stating the type of parameter marker
formatting expected by the interface. Possible values are formatting expected by the interface. Possible values are
[2]: [2]:
'qmark' Question mark style, 'qmark' Question mark style,
e.g. '...WHERE name=?' e.g. '...WHERE name=?'
'numeric' Numeric, positional style, 'numeric' Numeric, positional style,
e.g. '...WHERE name=:1' e.g. '...WHERE name=:1'
'named' Named style, 'named' Named style,
e.g. '...WHERE name=:name' e.g. '...WHERE name=:name'
'format' ANSI C printf format codes, 'format' ANSI C printf format codes,
e.g. '...WHERE name=%s' e.g. '...WHERE name=%s'
'pyformat' Python extended format codes, 'pyformat' Python extended format codes,
e.g. '...WHERE name=%(name)s' e.g. '...WHERE name=%(name)s'
The module should make all error information available through The module should make all error information available through
these exceptions or subclasses thereof: these exceptions or subclasses thereof:
Warning Warning
Exception raised for important warnings like data Exception raised for important warnings like data
truncations while inserting, etc. It must be a subclass of truncations while inserting, etc. It must be a subclass of
the Python StandardError (defined in the module the Python StandardError (defined in the module
exceptions). exceptions).
Error Error
Exception that is the base class of all other error Exception that is the base class of all other error
exceptions. You can use this to catch all errors with one exceptions. You can use this to catch all errors with one
@ -115,7 +115,7 @@ Module Interface
errors and thus should not use this class as base. It must errors and thus should not use this class as base. It must
be a subclass of the Python StandardError (defined in the be a subclass of the Python StandardError (defined in the
module exceptions). module exceptions).
InterfaceError InterfaceError
Exception raised for errors that are related to the Exception raised for errors that are related to the
@ -126,50 +126,50 @@ Module Interface
Exception raised for errors that are related to the Exception raised for errors that are related to the
database. It must be a subclass of Error. database. It must be a subclass of Error.
DataError DataError
Exception raised for errors that are due to problems with Exception raised for errors that are due to problems with
the processed data like division by zero, numeric value the processed data like division by zero, numeric value
out of range, etc. It must be a subclass of DatabaseError. out of range, etc. It must be a subclass of DatabaseError.
OperationalError OperationalError
Exception raised for errors that are related to the Exception raised for errors that are related to the
database's operation and not necessarily under the control database's operation and not necessarily under the control
of the programmer, e.g. an unexpected disconnect occurs, of the programmer, e.g. an unexpected disconnect occurs,
the data source name is not found, a transaction could not the data source name is not found, a transaction could not
be processed, a memory allocation error occurred during be processed, a memory allocation error occurred during
processing, etc. It must be a subclass of DatabaseError. processing, etc. It must be a subclass of DatabaseError.
IntegrityError IntegrityError
Exception raised when the relational integrity of the Exception raised when the relational integrity of the
database is affected, e.g. a foreign key check fails. It database is affected, e.g. a foreign key check fails. It
must be a subclass of DatabaseError. must be a subclass of DatabaseError.
InternalError InternalError
Exception raised when the database encounters an internal Exception raised when the database encounters an internal
error, e.g. the cursor is not valid anymore, the error, e.g. the cursor is not valid anymore, the
transaction is out of sync, etc. It must be a subclass of transaction is out of sync, etc. It must be a subclass of
DatabaseError. DatabaseError.
ProgrammingError ProgrammingError
Exception raised for programming errors, e.g. table not Exception raised for programming errors, e.g. table not
found or already exists, syntax error in the SQL found or already exists, syntax error in the SQL
statement, wrong number of parameters specified, etc. It statement, wrong number of parameters specified, etc. It
must be a subclass of DatabaseError. must be a subclass of DatabaseError.
NotSupportedError NotSupportedError
Exception raised in case a method or database API was used Exception raised in case a method or database API was used
which is not supported by the database, e.g. requesting a which is not supported by the database, e.g. requesting a
.rollback() on a connection that does not support .rollback() on a connection that does not support
transaction or has transactions turned off. It must be a transaction or has transactions turned off. It must be a
subclass of DatabaseError. subclass of DatabaseError.
This is the exception inheritance layout: This is the exception inheritance layout:
StandardError StandardError
@ -183,17 +183,17 @@ Module Interface
|__InternalError |__InternalError
|__ProgrammingError |__ProgrammingError
|__NotSupportedError |__NotSupportedError
Note: The values of these exceptions are not defined. They should Note: The values of these exceptions are not defined. They should
give the user a fairly good idea of what went wrong, though. give the user a fairly good idea of what went wrong, though.
Connection Objects Connection Objects
Connection Objects should respond to the following methods: Connection Objects should respond to the following methods:
.close() .close()
Close the connection now (rather than whenever __del__ is Close the connection now (rather than whenever __del__ is
called). The connection will be unusable from this point called). The connection will be unusable from this point
forward; an Error (or subclass) exception will be raised forward; an Error (or subclass) exception will be raised
@ -203,74 +203,74 @@ Connection Objects
committing the changes first will cause an implicit committing the changes first will cause an implicit
rollback to be performed. rollback to be performed.
.commit() .commit()
Commit any pending transaction to the database. Note that Commit any pending transaction to the database. Note that
if the database supports an auto-commit feature, this must if the database supports an auto-commit feature, this must
be initially off. An interface method may be provided to be initially off. An interface method may be provided to
turn it back on. turn it back on.
Database modules that do not support transactions should Database modules that do not support transactions should
implement this method with void functionality. implement this method with void functionality.
.rollback() .rollback()
This method is optional since not all databases provide This method is optional since not all databases provide
transaction support. [3] transaction support. [3]
In case a database does provide transactions this method In case a database does provide transactions this method
causes the the database to roll back to the start of any causes the the database to roll back to the start of any
pending transaction. Closing a connection without pending transaction. Closing a connection without
committing the changes first will cause an implicit committing the changes first will cause an implicit
rollback to be performed. rollback to be performed.
.cursor() .cursor()
Return a new Cursor Object using the connection. If the Return a new Cursor Object using the connection. If the
database does not provide a direct cursor concept, the database does not provide a direct cursor concept, the
module will have to emulate cursors using other means to module will have to emulate cursors using other means to
the extent needed by this specification. [4] the extent needed by this specification. [4]
Cursor Objects Cursor Objects
These objects represent a database cursor, which is used to These objects represent a database cursor, which is used to
manage the context of a fetch operation. Cursors created from manage the context of a fetch operation. Cursors created from
the same connection are not isolated, i.e., any changes the same connection are not isolated, i.e., any changes
done to the database by a cursor are immediately visible by the done to the database by a cursor are immediately visible by the
other cursors. Cursors created from different connections can other cursors. Cursors created from different connections can
or can not be isolated, depending on how the transaction support or can not be isolated, depending on how the transaction support
is implemented (see also the connection's rollback() and commit() is implemented (see also the connection's rollback() and commit()
methods.) methods.)
Cursor Objects should respond to the following methods and Cursor Objects should respond to the following methods and
attributes: attributes:
.description .description
This read-only attribute is a sequence of 7-item This read-only attribute is a sequence of 7-item
sequences. Each of these sequences contains information sequences. Each of these sequences contains information
describing one result column: (name, type_code, describing one result column: (name, type_code,
display_size, internal_size, precision, scale, display_size, internal_size, precision, scale,
null_ok). The first two items (name and type_code) are null_ok). The first two items (name and type_code) are
mandatory, the other five are optional and must be set to mandatory, the other five are optional and must be set to
None if meaningful values are not provided. None if meaningfull values are not provided.
This attribute will be None for operations that This attribute will be None for operations that
do not return rows or if the cursor has not had an do not return rows or if the cursor has not had an
operation invoked via the executeXXX() method yet. operation invoked via the executeXXX() method yet.
The type_code can be interpreted by comparing it to the The type_code can be interpreted by comparing it to the
Type Objects specified in the section below. Type Objects specified in the section below.
.rowcount .rowcount
This read-only attribute specifies the number of rows that This read-only attribute specifies the number of rows that
the last executeXXX() produced (for DQL statements like the last executeXXX() produced (for DQL statements like
'select') or affected (for DML statements like 'update' or 'select') or affected (for DML statements like 'update' or
'insert'). 'insert').
The attribute is -1 in case no executeXXX() has been The attribute is -1 in case no executeXXX() has been
performed on the cursor or the rowcount of the last performed on the cursor or the rowcount of the last
operation is not determinable by the interface. [7] operation is not determinable by the interface. [7]
@ -278,96 +278,96 @@ Cursor Objects
Note: Future versions of the DB API specification could Note: Future versions of the DB API specification could
redefine the latter case to have the object return None redefine the latter case to have the object return None
instead of -1. instead of -1.
.callproc(procname[,parameters]) .callproc(procname[,parameters])
(This method is optional since not all databases provide (This method is optional since not all databases provide
stored procedures. [3]) stored procedures. [3])
Call a stored database procedure with the given name. The Call a stored database procedure with the given name. The
sequence of parameters must contain one entry for each sequence of parameters must contain one entry for each
argument that the procedure expects. The result of the argument that the procedure expects. The result of the
call is returned as modified copy of the input call is returned as modified copy of the input
sequence. Input parameters are left untouched, output and sequence. Input parameters are left untouched, output and
input/output parameters replaced with possibly new values. input/output parameters replaced with possibly new values.
The procedure may also provide a result set as The procedure may also provide a result set as
output. This must then be made available through the output. This must then be made available through the
standard fetchXXX() methods. standard fetchXXX() methods.
.close() .close()
Close the cursor now (rather than whenever __del__ is Close the cursor now (rather than whenever __del__ is
called). The cursor will be unusable from this point called). The cursor will be unusable from this point
forward; an Error (or subclass) exception will be raised forward; an Error (or subclass) exception will be raised
if any operation is attempted with the cursor. if any operation is attempted with the cursor.
.execute(operation[,parameters]) .execute(operation[,parameters])
Prepare and execute a database operation (query or Prepare and execute a database operation (query or
command). Parameters may be provided as sequence or command). Parameters may be provided as sequence or
mapping and will be bound to variables in the operation. mapping and will be bound to variables in the operation.
Variables are specified in a database-specific notation Variables are specified in a database-specific notation
(see the module's paramstyle attribute for details). [5] (see the module's paramstyle attribute for details). [5]
A reference to the operation will be retained by the A reference to the operation will be retained by the
cursor. If the same operation object is passed in again, cursor. If the same operation object is passed in again,
then the cursor can optimize its behavior. This is most then the cursor can optimize its behavior. This is most
effective for algorithms where the same operation is used, effective for algorithms where the same operation is used,
but different parameters are bound to it (many times). but different parameters are bound to it (many times).
For maximum efficiency when reusing an operation, it is For maximum efficiency when reusing an operation, it is
best to use the setinputsizes() method to specify the best to use the setinputsizes() method to specify the
parameter types and sizes ahead of time. It is legal for parameter types and sizes ahead of time. It is legal for
a parameter to not match the predefined information; the a parameter to not match the predefined information; the
implementation should compensate, possibly with a loss of implementation should compensate, possibly with a loss of
efficiency. efficiency.
The parameters may also be specified as list of tuples to The parameters may also be specified as list of tuples to
e.g. insert multiple rows in a single operation, but this e.g. insert multiple rows in a single operation, but this
kind of usage is depreciated: executemany() should be used kind of usage is depreciated: executemany() should be used
instead. instead.
Return values are not defined. Return values are not defined.
.executemany(operation,seq_of_parameters) .executemany(operation,seq_of_parameters)
Prepare a database operation (query or command) and then Prepare a database operation (query or command) and then
execute it against all parameter sequences or mappings execute it against all parameter sequences or mappings
found in the sequence seq_of_parameters. found in the sequence seq_of_parameters.
Modules are free to implement this method using multiple Modules are free to implement this method using multiple
calls to the execute() method or by using array operations calls to the execute() method or by using array operations
to have the database process the sequence as a whole in to have the database process the sequence as a whole in
one call. one call.
Use of this method for an operation which produces one or Use of this method for an operation which produces one or
more result sets constitutes undefined behavior, and the more result sets constitutes undefined behavior, and the
implementation is permitted (but not required) to raise implementation is permitted (but not required) to raise
an exception when it detects that a result set has been an exception when it detects that a result set has been
created by an invocation of the operation. created by an invocation of the operation.
The same comments as for execute() also apply accordingly The same comments as for execute() also apply accordingly
to this method. to this method.
Return values are not defined. Return values are not defined.
.fetchone() .fetchone()
Fetch the next row of a query result set, returning a Fetch the next row of a query result set, returning a
single sequence, or None when no more data is single sequence, or None when no more data is
available. [6] available. [6]
An Error (or subclass) exception is raised if the previous An Error (or subclass) exception is raised if the previous
call to executeXXX() did not produce any result set or no call to executeXXX() did not produce any result set or no
call was issued yet. call was issued yet.
fetchmany([size=cursor.arraysize]) fetchmany([size=cursor.arraysize])
Fetch the next set of rows of a query result, returning a Fetch the next set of rows of a query result, returning a
sequence of sequences (e.g. a list of tuples). An empty sequence of sequences (e.g. a list of tuples). An empty
sequence is returned when no more rows are available. sequence is returned when no more rows are available.
The number of rows to fetch per call is specified by the The number of rows to fetch per call is specified by the
parameter. If it is not given, the cursor's arraysize parameter. If it is not given, the cursor's arraysize
determines the number of rows to be fetched. The method determines the number of rows to be fetched. The method
@ -375,62 +375,62 @@ Cursor Objects
parameter. If this is not possible due to the specified parameter. If this is not possible due to the specified
number of rows not being available, fewer rows may be number of rows not being available, fewer rows may be
returned. returned.
An Error (or subclass) exception is raised if the previous An Error (or subclass) exception is raised if the previous
call to executeXXX() did not produce any result set or no call to executeXXX() did not produce any result set or no
call was issued yet. call was issued yet.
Note there are performance considerations involved with Note there are performance considerations involved with
the size parameter. For optimal performance, it is the size parameter. For optimal performance, it is
usually best to use the arraysize attribute. If the size usually best to use the arraysize attribute. If the size
parameter is used, then it is best for it to retain the parameter is used, then it is best for it to retain the
same value from one fetchmany() call to the next. same value from one fetchmany() call to the next.
.fetchall() .fetchall()
Fetch all (remaining) rows of a query result, returning Fetch all (remaining) rows of a query result, returning
them as a sequence of sequences (e.g. a list of tuples). them as a sequence of sequences (e.g. a list of tuples).
Note that the cursor's arraysize attribute can affect the Note that the cursor's arraysize attribute can affect the
performance of this operation. performance of this operation.
An Error (or subclass) exception is raised if the previous An Error (or subclass) exception is raised if the previous
call to executeXXX() did not produce any result set or no call to executeXXX() did not produce any result set or no
call was issued yet. call was issued yet.
.nextset() .nextset()
(This method is optional since not all databases support (This method is optional since not all databases support
multiple result sets. [3]) multiple result sets. [3])
This method will make the cursor skip to the next This method will make the cursor skip to the next
available set, discarding any remaining rows from the available set, discarding any remaining rows from the
current set. current set.
If there are no more sets, the method returns If there are no more sets, the method returns
None. Otherwise, it returns a true value and subsequent None. Otherwise, it returns a true value and subsequent
calls to the fetch methods will return rows from the next calls to the fetch methods will return rows from the next
result set. result set.
An Error (or subclass) exception is raised if the previous An Error (or subclass) exception is raised if the previous
call to executeXXX() did not produce any result set or no call to executeXXX() did not produce any result set or no
call was issued yet. call was issued yet.
.arraysize .arraysize
This read/write attribute specifies the number of rows to This read/write attribute specifies the number of rows to
fetch at a time with fetchmany(). It defaults to 1 meaning fetch at a time with fetchmany(). It defaults to 1 meaning
to fetch a single row at a time. to fetch a single row at a time.
Implementations must observe this value with respect to Implementations must observe this value with respect to
the fetchmany() method, but are free to interact with the the fetchmany() method, but are free to interact with the
database a single row at a time. It may also be used in database a single row at a time. It may also be used in
the implementation of executemany(). the implementation of executemany().
.setinputsizes(sizes) .setinputsizes(sizes)
This can be used before a call to executeXXX() to This can be used before a call to executeXXX() to
predefine memory areas for the operation's parameters. predefine memory areas for the operation's parameters.
sizes is specified as a sequence -- one item for each sizes is specified as a sequence -- one item for each
input parameter. The item should be a Type Object that input parameter. The item should be a Type Object that
corresponds to the input that will be used, or it should corresponds to the input that will be used, or it should
@ -438,27 +438,27 @@ Cursor Objects
parameter. If the item is None, then no predefined memory parameter. If the item is None, then no predefined memory
area will be reserved for that column (this is useful to area will be reserved for that column (this is useful to
avoid predefined areas for large inputs). avoid predefined areas for large inputs).
This method would be used before the executeXXX() method This method would be used before the executeXXX() method
is invoked. is invoked.
Implementations are free to have this method do nothing Implementations are free to have this method do nothing
and users are free to not use it. and users are free to not use it.
.setoutputsize(size[,column]) .setoutputsize(size[,column])
Set a column buffer size for fetches of large columns Set a column buffer size for fetches of large columns
(e.g. LONGs, BLOBs, etc.). The column is specified as an (e.g. LONGs, BLOBs, etc.). The column is specified as an
index into the result sequence. Not specifying the column index into the result sequence. Not specifying the column
will set the default size for all large columns in the will set the default size for all large columns in the
cursor. cursor.
This method would be used before the executeXXX() method This method would be used before the executeXXX() method
is invoked. is invoked.
Implementations are free to have this method do nothing Implementations are free to have this method do nothing
and users are free to not use it. and users are free to not use it.
Type Objects and Constructors Type Objects and Constructors
@ -485,15 +485,15 @@ Type Objects and Constructors
Implementation Hints below for details). Implementation Hints below for details).
The module exports the following constructors and singletons: The module exports the following constructors and singletons:
Date(year,month,day) Date(year,month,day)
This function constructs an object holding a date value. This function constructs an object holding a date value.
Time(hour,minute,second) Time(hour,minute,second)
This function constructs an object holding a time value. This function constructs an object holding a time value.
Timestamp(year,month,day,hour,minute,second) Timestamp(year,month,day,hour,minute,second)
This function constructs an object holding a time stamp This function constructs an object holding a time stamp
@ -507,12 +507,12 @@ Type Objects and Constructors
module for details). module for details).
TimeFromTicks(ticks) TimeFromTicks(ticks)
This function constructs an object holding a time value This function constructs an object holding a time value
from the given ticks value (number of seconds since the from the given ticks value (number of seconds since the
epoch; see the documentation of the standard Python time epoch; see the documentation of the standard Python time
module for details). module for details).
TimestampFromTicks(ticks) TimestampFromTicks(ticks)
This function constructs an object holding a time stamp This function constructs an object holding a time stamp
@ -521,10 +521,10 @@ Type Objects and Constructors
time module for details). time module for details).
Binary(string) Binary(string)
This function constructs an object capable of holding a This function constructs an object capable of holding a
binary (long) string value. binary (long) string value.
STRING STRING
@ -535,22 +535,22 @@ Type Objects and Constructors
This type object is used to describe (long) binary columns This type object is used to describe (long) binary columns
in a database (e.g. LONG, RAW, BLOBs). in a database (e.g. LONG, RAW, BLOBs).
NUMBER NUMBER
This type object is used to describe numeric columns in a This type object is used to describe numeric columns in a
database. database.
DATETIME DATETIME
This type object is used to describe date/time columns in This type object is used to describe date/time columns in
a database. a database.
ROWID ROWID
This type object is used to describe the "Row ID" column This type object is used to describe the "Row ID" column
in a database. in a database.
SQL NULL values are represented by the Python None singleton on SQL NULL values are represented by the Python None singleton on
input and output. input and output.
@ -563,7 +563,7 @@ Implementation Hints for Module Authors
* The preferred object types for the date/time objects are those * The preferred object types for the date/time objects are those
defined in the mxDateTime package. It provides all necessary defined in the mxDateTime package. It provides all necessary
constructors and methods both at Python and C level. constructors and methods both at Python and C level.
* The preferred object type for Binary objects are the * The preferred object type for Binary objects are the
buffer types available in standard Python starting with buffer types available in standard Python starting with
version 1.5.2. Please see the Python documentation for version 1.5.2. Please see the Python documentation for
@ -577,7 +577,7 @@ Implementation Hints for Module Authors
processing. However, it should be noted that this does not processing. However, it should be noted that this does not
expose a C API like mxDateTime does which means that integration expose a C API like mxDateTime does which means that integration
with C based database modules is more difficult. with C based database modules is more difficult.
* Here is a sample implementation of the Unix ticks based * Here is a sample implementation of the Unix ticks based
constructors for date/time delegating work to the generic constructors for date/time delegating work to the generic
constructors: constructors:
@ -645,7 +645,7 @@ Implementation Hints for Module Authors
class NotSupportedError(DatabaseError): class NotSupportedError(DatabaseError):
pass pass
In C you can use the PyErr_NewException(fullname, In C you can use the PyErr_NewException(fullname,
base, NULL) API to create the exception objects. base, NULL) API to create the exception objects.
@ -760,7 +760,7 @@ Optional DB API Extensions
Warning Message: "DB-API extension connection.messages used" Warning Message: "DB-API extension connection.messages used"
Cursor Method .next() Cursor Method .next()
Return the next row from the currently executing SQL statement Return the next row from the currently executing SQL statement
using the same semantics as .fetchone(). A StopIteration using the same semantics as .fetchone(). A StopIteration
exception is raised when the result set is exhausted for Python exception is raised when the result set is exhausted for Python
@ -790,13 +790,13 @@ Optional DB API Extensions
Warning Message: "DB-API extension cursor.lastrowid used" Warning Message: "DB-API extension cursor.lastrowid used"
Optional Error Handling Extension Optional Error Handling Extension
The core DB API specification only introduces a set of exceptions The core DB API specification only introduces a set of exceptions
which can be raised to report errors to the user. In some cases, which can be raised to report errors to the user. In some cases,
exceptions may be too disruptive for the flow of a program or even exceptions may be too disruptive for the flow of a program or even
render execution impossible. render execution impossible.
For these cases and in order to simplify error handling when For these cases and in order to simplify error handling when
dealing with databases, database module authors may choose to dealing with databases, database module authors may choose to
@ -806,7 +806,7 @@ Optional Error Handling Extension
Cursor/Connection Attribute .errorhandler Cursor/Connection Attribute .errorhandler
Read/write attribute which references an error handler to call Read/write attribute which references an error handler to call
in case an error condition is met. in case an error condition is met.
The handler must be a Python callable taking the following The handler must be a Python callable taking the following
arguments: errorhandler(connection, cursor, errorclass, arguments: errorhandler(connection, cursor, errorclass,
@ -836,7 +836,7 @@ Frequently Asked Questions
specification. This section covers some of the issues people specification. This section covers some of the issues people
sometimes have with the specification. sometimes have with the specification.
Question: Question:
How can I construct a dictionary out of the tuples returned by How can I construct a dictionary out of the tuples returned by
.fetchxxx(): .fetchxxx():
@ -855,7 +855,7 @@ Frequently Asked Questions
* Some databases don't support case-sensitive column names or * Some databases don't support case-sensitive column names or
auto-convert them to all lowercase or all uppercase auto-convert them to all lowercase or all uppercase
characters. characters.
* Columns in the result set which are generated by the query * Columns in the result set which are generated by the query
(e.g. using SQL functions) don't map to table column names (e.g. using SQL functions) don't map to table column names
and databases usually generate names for these columns in a and databases usually generate names for these columns in a
@ -872,9 +872,9 @@ Major Changes from Version 1.0 to Version 2.0
compared to the 1.0 version. Because some of these changes will compared to the 1.0 version. Because some of these changes will
cause existing DB API 1.0 based scripts to break, the major cause existing DB API 1.0 based scripts to break, the major
version number was adjusted to reflect this change. version number was adjusted to reflect this change.
These are the most important changes from 1.0 to 2.0: These are the most important changes from 1.0 to 2.0:
* The need for a separate dbi module was dropped and the * The need for a separate dbi module was dropped and the
functionality merged into the module interface itself. functionality merged into the module interface itself.
@ -886,10 +886,10 @@ Major Changes from Version 1.0 to Version 2.0
* New constants (apilevel, threadlevel, paramstyle) and * New constants (apilevel, threadlevel, paramstyle) and
methods (executemany, nextset) were added to provide better methods (executemany, nextset) were added to provide better
database bindings. database bindings.
* The semantics of .callproc() needed to call stored * The semantics of .callproc() needed to call stored
procedures are now clearly defined. procedures are now clearly defined.
* The definition of the .execute() return value changed. * The definition of the .execute() return value changed.
Previously, the return value was based on the SQL statement Previously, the return value was based on the SQL statement
type (which was hard to implement right) -- it is undefined type (which was hard to implement right) -- it is undefined
@ -898,7 +898,7 @@ Major Changes from Version 1.0 to Version 2.0
values, but these are no longer mandated by the values, but these are no longer mandated by the
specification and should be considered database interface specification and should be considered database interface
dependent. dependent.
* Class based exceptions were incorporated into the * Class based exceptions were incorporated into the
specification. Module implementors are free to extend the specification. Module implementors are free to extend the
exception layout defined in this specification by exception layout defined in this specification by
@ -916,10 +916,10 @@ Open Issues
questions that were left open in the 1.0 version, there are still questions that were left open in the 1.0 version, there are still
some remaining issues which should be addressed in future some remaining issues which should be addressed in future
versions: versions:
* Define a useful return value for .nextset() for the case where * Define a useful return value for .nextset() for the case where
a new result set is available. a new result set is available.
* Create a fixed point numeric type for use as loss-less * Create a fixed point numeric type for use as loss-less
monetary and decimal interchange format. monetary and decimal interchange format.
@ -929,17 +929,17 @@ Footnotes
[1] As a guideline the connection constructor parameters should be [1] As a guideline the connection constructor parameters should be
implemented as keyword parameters for more intuitive use and implemented as keyword parameters for more intuitive use and
follow this order of parameters: follow this order of parameters:
dsn Data source name as string dsn Data source name as string
user User name as string (optional) user User name as string (optional)
password Password as string (optional) password Password as string (optional)
host Hostname (optional) host Hostname (optional)
database Database name (optional) database Database name (optional)
E.g. a connect could look like this: E.g. a connect could look like this:
connect(dsn='myhost:MYDB',user='guido',password='234$') connect(dsn='myhost:MYDB',user='guido',password='234$')
[2] Module implementors should prefer 'numeric', 'named' or [2] Module implementors should prefer 'numeric', 'named' or
'pyformat' over the other formats because these offer more 'pyformat' over the other formats because these offer more
clarity and flexibility. clarity and flexibility.
@ -947,41 +947,41 @@ Footnotes
[3] If the database does not support the functionality required [3] If the database does not support the functionality required
by the method, the interface should throw an exception in by the method, the interface should throw an exception in
case the method is used. case the method is used.
The preferred approach is to not implement the method and The preferred approach is to not implement the method and
thus have Python generate an AttributeError in thus have Python generate an AttributeError in
case the method is requested. This allows the programmer to case the method is requested. This allows the programmer to
check for database capabilities using the standard check for database capabilities using the standard
hasattr() function. hasattr() function.
For some dynamically configured interfaces it may not be For some dynamically configured interfaces it may not be
appropriate to require dynamically making the method appropriate to require dynamically making the method
available. These interfaces should then raise a available. These interfaces should then raise a
NotSupportedError to indicate the non-ability NotSupportedError to indicate the non-ability
to perform the roll back when the method is invoked. to perform the roll back when the method is invoked.
[4] a database interface may choose to support named cursors by [4] a database interface may choose to support named cursors by
allowing a string argument to the method. This feature is allowing a string argument to the method. This feature is
not part of the specification, since it complicates not part of the specification, since it complicates
semantics of the .fetchXXX() methods. semantics of the .fetchXXX() methods.
[5] The module will use the __getitem__ method of the parameters [5] The module will use the __getitem__ method of the parameters
object to map either positions (integers) or names (strings) object to map either positions (integers) or names (strings)
to parameter values. This allows for both sequences and to parameter values. This allows for both sequences and
mappings to be used as input. mappings to be used as input.
The term "bound" refers to the process of binding an input The term "bound" refers to the process of binding an input
value to a database execution buffer. In practical terms, value to a database execution buffer. In practical terms,
this means that the input value is directly used as a value this means that the input value is directly used as a value
in the operation. The client should not be required to in the operation. The client should not be required to
"escape" the value so that it can be used -- the value "escape" the value so that it can be used -- the value
should be equal to the actual database value. should be equal to the actual database value.
[6] Note that the interface may implement row fetching using [6] Note that the interface may implement row fetching using
arrays and other optimizations. It is not arrays and other optimizations. It is not
guaranteed that a call to this method will only move the guaranteed that a call to this method will only move the
associated cursor forward by one row. associated cursor forward by one row.
[7] The rowcount attribute may be coded in a way that updates [7] The rowcount attribute may be coded in a way that updates
its value dynamically. This can be useful for databases that its value dynamically. This can be useful for databases that
return usable rowcount values only after the first call to return usable rowcount values only after the first call to

View File

@ -1,68 +0,0 @@
How to make a psycopg2 release
==============================
- Edit ``setup.py`` and set a stable version release. Use PEP 440 to choose
version numbers, e.g.
- ``2.7``: a new major release, new features
- ``2.7.1``: a bugfix release
- ``2.7.1.1``: a release to fix packaging problems
- ``2.7.2.dev0``: version held during development, non-public test packages...
- ``2.8b1``: a beta for public tests
In the rest of this document we assume you have exported the version number
into an environment variable, e.g.::
$ export VERSION=2.8.4
- Push psycopg2 to master or to the maint branch. Make sure tests on `GitHub
Actions`__.
.. __: https://github.com/psycopg/psycopg2/actions/workflows/tests.yml
- Create a signed tag with the content of the relevant NEWS bit and push it.
E.g.::
# Tag name will be 2_8_4
$ git tag -a -s ${VERSION//\./_}
Psycopg 2.8.4 released
What's new in psycopg 2.8.4
---------------------------
New features:
- Fixed bug blah (:ticket:`#42`).
...
- Create the packages:
- On GitHub Actions run manually a `package build workflow`__.
.. __: https://github.com/psycopg/psycopg2/actions/workflows/packages.yml
- When the workflows have finished download the packages from the job
artifacts.
- Only for stable packages: upload the signed packages on PyPI::
$ twine upload -s wheelhouse/psycopg2-${VERSION}/*
- Create a release and release notes in the psycopg website, announce to
psycopg and pgsql-announce mailing lists.
- Edit ``setup.py`` changing the version again (e.g. go to ``2.8.5.dev0``).
Releasing test packages
-----------------------
Test packages may be uploaded on the `PyPI testing site`__ using::
$ twine upload -s -r testpypi wheelhouse/psycopg2-${VERSION}/*
assuming `proper configuration`__ of ``~/.pypirc``.
.. __: https://test.pypi.org/project/psycopg2/
.. __: https://wiki.python.org/moin/TestPyPI

View File

@ -1,2 +0,0 @@
Sphinx
sphinx-better-theme

View File

@ -1,50 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile requirements.in
#
alabaster==0.7.13
# via sphinx
babel==2.12.1
# via sphinx
certifi>=2023.7.22
# via requests
charset-normalizer==3.1.0
# via requests
docutils==0.19
# via sphinx
idna==3.4
# via requests
imagesize==1.4.1
# via sphinx
jinja2==3.1.2
# via sphinx
markupsafe==2.1.2
# via jinja2
packaging==23.1
# via sphinx
pygments==2.15.0
# via sphinx
requests==2.31.0
# via sphinx
snowballstemmer==2.2.0
# via sphinx
sphinx==6.1.3
# via -r requirements.in
sphinx-better-theme==0.1.5
# via -r requirements.in
sphinxcontrib-applehelp==1.0.4
# via sphinx
sphinxcontrib-devhelp==1.0.2
# via sphinx
sphinxcontrib-htmlhelp==2.0.1
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.3
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
# via sphinx
urllib3==1.26.17
# via requests

View File

@ -1,3 +1,5 @@
@import url("default.css");
blockquote { blockquote {
font-style: italic; font-style: italic;
} }
@ -12,18 +14,11 @@ div.dbapi-extension {
border: 1px solid #aaf; border: 1px solid #aaf;
} }
code.sql,
tt.sql { tt.sql {
font-size: 1em; font-size: 1em;
background-color: transparent; background-color: transparent;
} }
a > code.sql,
a > tt.sql {
font-weight: normal;
}
a > code.sql:hover,
a > tt.sql:hover { a > tt.sql:hover {
text-decoration: underline; text-decoration: underline;
} }
@ -31,106 +26,3 @@ a > tt.sql:hover {
dl.faq dt { dl.faq dt {
font-weight: bold; font-weight: bold;
} }
table.data-types div.line-block {
margin-bottom: 0;
}
/* better theme customisation */
body {
background-color: #216464;
}
header, .related, .document, footer {
background-color: white;
}
header h1 {
font-size: 150%;
margin-bottom: 0;
padding: 0.5rem 10px 0.5rem 10px;
}
h1, h2, h3 {
font-weight: normal;
}
.body h1, .body h2, .body h3 {
color: #074848;
}
h1 {
font-size: 200%;
}
h2 {
font-size: 160%;
}
h3 {
font-size: 140%;
}
footer#pagefooter {
margin-bottom: 1rem;
font-size: 85%;
color: #444;
}
#rellinks, #breadcrumbs {
padding-right: 10px;
padding-left: 10px;
}
.sphinxsidebar {
padding-left: 10px;
}
.bodywrapper {
padding-right: 10px;
}
div.body h1, div.body h2, div.body h3 {
background-color: #f2f2f2;
border-bottom: 1px solid #d0d0d0;
}
div.body p.rubric {
border-bottom: 1px solid #d0d0d0;
}
body .sphinxsidebar .search {
margin-top: 0;
}
html pre {
background-color: #efc;
border: 1px solid #ac9;
border-left: none;
border-right: none;
}
a, a:visited {
color: #0b6868;
}
th {
background-color: #ede;
}
code.xref, a code {
font-weight: bold;
}
code.descname {
font-weight: bold;
font-size: 120%;
}
@media (max-width: 820px) {
body {
background-color: white;
}
}

View File

@ -1,6 +0,0 @@
{# Add a title over the search box #}
{%- if pagename != "search" %}
<h3>Quick search</h3>
{%- include "!searchbox.html" %}
{%- endif %}

View File

@ -12,7 +12,7 @@ More advanced topics
conn.commit() conn.commit()
def wait(conn): def wait(conn):
while True: while 1:
state = conn.poll() state = conn.poll()
if state == psycopg2.extensions.POLL_OK: if state == psycopg2.extensions.POLL_OK:
break break
@ -27,7 +27,6 @@ More advanced topics
wait(aconn) wait(aconn)
acurs = aconn.cursor() acurs = aconn.cursor()
.. index:: .. index::
double: Subclassing; Cursor double: Subclassing; Cursor
double: Subclassing; Connection double: Subclassing; Connection
@ -46,16 +45,6 @@ but other uses are possible. `cursor` is much more interesting, because
it is the class where query building, execution and result type-casting into it is the class where query building, execution and result type-casting into
Python variables happens. Python variables happens.
The `~psycopg2.extras` module contains several examples of :ref:`connection
and cursor subclasses <cursor-subclasses>`.
.. note::
If you only need a customized cursor class, since Psycopg 2.5 you can use
the `~connection.cursor_factory` parameter of a regular connection instead
of creating a new `!connection` subclass.
.. index:: .. index::
single: Example; Cursor subclass single: Example; Cursor subclass
@ -145,9 +134,7 @@ geometric type:
... self.y = y ... self.y = y
>>> def adapt_point(point): >>> def adapt_point(point):
... x = adapt(point.x).getquoted() ... return AsIs("'(%s, %s)'" % (adapt(point.x), adapt(point.y)))
... y = adapt(point.y).getquoted()
... return AsIs("'(%s, %s)'" % (x, y))
>>> register_adapter(Point, adapt_point) >>> register_adapter(Point, adapt_point)
@ -156,11 +143,11 @@ geometric type:
.. |point| replace:: :sql:`point` .. |point| replace:: :sql:`point`
.. _point: https://www.postgresql.org/docs/current/static/datatype-geometric.html#DATATYPE-GEOMETRIC .. _point: http://www.postgresql.org/docs/9.0/static/datatype-geometric.html#DATATYPE-GEOMETRIC
The above function call results in the SQL command:: The above function call results in the SQL command::
INSERT INTO atable (apoint) VALUES ('(1.23, 4.56)'); INSERT INTO atable (apoint) VALUES ((1.23, 4.56));
@ -188,7 +175,7 @@ representation into the previously defined `!Point` class:
... return Point(float(m.group(1)), float(m.group(2))) ... return Point(float(m.group(1)), float(m.group(2)))
... else: ... else:
... raise InterfaceError("bad point representation: %r" % value) ... raise InterfaceError("bad point representation: %r" % value)
In order to create a mapping from a PostgreSQL type (either standard or In order to create a mapping from a PostgreSQL type (either standard or
user-defined), its OID must be known. It can be retrieved either by the second user-defined), its OID must be known. It can be retrieved either by the second
@ -226,12 +213,9 @@ read:
>>> cur.execute("SELECT '(10.2,20.3)'::point") >>> cur.execute("SELECT '(10.2,20.3)'::point")
>>> point = cur.fetchone()[0] >>> point = cur.fetchone()[0]
>>> print(type(point), point.x, point.y) >>> print type(point), point.x, point.y
<class 'Point'> 10.2 20.3 <class 'Point'> 10.2 20.3
A typecaster created by `!new_type()` can be also used with
`~psycopg2.extensions.new_array_type()` to create a typecaster converting a
PostgreSQL array into a Python list.
.. index:: .. index::
@ -255,13 +239,14 @@ be sent from Python code simply executing a :sql:`NOTIFY` command in an
`~cursor.execute()` call. `~cursor.execute()` call.
Because of the way sessions interact with notifications (see |NOTIFY|_ Because of the way sessions interact with notifications (see |NOTIFY|_
documentation), you should keep the connection in `~connection.autocommit` documentation), you should keep the connection in :ref:`autocommit
mode if you wish to receive or send notifications in a timely manner. <autocommit>` mode if you wish to receive or send notifications in a timely
manner.
.. |LISTEN| replace:: :sql:`LISTEN` .. |LISTEN| replace:: :sql:`LISTEN`
.. _LISTEN: https://www.postgresql.org/docs/current/static/sql-listen.html .. _LISTEN: http://www.postgresql.org/docs/9.0/static/sql-listen.html
.. |NOTIFY| replace:: :sql:`NOTIFY` .. |NOTIFY| replace:: :sql:`NOTIFY`
.. _NOTIFY: https://www.postgresql.org/docs/current/static/sql-notify.html .. _NOTIFY: http://www.postgresql.org/docs/9.0/static/sql-notify.html
Notifications are received after every query execution. If the user is Notifications are received after every query execution. If the user is
interested in receiving notifications but not in performing any query, the interested in receiving notifications but not in performing any query, the
@ -270,7 +255,7 @@ wasting resources.
A simple application could poll the connection from time to time to check if A simple application could poll the connection from time to time to check if
something new has arrived. A better strategy is to use some I/O completion something new has arrived. A better strategy is to use some I/O completion
function such as :py:func:`~select.select` to sleep until awakened by the kernel when there is function such as :py:func:`~select.select` to sleep until awaken from the kernel when there is
some data to read on the connection, thereby using no CPU unless there is some data to read on the connection, thereby using no CPU unless there is
something to read:: something to read::
@ -284,20 +269,18 @@ something to read::
curs = conn.cursor() curs = conn.cursor()
curs.execute("LISTEN test;") curs.execute("LISTEN test;")
print("Waiting for notifications on channel 'test'") print "Waiting for notifications on channel 'test'"
while True: while 1:
if select.select([conn],[],[],5) == ([],[],[]): if select.select([conn],[],[],5) == ([],[],[]):
print("Timeout") print "Timeout"
else: else:
conn.poll() conn.poll()
while conn.notifies: while conn.notifies:
notify = conn.notifies.pop(0) notify = conn.notifies.pop()
print("Got NOTIFY:", notify.pid, notify.channel, notify.payload) print "Got NOTIFY:", notify.pid, notify.channel, notify.payload
Running the script and executing a command such as :sql:`NOTIFY test, 'hello'` Running the script and executing a command such as :sql:`NOTIFY test, 'hello'`
in a separate :program:`psql` shell, the output may look similar to: in a separate :program:`psql` shell, the output may look similar to::
.. code-block:: none
Waiting for notifications on channel 'test' Waiting for notifications on channel 'test'
Timeout Timeout
@ -314,10 +297,6 @@ received from a previous version server will have the
Added `~psycopg2.extensions.Notify` object and handling notification Added `~psycopg2.extensions.Notify` object and handling notification
payload. payload.
.. versionchanged:: 2.7
The `~connection.notifies` attribute is writable: it is possible to
replace it with any object exposing an `!append()` method. An useful
example would be to use a `~collections.deque` object.
.. index:: .. index::
@ -328,7 +307,7 @@ received from a previous version server will have the
Asynchronous support Asynchronous support
-------------------- --------------------
.. versionadded:: 2.2 .. versionadded:: 2.2.0
Psycopg can issue asynchronous queries to a PostgreSQL database. An asynchronous Psycopg can issue asynchronous queries to a PostgreSQL database. An asynchronous
communication style is established passing the parameter *async*\=1 to the communication style is established passing the parameter *async*\=1 to the
@ -347,7 +326,7 @@ together with the Python :py:func:`~select.select` function in order to carry on
asynchronous operations with Psycopg:: asynchronous operations with Psycopg::
def wait(conn): def wait(conn):
while True: while 1:
state = conn.poll() state = conn.poll()
if state == psycopg2.extensions.POLL_OK: if state == psycopg2.extensions.POLL_OK:
break break
@ -370,12 +349,12 @@ returned, the connection can be safely used:
>>> wait(aconn) >>> wait(aconn)
>>> acurs = aconn.cursor() >>> acurs = aconn.cursor()
Note that there are a few other requirements to be met in order to have a Notice that there are a few other requirements to be met in order to have a
completely non-blocking connection attempt: see the libpq documentation for completely non-blocking connection attempt: see the libpq documentation for
|PQconnectStart|_. |PQconnectStart|_.
.. |PQconnectStart| replace:: `!PQconnectStart()` .. |PQconnectStart| replace:: `!PQconnectStart()`
.. _PQconnectStart: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS .. _PQconnectStart: http://www.postgresql.org/docs/9.0/static/libpq-connect.html#LIBPQ-PQCONNECTSTART
The same loop should be also used to perform nonblocking queries: after The same loop should be also used to perform nonblocking queries: after
sending a query via `~cursor.execute()` or `~cursor.callproc()`, call sending a query via `~cursor.execute()` or `~cursor.callproc()`, call
@ -394,14 +373,12 @@ When an asynchronous query is being executed, `connection.isexecuting()` returns
connection. connection.
There are several limitations in using asynchronous connections: the There are several limitations in using asynchronous connections: the
connection is always in `~connection.autocommit` mode and it is not connection is always in :ref:`autocommit <autocommit>` mode and it is not
possible to change it. So a possible to change it using `~connection.set_isolation_level()`. So a
transaction is not implicitly started at the first query and is not possible transaction is not implicitly started at the first query and is not possible
to use methods `~connection.commit()` and `~connection.rollback()`: you can to use methods `~connection.commit()` and `~connection.rollback()`: you can
manually control transactions using `~cursor.execute()` to send database manually control transactions using `~cursor.execute()` to send database
commands such as :sql:`BEGIN`, :sql:`COMMIT` and :sql:`ROLLBACK`. Similarly commands such as :sql:`BEGIN`, :sql:`COMMIT` and :sql:`ROLLBACK`.
`~connection.set_session()` can't be used but it is still possible to invoke the
:sql:`SET` command with the proper :sql:`default_transaction_...` parameter.
With asynchronous connections it is also not possible to use With asynchronous connections it is also not possible to use
`~connection.set_client_encoding()`, `~cursor.executemany()`, :ref:`large `~connection.set_client_encoding()`, `~cursor.executemany()`, :ref:`large
@ -422,13 +399,13 @@ this will be probably implemented in a future release.
.. _green-support: .. _green-support:
Support for coroutine libraries Support to coroutine libraries
------------------------------- ------------------------------
.. versionadded:: 2.2 .. versionadded:: 2.2.0
Psycopg can be used together with coroutine_\-based libraries and participate Psycopg can be used together with coroutine_\-based libraries, and participate
in cooperative multithreading. to cooperative multithreading.
Coroutine-based libraries (such as Eventlet_ or gevent_) can usually patch the Coroutine-based libraries (such as Eventlet_ or gevent_) can usually patch the
Python standard library in order to enable a coroutine switch in the presence of Python standard library in order to enable a coroutine switch in the presence of
@ -454,9 +431,11 @@ SQLAlchemy_) to be used in coroutine-based programs.
.. warning:: .. warning::
Psycopg connections are not *green thread safe* and can't be used Psycopg connections are not *green thread safe* and can't be used
concurrently by different green threads. Trying to execute more than one concurrently by different green threads. Each connection has a lock
command at time using one cursor per thread will result in an error (or a used to serialize requests from different cursors to the backend process.
deadlock on versions before 2.4.2). The lock is held for the duration of the command: if the control switched
to a different thread and the latter tried to access the same connection,
the result would be a deadlock.
Therefore, programmers are advised to either avoid sharing connections Therefore, programmers are advised to either avoid sharing connections
between coroutines or to use a library-friendly lock to synchronize shared between coroutines or to use a library-friendly lock to synchronize shared
@ -468,7 +447,7 @@ example callback (using `!select()` to block) is provided as
`psycopg2.extras.wait_select()`: it boils down to something similar to:: `psycopg2.extras.wait_select()`: it boils down to something similar to::
def wait_select(conn): def wait_select(conn):
while True: while 1:
state = conn.poll() state = conn.poll()
if state == extensions.POLL_OK: if state == extensions.POLL_OK:
break break
@ -484,17 +463,16 @@ psycopg2 scope, as the callback can be tied to the libraries' implementation
details. You can check the `psycogreen`_ project for further informations and details. You can check the `psycogreen`_ project for further informations and
resources about the topic. resources about the topic.
.. _coroutine: https://en.wikipedia.org/wiki/Coroutine .. _coroutine: http://en.wikipedia.org/wiki/Coroutine
.. _greenlet: https://pypi.org/project/greenlet/ .. _greenlet: http://pypi.python.org/pypi/greenlet
.. _green threads: https://en.wikipedia.org/wiki/Green_threads .. _green threads: http://en.wikipedia.org/wiki/Green_threads
.. _Eventlet: https://eventlet.net/ .. _Eventlet: http://eventlet.net/
.. _gevent: http://www.gevent.org/ .. _gevent: http://www.gevent.org/
.. _SQLAlchemy: https://www.sqlalchemy.org/ .. _SQLAlchemy: http://www.sqlalchemy.org/
.. _psycogreen: https://github.com/psycopg/psycogreen/ .. _psycogreen: http://bitbucket.org/dvarrazzo/psycogreen/
.. __: https://www.postgresql.org/docs/current/static/libpq-async.html .. __: http://www.postgresql.org/docs/9.0/static/libpq-async.html
.. warning:: .. warning::
:ref:`COPY commands <copy>` are currently not supported when a wait callback :ref:`COPY commands <copy>` are currently not supported when a wait callback
is registered, but they will be probably implemented in a future release. is registered, but they will be probably implemented in a future release.
@ -511,89 +489,3 @@ resources about the topic.
conn.commit() conn.commit()
cur.close() cur.close()
conn.close() conn.close()
.. index::
single: Replication
.. _replication-support:
Replication protocol support
----------------------------
.. versionadded:: 2.7
Modern PostgreSQL servers (version 9.0 and above) support replication. The
replication protocol is built on top of the client-server protocol and can be
operated using ``libpq``, as such it can be also operated by ``psycopg2``.
The replication protocol can be operated on both synchronous and
:ref:`asynchronous <async-support>` connections.
Server version 9.4 adds a new feature called *Logical Replication*.
.. seealso::
- PostgreSQL `Streaming Replication Protocol`__
.. __: https://www.postgresql.org/docs/current/static/protocol-replication.html
Logical replication Quick-Start
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You must be using PostgreSQL server version 9.4 or above to run this quick
start.
Make sure that replication connections are permitted for user ``postgres`` in
``pg_hba.conf`` and reload the server configuration. You also need to set
``wal_level=logical`` and ``max_wal_senders``, ``max_replication_slots`` to
value greater than zero in ``postgresql.conf`` (these changes require a server
restart). Create a database ``psycopg2_test``.
Then run the following code to quickly try the replication support out. This
is not production code -- it's only intended as a simple demo of logical
replication::
from __future__ import print_function
import sys
import psycopg2
import psycopg2.extras
conn = psycopg2.connect('dbname=psycopg2_test user=postgres',
connection_factory=psycopg2.extras.LogicalReplicationConnection)
cur = conn.cursor()
try:
# test_decoding produces textual output
cur.start_replication(slot_name='pytest', decode=True)
except psycopg2.ProgrammingError:
cur.create_replication_slot('pytest', output_plugin='test_decoding')
cur.start_replication(slot_name='pytest', decode=True)
class DemoConsumer(object):
def __call__(self, msg):
print(msg.payload)
msg.cursor.send_feedback(flush_lsn=msg.data_start)
democonsumer = DemoConsumer()
print("Starting streaming, press Control-C to end...", file=sys.stderr)
try:
cur.consume_stream(democonsumer)
except KeyboardInterrupt:
cur.close()
conn.close()
print("The slot 'pytest' still exists. Drop it with "
"SELECT pg_drop_replication_slot('pytest'); if no longer needed.",
file=sys.stderr)
print("WARNING: Transaction logs will accumulate in pg_xlog "
"until the slot is dropped.", file=sys.stderr)
You can now make changes to the ``psycopg2_test`` database using a normal
psycopg2 session, ``psql``, etc. and see the logical decoding stream printed
by this demo client.
This will continue running until terminated with ``Control-C``.
For the details see :ref:`replication-objects`.

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# #
# Psycopg documentation build configuration file, created by # Psycopg documentation build configuration file, created by
# sphinx-quickstart on Sun Feb 7 13:48:41 2010. # sphinx-quickstart on Sun Feb 7 13:48:41 2010.
@ -10,9 +11,7 @@
# All configuration values have a default; values that are commented out # All configuration values have a default; values that are commented out
# serve to show the default. # serve to show the default.
import os import sys, os
import sys
from better import better_theme_path
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the
@ -23,16 +22,11 @@ sys.path.append(os.path.abspath('tools/lib'))
# Add any Sphinx extension module names here, as strings. They can be extensions # Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig',
'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx' ]
'sphinx.ext.todo',
'sphinx.ext.ifconfig',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
]
# Specific extensions for Psycopg documentation. # Specific extensions for Psycopg documentation.
extensions += ['dbapi_extension', 'sql_role', 'ticket_role'] extensions += [ 'dbapi_extension', 'sql_role' ]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']
@ -41,16 +35,14 @@ templates_path = ['_templates']
source_suffix = '.rst' source_suffix = '.rst'
# The encoding of source files. # The encoding of source files.
# source_encoding = 'utf-8' #source_encoding = 'utf-8'
# The master toctree document. # The master toctree document.
master_doc = 'index' master_doc = 'index'
# General information about the project. # General information about the project.
project = 'Psycopg' project = u'Psycopg'
copyright = ( copyright = u'2001-2011, Federico Di Gregorio. Documentation by Daniele Varrazzo'
'2001-2021, Federico Di Gregorio, Daniele Varrazzo, The Psycopg Team'
)
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@ -62,32 +54,29 @@ version = '2.0'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
try: try:
import psycopg2 import psycopg2
except ImportError:
print("WARNING: couldn't import psycopg to read version.")
release = version
else:
release = psycopg2.__version__.split()[0] release = psycopg2.__version__.split()[0]
version = '.'.join(release.split('.')[:2]) version = '.'.join(release.split('.')[:2])
except ImportError:
print "WARNING: couldn't import psycopg to read version."
release = version
intersphinx_mapping = {'py': ('https://docs.python.org/3', None)} intersphinx_mapping = {
'py': ('http://docs.python.org/', None),
# Pattern to generate links to the bug tracker 'py3': ('http://docs.python.org/3.2', None),
ticket_url = 'https://github.com/psycopg/psycopg2/issues/%s' }
ticket_remap_until = 25
ticket_remap_offset = 230
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.
# language = None #language = None
# There are two options for replacing |today|: either, you set today to some # There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used: # non-false value, then it is used:
# today = '' #today = ''
# Else, today_fmt is used as the format for a strftime call. # Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y' #today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build. # List of documents that shouldn't be included in the build.
# unused_docs = [] #unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched # List of directories, relative to source directory, that shouldn't be searched
# for source files. # for source files.
@ -97,25 +86,21 @@ exclude_trees = ['_build', 'html']
default_role = 'obj' default_role = 'obj'
# If true, '()' will be appended to :func: etc. cross-reference text. # If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True #add_function_parentheses = True
# If true, the current module name will be prepended to all description # If true, the current module name will be prepended to all description
# unit titles (such as .. function::). # unit titles (such as .. function::).
# add_module_names = True #add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the # If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default. # output. They are ignored by default.
# show_authors = False #show_authors = False
# Using 'python' instead of the default gives warnings if parsing an example
# fails, instead of defaulting to none
highlight_language = 'python'
# The name of the Pygments (syntax highlighting) style to use. # The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx' pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting. # A list of ignored prefixes for module index sorting.
# modindex_common_prefix = [] #modindex_common_prefix = []
# Include TODO items in the documentation # Include TODO items in the documentation
todo_include_todos = False todo_include_todos = False
@ -123,10 +108,15 @@ todo_include_todos = False
rst_epilog = """ rst_epilog = """
.. |DBAPI| replace:: DB API 2.0 .. |DBAPI| replace:: DB API 2.0
.. _DBAPI: https://www.python.org/dev/peps/pep-0249/ .. _DBAPI: http://www.python.org/dev/peps/pep-0249/
.. _transaction isolation level: .. _transaction isolation level:
https://www.postgresql.org/docs/current/static/transaction-iso.html http://www.postgresql.org/docs/9.0/static/transaction-iso.html
.. _serializable isolation level:
http://www.postgresql.org/docs/9.0/static/transaction-iso.html#XACT-SERIALIZABLE
.. _mx.DateTime: http://www.egenix.com/products/python/mxBase/mxDateTime/
.. |MVCC| replace:: :abbr:`MVCC (Multiversion concurrency control)` .. |MVCC| replace:: :abbr:`MVCC (Multiversion concurrency control)`
""" """
@ -135,41 +125,35 @@ rst_epilog = """
# The theme to use for HTML and HTML Help pages. Major themes that come with # The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'. # Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'better' html_theme = 'default'
# The stylesheet to use with HTML output: this will include the original one # The stylesheet to use with HTML output: this will include the original one
# adding a few classes. # adding a few classes.
# html_style = 'psycopg.css' html_style = 'psycopg.css'
# Hide the sphinx footer
html_show_sphinx = False
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
# documentation. # documentation.
html_theme_options = { #html_theme_options = {}
'linktotheme': False,
'cssfiles': ['_static/psycopg.css'],
}
# Add any paths that contain custom themes here, relative to this directory. # Add any paths that contain custom themes here, relative to this directory.
html_theme_path = [better_theme_path] #html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to # The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation". # "<project> v<release> documentation".
# html_title = None #html_title = None
# A shorter title for the navigation bar. Default is the same as html_title. # A shorter title for the navigation bar. Default is the same as html_title.
html_short_title = 'Home' #html_short_title = None
# The name of an image file (relative to this directory) to place at the top # The name of an image file (relative to this directory) to place at the top
# of the sidebar. # of the sidebar.
# html_logo = None #html_logo = None
# The name of an image file (within the static path) to use as favicon of the # The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large. # pixels large.
# html_favicon = None #html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
@ -178,41 +162,38 @@ html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format. # using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y' #html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to # If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities. # typographically correct entities.
# html_use_smartypants = True #html_use_smartypants = True
# Custom sidebar templates, maps document names to template names. # Custom sidebar templates, maps document names to template names.
# no need for the prev/next topic link using better theme: they are on top #html_sidebars = {}
html_sidebars = {
'**': ['localtoc.html', 'searchbox.html'],
}
# Additional templates that should be rendered to pages, maps page names to # Additional templates that should be rendered to pages, maps page names to
# template names. # template names.
# html_additional_pages = {} #html_additional_pages = {}
# If false, no module index is generated. # If false, no module index is generated.
# html_use_modindex = True #html_use_modindex = True
# If false, no index is generated. # If false, no index is generated.
# html_use_index = True #html_use_index = True
# If true, the index is split into individual pages for each letter. # If true, the index is split into individual pages for each letter.
# html_split_index = False #html_split_index = False
# If true, links to the reST sources are added to the pages. # If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True #html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will # If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the # contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served. # base URL from which the finished HTML is served.
# html_use_opensearch = '' #html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = '' #html_file_suffix = ''
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
htmlhelp_basename = 'psycopgdoc' htmlhelp_basename = 'psycopgdoc'
@ -221,41 +202,35 @@ htmlhelp_basename = 'psycopgdoc'
# -- Options for LaTeX output -------------------------------------------------- # -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4'). # The paper size ('letter' or 'a4').
# latex_paper_size = 'letter' #latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt'). # The font size ('10pt', '11pt' or '12pt').
# latex_font_size = '10pt' #latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]). # (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [ latex_documents = [
( ('index', 'psycopg.tex', u'Psycopg Documentation',
'index', u'Federico Di Gregorio', 'manual'),
'psycopg.tex',
'Psycopg Documentation',
'Federico Di Gregorio',
'manual',
)
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of
# the title page. # the title page.
# latex_logo = None #latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts, # For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters. # not chapters.
# latex_use_parts = False #latex_use_parts = False
# Additional stuff for the LaTeX preamble. # Additional stuff for the LaTeX preamble.
# latex_preamble = '' #latex_preamble = ''
# Documents to append as an appendix to all manuals. # Documents to append as an appendix to all manuals.
# latex_appendices = [] #latex_appendices = []
# If false, no module index is generated. # If false, no module index is generated.
# latex_use_modindex = True #latex_use_modindex = True
toc_object_entries = False
doctest_global_setup = """ doctest_global_setup = """

View File

@ -18,42 +18,16 @@ The ``connection`` class
Connections are created using the factory function Connections are created using the factory function
`~psycopg2.connect()`. `~psycopg2.connect()`.
Connections are thread safe and can be shared among many threads. See Connections are thread safe and can be shared among many thread. See
:ref:`thread-safety` for details. :ref:`thread-safety` for details.
Connections can be used as context managers. Note that a context wraps a .. method:: cursor([name] [, cursor_factory])
transaction: if the context exits with success the transaction is
committed, if it exits with an exception the transaction is rolled back.
Note that the connection is not closed by the context and it can be used
for several contexts.
.. code:: python
conn = psycopg2.connect(DSN)
with conn:
with conn.cursor() as curs:
curs.execute(SQL1)
with conn:
with conn.cursor() as curs:
curs.execute(SQL2)
# leaving contexts doesn't close the connection
conn.close()
.. method:: cursor(name=None, cursor_factory=None, scrollable=None, withhold=False)
Return a new `cursor` object using the connection. Return a new `cursor` object using the connection.
If *name* is specified, the returned cursor will be a :ref:`server If *name* is specified, the returned cursor will be a :ref:`server
side cursor <server-side-cursors>` (also known as *named cursor*). side cursor <server-side-cursors>` (also known as *named cursor*).
Otherwise it will be a regular *client side* cursor. By default a Otherwise it will be a regular *client side* cursor.
named cursor is declared without :sql:`SCROLL` option and
:sql:`WITHOUT HOLD`: set the argument or property `~cursor.scrollable`
to `!True`/`!False` and or `~cursor.withhold` to `!True` to change the
declaration.
The name can be a string not valid as a PostgreSQL identifier: for The name can be a string not valid as a PostgreSQL identifier: for
example it may start with a digit and contain non-alphanumeric example it may start with a digit and contain non-alphanumeric
@ -63,39 +37,31 @@ The ``connection`` class
previously only valid PostgreSQL identifiers were accepted as previously only valid PostgreSQL identifiers were accepted as
cursor name. cursor name.
The *cursor_factory* argument can be used to create non-standard .. warning::
cursors. The class returned must be a subclass of It is unsafe to expose the *name* to an untrusted source, for
`psycopg2.extensions.cursor`. See :ref:`subclassing-cursor` for instance you shouldn't allow *name* to be read from a HTML form.
details. A default factory for the connection can also be specified Consider it as part of the query, not as a query parameter.
using the `~connection.cursor_factory` attribute.
.. versionchanged:: 2.4.3 added the *withhold* argument. The *cursor_factory* argument can be used to create non-standard
.. versionchanged:: 2.5 added the *scrollable* argument. cursors. The class returned should be a subclass of
`psycopg2.extensions.cursor`. See :ref:`subclassing-cursor` for
details.
.. extension:: .. extension::
All the function arguments are Psycopg extensions to the |DBAPI|. The `name` and `cursor_factory` parameters are Psycopg
extensions to the |DBAPI|.
.. index:: .. index::
pair: Transaction; Commit pair: Transaction; Commit
.. method:: commit() .. method:: commit()
Commit any pending transaction to the database. Commit any pending transaction to the database. Psycopg can be set to
perform automatic commits at each operation, see
By default, Psycopg opens a transaction before executing the first `~connection.set_isolation_level()`.
command: if `!commit()` is not called, the effect of any data
manipulation will be lost.
The connection can be also set in "autocommit" mode: no transaction is
automatically open, commands have immediate effect. See
:ref:`transactions-control` for details.
.. versionchanged:: 2.5 if the connection is used in a ``with``
statement, the method is automatically called if no exception is
raised in the ``with`` block.
.. index:: .. index::
pair: Transaction; Rollback pair: Transaction; Rollback
@ -106,13 +72,9 @@ The ``connection`` class
connection without committing the changes first will cause an implicit connection without committing the changes first will cause an implicit
rollback to be performed. rollback to be performed.
.. versionchanged:: 2.5 if the connection is used in a ``with``
statement, the method is automatically called if an exception is
raised in the ``with`` block.
.. method:: close() .. method:: close()
Close the connection now (rather than whenever `del` is executed). Close the connection now (rather than whenever `del` is executed).
The connection will be unusable from this point forward; an The connection will be unusable from this point forward; an
`~psycopg2.InterfaceError` will be raised if any operation is `~psycopg2.InterfaceError` will be raised if any operation is
@ -139,7 +101,7 @@ The ``connection`` class
with a `~connection.commit()`/`~connection.rollback()` before with a `~connection.commit()`/`~connection.rollback()` before
closing. closing.
.. _PgBouncer: http://www.pgbouncer.org/ .. _PgBouncer: http://pgbouncer.projects.postgresql.org/
.. index:: .. index::
@ -220,7 +182,7 @@ The ``connection`` class
.. seealso:: the |PREPARE TRANSACTION|_ PostgreSQL command. .. seealso:: the |PREPARE TRANSACTION|_ PostgreSQL command.
.. |PREPARE TRANSACTION| replace:: :sql:`PREPARE TRANSACTION` .. |PREPARE TRANSACTION| replace:: :sql:`PREPARE TRANSACTION`
.. _PREPARE TRANSACTION: https://www.postgresql.org/docs/current/static/sql-prepare-transaction.html .. _PREPARE TRANSACTION: http://www.postgresql.org/docs/9.0/static/sql-prepare-transaction.html
.. index:: .. index::
@ -246,7 +208,7 @@ The ``connection`` class
.. seealso:: the |COMMIT PREPARED|_ PostgreSQL command. .. seealso:: the |COMMIT PREPARED|_ PostgreSQL command.
.. |COMMIT PREPARED| replace:: :sql:`COMMIT PREPARED` .. |COMMIT PREPARED| replace:: :sql:`COMMIT PREPARED`
.. _COMMIT PREPARED: https://www.postgresql.org/docs/current/static/sql-commit-prepared.html .. _COMMIT PREPARED: http://www.postgresql.org/docs/9.0/static/sql-commit-prepared.html
.. index:: .. index::
@ -268,7 +230,7 @@ The ``connection`` class
.. seealso:: the |ROLLBACK PREPARED|_ PostgreSQL command. .. seealso:: the |ROLLBACK PREPARED|_ PostgreSQL command.
.. |ROLLBACK PREPARED| replace:: :sql:`ROLLBACK PREPARED` .. |ROLLBACK PREPARED| replace:: :sql:`ROLLBACK PREPARED`
.. _ROLLBACK PREPARED: https://www.postgresql.org/docs/current/static/sql-rollback-prepared.html .. _ROLLBACK PREPARED: http://www.postgresql.org/docs/9.0/static/sql-rollback-prepared.html
.. index:: .. index::
@ -289,17 +251,17 @@ The ``connection`` class
transactions initiated by a program using such driver should be transactions initiated by a program using such driver should be
unpacked correctly. unpacked correctly.
.. __: https://jdbc.postgresql.org/ .. __: http://jdbc.postgresql.org/
Xids returned by `!tpc_recover()` also have extra attributes Xids returned by `!tpc_recover()` also have extra attributes
`~psycopg2.extensions.Xid.prepared`, `~psycopg2.extensions.Xid.owner`, `~psycopg2.extensions.Xid.prepared`, `~psycopg2.extensions.Xid.owner`,
`~psycopg2.extensions.Xid.database` populated with the values read `~psycopg2.extensions.Xid.database` populated with the values read
from the server. from the server.
.. seealso:: the |pg_prepared_xacts|_ system view. .. seealso:: the |pg_prepared_xacts|_ system view.
.. |pg_prepared_xacts| replace:: `pg_prepared_xacts` .. |pg_prepared_xacts| replace:: `pg_prepared_xacts`
.. _pg_prepared_xacts: https://www.postgresql.org/docs/current/static/view-pg-prepared-xacts.html .. _pg_prepared_xacts: http://www.postgresql.org/docs/9.0/static/view-pg-prepared-xacts.html
@ -312,8 +274,8 @@ The ``connection`` class
.. attribute:: closed .. attribute:: closed
Read-only integer attribute: 0 if the connection is open, nonzero if Read-only attribute reporting whether the database connection is open
it is closed or broken. (0) or closed (1).
.. method:: cancel .. method:: cancel
@ -331,7 +293,7 @@ The ``connection`` class
|PQcancel|_. |PQcancel|_.
.. |PQcancel| replace:: `!PQcancel()` .. |PQcancel| replace:: `!PQcancel()`
.. _PQcancel: https://www.postgresql.org/docs/current/static/libpq-cancel.html#LIBPQ-PQCANCEL .. _PQcancel: http://www.postgresql.org/docs/8.4/static/libpq-cancel.html#AEN34765
.. versionadded:: 2.3 .. versionadded:: 2.3
@ -347,10 +309,10 @@ The ``connection`` class
available for recover. available for recover.
.. |RESET| replace:: :sql:`RESET` .. |RESET| replace:: :sql:`RESET`
.. _RESET: https://www.postgresql.org/docs/current/static/sql-reset.html .. _RESET: http://www.postgresql.org/docs/9.0/static/sql-reset.html
.. |SET SESSION AUTHORIZATION| replace:: :sql:`SET SESSION AUTHORIZATION` .. |SET SESSION AUTHORIZATION| replace:: :sql:`SET SESSION AUTHORIZATION`
.. __: https://www.postgresql.org/docs/current/static/sql-set-session-authorization.html .. __: http://www.postgresql.org/docs/9.0/static/sql-set-session-authorization.html
.. versionadded:: 2.0.12 .. versionadded:: 2.0.12
@ -360,195 +322,34 @@ The ``connection`` class
Read-only string containing the connection string used by the Read-only string containing the connection string used by the
connection. connection.
If a password was specified in the connection string it will be
obscured.
.. rubric:: Transaction control methods and attributes.
.. index:: .. index::
pair: Transaction; Autocommit pair: Transaction; Autocommit
pair: Transaction; Isolation level pair: Transaction; Isolation level
.. method:: set_session(isolation_level=None, readonly=None, deferrable=None, autocommit=None) .. _autocommit:
Set one or more parameters for the next transactions or statements in
the current session.
:param isolation_level: set the `isolation level`_ for the next
transactions/statements. The value can be one of the literal
values ``READ UNCOMMITTED``, ``READ COMMITTED``, ``REPEATABLE
READ``, ``SERIALIZABLE`` or the equivalent :ref:`constant
<isolation-level-constants>` defined in the `~psycopg2.extensions`
module.
:param readonly: if `!True`, set the connection to read only;
read/write if `!False`.
:param deferrable: if `!True`, set the connection to deferrable;
non deferrable if `!False`. Only available from PostgreSQL 9.1.
:param autocommit: switch the connection to autocommit mode: not a
PostgreSQL session setting but an alias for setting the
`autocommit` attribute.
.. _isolation level:
https://www.postgresql.org/docs/current/static/transaction-iso.html
Arguments set to `!None` (the default for all) will not be changed.
The parameters *isolation_level*, *readonly* and *deferrable* also
accept the string ``DEFAULT`` as a value: the effect is to reset the
parameter to the server default. Defaults are defined by the server
configuration: see values for |default_transaction_isolation|__,
|default_transaction_read_only|__, |default_transaction_deferrable|__.
.. |default_transaction_isolation| replace:: :sql:`default_transaction_isolation`
.. __: https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-ISOLATION
.. |default_transaction_read_only| replace:: :sql:`default_transaction_read_only`
.. __: https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-READ-ONLY
.. |default_transaction_deferrable| replace:: :sql:`default_transaction_deferrable`
.. __: https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-DEFERRABLE
The function must be invoked with no transaction in progress.
.. seealso:: |SET TRANSACTION|_ for further details about the behaviour
of the transaction parameters in the server.
.. |SET TRANSACTION| replace:: :sql:`SET TRANSACTION`
.. _SET TRANSACTION: https://www.postgresql.org/docs/current/static/sql-set-transaction.html
.. versionadded:: 2.4.2
.. versionchanged:: 2.7
Before this version, the function would have set
:sql:`default_transaction_*` attribute in the current session;
this implementation has the problem of not playing well with
external connection pooling working at transaction level and not
resetting the state of the session: changing the default
transaction would pollute the connections in the pool and create
problems to other applications using the same pool.
Starting from 2.7, if the connection is not autocommit, the
transaction characteristics are issued together with :sql:`BEGIN`
and will leave the :sql:`default_transaction_*` settings untouched.
For example::
conn.set_session(readonly=True)
will not change :sql:`default_transaction_read_only`, but
following transaction will start with a :sql:`BEGIN READ ONLY`.
Conversely, using::
conn.set_session(readonly=True, autocommit=True)
will set :sql:`default_transaction_read_only` to :sql:`on` and
rely on the server to apply the read only state to whatever
transaction, implicit or explicit, is executed in the connection.
.. attribute:: autocommit
Read/write attribute: if `!True`, no transaction is handled by the
driver and every statement sent to the backend has immediate effect;
if `!False` a new transaction is started at the first command
execution: the methods `commit()` or `rollback()` must be manually
invoked to terminate the transaction.
The autocommit mode is useful to execute commands requiring to be run
outside a transaction, such as :sql:`CREATE DATABASE` or
:sql:`VACUUM`.
The default is `!False` (manual commit) as per DBAPI specification.
.. warning::
By default, any query execution, including a simple :sql:`SELECT`
will start a transaction: for long-running programs, if no further
action is taken, the session will remain "idle in transaction", an
undesirable condition for several reasons (locks are held by
the session, tables bloat...). For long lived scripts, either
ensure to terminate a transaction as soon as possible or use an
autocommit connection.
.. versionadded:: 2.4.2
.. attribute:: isolation_level .. attribute:: isolation_level
Return or set the `transaction isolation level`_ for the current
session. The value is one of the :ref:`isolation-level-constants`
defined in the `psycopg2.extensions` module. On set it is also
possible to use one of the literal values ``READ UNCOMMITTED``, ``READ
COMMITTED``, ``REPEATABLE READ``, ``SERIALIZABLE``, ``DEFAULT``.
.. versionchanged:: 2.7
the property is writable.
.. versionchanged:: 2.7
the default value for `!isolation_level` is
`~psycopg2.extensions.ISOLATION_LEVEL_DEFAULT`; previously the
property would have queried the server and returned the real value
applied. To know this value you can run a query such as :sql:`show
transaction_isolation`. Usually the default value is `READ
COMMITTED`, but this may be changed in the server configuration.
This value is now entirely separate from the `autocommit`
property: in previous version, if `!autocommit` was set to `!True`
this property would have returned
`~psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT`; it will now
return the server isolation level.
.. attribute:: readonly
Return or set the read-only status for the current session. Available
values are `!True` (new transactions will be in read-only mode),
`!False` (new transactions will be writable), `!None` (use the default
configured for the server by :sql:`default_transaction_read_only`).
.. versionadded:: 2.7
.. attribute:: deferrable
Return or set the `deferrable status`__ for the current session.
Available values are `!True` (new transactions will be in deferrable
mode), `!False` (new transactions will be in non deferrable mode),
`!None` (use the default configured for the server by
:sql:`default_transaction_deferrable`).
.. __: `SET TRANSACTION`_
.. versionadded:: 2.7
.. method:: set_isolation_level(level) .. method:: set_isolation_level(level)
.. note:: Read or set the `transaction isolation level`_ for the current session.
This is a legacy method mixing `~conn.isolation_level` and
`~conn.autocommit`. Using the respective properties is a better
option.
Set the `transaction isolation level`_ for the current session.
The level defines the different phenomena that can happen in the The level defines the different phenomena that can happen in the
database between concurrent transactions. database between concurrent transactions.
The value set is an integer: symbolic constants are defined in The value set or read is an integer: symbolic constants are defined in
the module `psycopg2.extensions`: see the module `psycopg2.extensions`: see
:ref:`isolation-level-constants` for the available values. :ref:`isolation-level-constants` for the available values.
The default level is `~psycopg2.extensions.ISOLATION_LEVEL_DEFAULT`: The default level is :sql:`READ COMMITTED`: at this level a
at this level a transaction is automatically started the first time a transaction is automatically started the first time a database command
database command is executed. If you want an *autocommit* mode, is executed. If you want an *autocommit* mode, switch to
switch to `~psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT` before `~psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT` before
executing any command:: executing any command::
>>> conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) >>> conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
See also :ref:`transactions-control`. See also :ref:`transactions-control`.
.. index:: .. index::
pair: Client; Encoding pair: Client; Encoding
@ -559,7 +360,7 @@ The ``connection`` class
is the encoding defined by the database. It should be one of the is the encoding defined by the database. It should be one of the
`characters set supported by PostgreSQL`__ `characters set supported by PostgreSQL`__
.. __: https://www.postgresql.org/docs/current/static/multibyte.html .. __: http://www.postgresql.org/docs/9.0/static/multibyte.html
.. index:: .. index::
@ -571,29 +372,21 @@ The ``connection`` class
the session. the session.
.. doctest:: .. doctest::
:options: +NORMALIZE_WHITESPACE :options: NORMALIZE_WHITESPACE
>>> cur.execute("CREATE TABLE foo (id serial PRIMARY KEY);") >>> cur.execute("CREATE TABLE foo (id serial PRIMARY KEY);")
>>> pprint(conn.notices) >>> pprint(conn.notices)
['NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"\n', ['NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"\n',
'NOTICE: CREATE TABLE will create implicit sequence "foo_id_seq" for serial column "foo.id"\n'] 'NOTICE: CREATE TABLE will create implicit sequence "foo_id_seq" for serial column "foo.id"\n']
.. versionchanged:: 2.7
The `!notices` attribute is writable: the user may replace it
with any Python object exposing an `!append()` method. If
appending raises an exception the notice is silently
dropped.
To avoid a leak in case excessive notices are generated, only the last To avoid a leak in case excessive notices are generated, only the last
50 messages are kept. This check is only in place if the `!notices` 50 messages are kept.
attribute is a list: if any other object is used it will be up to the
user to guard from leakage.
You can configure what messages to receive using `PostgreSQL logging You can configure what messages to receive using `PostgreSQL logging
configuration parameters`__ such as ``log_statement``, configuration parameters`__ such as ``log_statement``,
``client_min_messages``, ``log_min_duration_statement`` etc. ``client_min_messages``, ``log_min_duration_statement`` etc.
.. __: https://www.postgresql.org/docs/current/static/runtime-config-logging.html .. __: http://www.postgresql.org/docs/9.0/static/runtime-config-logging.html
.. attribute:: notifies .. attribute:: notifies
@ -609,30 +402,93 @@ The ``connection`` class
the payload was not accessible. To keep backward compatibility, the payload was not accessible. To keep backward compatibility,
`!Notify` objects can still be accessed as 2 items tuples. `!Notify` objects can still be accessed as 2 items tuples.
.. versionchanged:: 2.7 .. index::
The `!notifies` attribute is writable: the user may replace it pair: Backend; PID
with any Python object exposing an `!append()` method. If
appending raises an exception the notification is silently
dropped.
.. method:: get_backend_pid()
.. attribute:: cursor_factory Returns the process ID (PID) of the backend server process handling
this connection.
The default cursor factory used by `~connection.cursor()` if the Note that the PID belongs to a process executing on the database
parameter is not specified. server host, not the local host!
.. versionadded:: 2.5 .. seealso:: libpq docs for `PQbackendPID()`__ for details.
.. __: http://www.postgresql.org/docs/9.0/static/libpq-status.html#LIBPQ-PQBACKENDPID
.. versionadded:: 2.0.8
.. index:: .. index::
pair: Connection; Info pair: Server; Parameters
.. attribute:: info .. method:: get_parameter_status(parameter)
Look up a current parameter setting of the server.
A `~psycopg2.extensions.ConnectionInfo` object exposing information Potential values for ``parameter`` are: ``server_version``,
about the native libpq connection. ``server_encoding``, ``client_encoding``, ``is_superuser``,
``session_authorization``, ``DateStyle``, ``TimeZone``,
``integer_datetimes``, and ``standard_conforming_strings``.
.. versionadded:: 2.8 If server did not report requested parameter, return `!None`.
.. seealso:: libpq docs for `PQparameterStatus()`__ for details.
.. __: http://www.postgresql.org/docs/9.0/static/libpq-status.html#LIBPQ-PQPARAMETERSTATUS
.. versionadded:: 2.0.12
.. index::
pair: Transaction; Status
.. method:: get_transaction_status()
Return the current session transaction status as an integer. Symbolic
constants for the values are defined in the module
`psycopg2.extensions`: see :ref:`transaction-status-constants`
for the available values.
.. seealso:: libpq docs for `PQtransactionStatus()`__ for details.
.. __: http://www.postgresql.org/docs/9.0/static/libpq-status.html#LIBPQ-PQTRANSACTIONSTATUS
.. index::
pair: Protocol; Version
.. attribute:: protocol_version
A read-only integer representing frontend/backend protocol being used.
Currently Psycopg supports only protocol 3, which allows connection
to PostgreSQL server from version 7.4. Psycopg versions previous than
2.3 support both protocols 2 and 3.
.. seealso:: libpq docs for `PQprotocolVersion()`__ for details.
.. __: http://www.postgresql.org/docs/9.0/static/libpq-status.html#LIBPQ-PQPROTOCOLVERSION
.. versionadded:: 2.0.12
.. index::
pair: Server; Version
.. attribute:: server_version
A read-only integer representing the backend version.
The number is formed by converting the major, minor, and revision
numbers into two-decimal-digit numbers and appending them together.
For example, version 8.1.5 will be returned as ``80105``.
.. seealso:: libpq docs for `PQserverVersion()`__ for details.
.. __: http://www.postgresql.org/docs/9.0/static/libpq-status.html#LIBPQ-PQSERVERVERSION
.. versionadded:: 2.0.12
.. index:: .. index::
@ -641,12 +497,10 @@ The ``connection`` class
.. attribute:: status .. attribute:: status
A read-only integer representing the status of the connection. A read-only integer representing the status of the connection.
Symbolic constants for the values are defined in the module Symbolic constants for the values are defined in the module
`psycopg2.extensions`: see :ref:`connection-status-constants` `psycopg2.extensions`: see :ref:`connection-status-constants`
for the available values. for the available values.
The status is undefined for `closed` connections.
.. method:: lobject([oid [, mode [, new_oid [, new_file [, lobject_factory]]]]]) .. method:: lobject([oid [, mode [, new_oid [, new_file [, lobject_factory]]]]])
@ -661,13 +515,13 @@ The ``connection`` class
:param new_oid: Create a new object using the specified OID. The :param new_oid: Create a new object using the specified OID. The
function raises `~psycopg2.OperationalError` if the OID is already function raises `~psycopg2.OperationalError` if the OID is already
in use. Default is 0, meaning assign a new one automatically. in use. Default is 0, meaning assign a new one automatically.
:param new_file: The name of a file to be imported in the database :param new_file: The name of a file to be imported in the the database
(using the |lo_import|_ function) (using the |lo_import|_ function)
:param lobject_factory: Subclass of :param lobject_factory: Subclass of
`~psycopg2.extensions.lobject` to be instantiated. `~psycopg2.extensions.lobject` to be instantiated.
.. |lo_import| replace:: `!lo_import()` .. |lo_import| replace:: `!lo_import()`
.. _lo_import: https://www.postgresql.org/docs/current/static/lo-interfaces.html#LO-IMPORT .. _lo_import: http://www.postgresql.org/docs/9.0/static/lo-interfaces.html#LO-IMPORT
Available values for *mode* are: Available values for *mode* are:
@ -692,21 +546,17 @@ The ``connection`` class
support. support.
.. rubric:: Methods related to asynchronous support .. rubric:: Methods related to asynchronous support.
.. versionadded:: 2.2 .. versionadded:: 2.2.0
.. seealso:: :ref:`async-support` and :ref:`green-support`. .. seealso:: :ref:`async-support` and :ref:`green-support`.
.. attribute:: async .. attribute:: async
async_
Read only attribute: 1 if the connection is asynchronous, 0 otherwise. Read only attribute: 1 if the connection is asynchronous, 0 otherwise.
.. versionchanged:: 2.7 added the `!async_` alias for Python versions
where `!async` is a keyword.
.. method:: poll() .. method:: poll()
@ -716,7 +566,7 @@ The ``connection`` class
Return one of the constants defined in :ref:`poll-constants`. If it Return one of the constants defined in :ref:`poll-constants`. If it
returns `~psycopg2.extensions.POLL_OK` then the connection has been returns `~psycopg2.extensions.POLL_OK` then the connection has been
established or the query results are available on the client. estabilished or the query results are available on the client.
Otherwise wait until the file descriptor returned by `fileno()` is Otherwise wait until the file descriptor returned by `fileno()` is
ready to read or to write, as explained in :ref:`async-support`. ready to read or to write, as explained in :ref:`async-support`.
`poll()` should be also used by the function installed by `poll()` should be also used by the function installed by
@ -738,178 +588,6 @@ The ``connection`` class
Return `!True` if the connection is executing an asynchronous operation. Return `!True` if the connection is executing an asynchronous operation.
.. rubric:: Interoperation with other C API modules
.. attribute:: pgconn_ptr
Return the internal `!PGconn*` as integer. Useful to pass the libpq
raw connection structure to C functions, e.g. via `ctypes`::
>>> import ctypes
>>> import ctypes.util
>>> libpq = ctypes.pydll.LoadLibrary(ctypes.util.find_library('pq'))
>>> libpq.PQserverVersion.argtypes = [ctypes.c_void_p]
>>> libpq.PQserverVersion.restype = ctypes.c_int
>>> libpq.PQserverVersion(conn.pgconn_ptr)
90611
.. versionadded:: 2.8
.. method:: get_native_connection()
Return the internal `!PGconn*` wrapped in a PyCapsule object. This is
only useful for passing the `libpq` raw connection associated to this
connection object to other C-level modules that may have a use for it.
.. seealso:: Python C API `Capsules`__ docs.
.. __: https://docs.python.org/3.1/c-api/capsule.html
.. versionadded:: 2.8
.. rubric:: informative methods of the native connection
.. note::
These methods are better accessed using the `~connection.info`
attributes and may be dropped in future versions.
.. index::
pair: Transaction; Status
.. method:: get_transaction_status()
Also available as `~connection.info`\ `!.`\
`~psycopg2.extensions.ConnectionInfo.transaction_status`.
Return the current session transaction status as an integer. Symbolic
constants for the values are defined in the module
`psycopg2.extensions`: see :ref:`transaction-status-constants`
for the available values.
.. seealso:: libpq docs for `PQtransactionStatus()`__ for details.
.. __: https://www.postgresql.org/docs/current/static/libpq-status.html#LIBPQ-PQTRANSACTIONSTATUS
.. index::
pair: Protocol; Version
.. attribute:: protocol_version
Also available as `~connection.info`\ `!.`\
`~psycopg2.extensions.ConnectionInfo.protocol_version`.
A read-only integer representing frontend/backend protocol being used.
Currently Psycopg supports only protocol 3, which allows connection
to PostgreSQL server from version 7.4. Psycopg versions previous than
2.3 support both protocols 2 and 3.
.. seealso:: libpq docs for `PQprotocolVersion()`__ for details.
.. __: https://www.postgresql.org/docs/current/static/libpq-status.html#LIBPQ-PQPROTOCOLVERSION
.. versionadded:: 2.0.12
.. index::
pair: Server; Version
.. attribute:: server_version
Also available as `~connection.info`\ `!.`\
`~psycopg2.extensions.ConnectionInfo.server_version`.
A read-only integer representing the backend version.
The number is formed by converting the major, minor, and revision
numbers into two-decimal-digit numbers and appending them together.
For example, version 8.1.5 will be returned as ``80105``.
.. seealso:: libpq docs for `PQserverVersion()`__ for details.
.. __: https://www.postgresql.org/docs/current/static/libpq-status.html#LIBPQ-PQSERVERVERSION
.. versionadded:: 2.0.12
.. index::
pair: Backend; PID
.. method:: get_backend_pid()
Also available as `~connection.info`\ `!.`\
`~psycopg2.extensions.ConnectionInfo.backend_pid`.
Returns the process ID (PID) of the backend server process *you
connected to*. Note that if you use a connection pool service such as
PgBouncer_ this value will not be updated if your connection is
switched to a different backend.
Note that the PID belongs to a process executing on the database
server host, not the local host!
.. seealso:: libpq docs for `PQbackendPID()`__ for details.
.. __: https://www.postgresql.org/docs/current/static/libpq-status.html#LIBPQ-PQBACKENDPID
.. versionadded:: 2.0.8
.. index::
pair: Server; Parameters
.. method:: get_parameter_status(parameter)
Also available as `~connection.info`\ `!.`\
`~psycopg2.extensions.ConnectionInfo.parameter_status()`.
Look up a current parameter setting of the server.
Potential values for ``parameter`` are: ``server_version``,
``server_encoding``, ``client_encoding``, ``is_superuser``,
``session_authorization``, ``DateStyle``, ``TimeZone``,
``integer_datetimes``, and ``standard_conforming_strings``.
If server did not report requested parameter, return `!None`.
.. seealso:: libpq docs for `PQparameterStatus()`__ for details.
.. __: https://www.postgresql.org/docs/current/static/libpq-status.html#LIBPQ-PQPARAMETERSTATUS
.. versionadded:: 2.0.12
.. index::
pair: Connection; Parameters
.. method:: get_dsn_parameters()
Also available as `~connection.info`\ `!.`\
`~psycopg2.extensions.ConnectionInfo.dsn_parameters`.
Get the effective dsn parameters for the connection as a dictionary.
The *password* parameter is removed from the result.
Example::
>>> conn.get_dsn_parameters()
{'dbname': 'test', 'user': 'postgres', 'port': '5432', 'sslmode': 'prefer'}
Requires libpq >= 9.3.
.. seealso:: libpq docs for `PQconninfo()`__ for details.
.. __: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PQCONNINFO
.. versionadded:: 2.7
.. testcode:: .. testcode::
:hide: :hide:

View File

@ -34,74 +34,56 @@ The ``cursor`` class
many cursors from the same connection and should use each cursor from many cursors from the same connection and should use each cursor from
a single thread. See :ref:`thread-safety` for details. a single thread. See :ref:`thread-safety` for details.
Cursors can be used as context managers: leaving the context will close
the cursor. .. attribute:: description
.. code:: python This read-only attribute is a sequence of 7-item sequences.
with conn.cursor() as curs: Each of these sequences is a named tuple (a regular tuple if
curs.execute(SQL) :func:`collections.namedtuple` is not available) containing information
describing one result column:
# the cursor is now closed 0. `!name`: the name of the column returned.
1. `!type_code`: the PostgreSQL OID of the column. You can use the
|pg_type|_ system table to get more informations about the type.
This is the value used by Psycopg to decide what Python type use
to represent the value. See also
:ref:`type-casting-from-sql-to-python`.
2. `!display_size`: the actual length of the column in bytes.
Obtaining this value is computationally intensive, so it is
always `!None` unless the :envvar:`PSYCOPG_DISPLAY_SIZE` parameter
is set at compile time. See also PQgetlength_.
3. `!internal_size`: the size in bytes of the column associated to
this column on the server. Set to a negative value for
variable-size types See also PQfsize_.
4. `!precision`: total number of significant digits in columns of
type |NUMERIC|_. `!None` for other types.
5. `!scale`: count of decimal digits in the fractional part in
columns of type |NUMERIC|. `!None` for other types.
6. `!null_ok`: always `!None` as not easy to retrieve from the libpq.
This attribute will be `!None` for operations that do not return rows
.. attribute:: description or if the cursor has not had an operation invoked via the
|execute*|_ methods yet.
Read-only attribute describing the result of a query. It is a
sequence of `~psycopg2.extensions.Column` instances, each one .. |pg_type| replace:: :sql:`pg_type`
describing one result column in order. The attribute is `!None` for .. _pg_type: http://www.postgresql.org/docs/9.0/static/catalog-pg-type.html
operations that do not return rows or if the cursor has not had an .. _PQgetlength: http://www.postgresql.org/docs/9.0/static/libpq-exec.html#LIBPQ-PQGETLENGTH
operation invoked via the |execute*|_ methods yet. .. _PQfsize: http://www.postgresql.org/docs/9.0/static/libpq-exec.html#LIBPQ-PQFSIZE
.. _NUMERIC: http://www.postgresql.org/docs/9.0/static/datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL
For compatibility with the DB-API, every object can be unpacked as a .. |NUMERIC| replace:: :sql:`NUMERIC`
7-items sequence: the attributes retuned this way are the following.
For further details and other attributes available check the
`~psycopg2.extensions.Column` documentation.
0. `~psycopg2.extensions.Column.name`: the name of the column returned.
1. `~psycopg2.extensions.Column.type_code`: the PostgreSQL OID of the
column.
2. `~psycopg2.extensions.Column.display_size`: the actual length of
the column in bytes.
3. `~psycopg2.extensions.Column.internal_size`: the size in bytes of
the column associated to this column on the server.
4. `~psycopg2.extensions.Column.precision`: total number of
significant digits in columns of type |NUMERIC|. `!None`
for other types.
5. `~psycopg2.extensions.Column.scale`: count of decimal digits in
the fractional part in columns of type |NUMERIC|. `!None`
for other types.
6. `~psycopg2.extensions.Column.null_ok`: always `!None` as not easy
to retrieve from the libpq.
.. versionchanged:: 2.4 .. versionchanged:: 2.4
if possible, columns descriptions are named tuple instead of if possible, columns descriptions are named tuple instead of
regular tuples. regular tuples.
.. versionchanged:: 2.8
columns descriptions are instances of `!Column`, exposing extra
attributes.
.. |NUMERIC| replace:: :sql:`NUMERIC`
.. method:: close() .. method:: close()
Close the cursor now (rather than whenever `del` is executed). Close the cursor now (rather than whenever `del` is executed).
The cursor will be unusable from this point forward; an The cursor will be unusable from this point forward; an
`~psycopg2.InterfaceError` will be raised if any operation is `~psycopg2.InterfaceError` will be raised if any operation is
attempted with the cursor. attempted with the cursor.
.. versionchanged:: 2.5 if the cursor is used in a ``with`` statement,
the method is automatically called at the end of the ``with``
block.
.. attribute:: closed .. attribute:: closed
Read-only boolean attribute: specifies if the cursor is closed Read-only boolean attribute: specifies if the cursor is closed
@ -124,7 +106,7 @@ The ``cursor`` class
.. attribute:: name .. attribute:: name
Read-only attribute containing the name of the cursor if it was Read-only attribute containing the name of the cursor if it was
created as named cursor by `connection.cursor()`, or `!None` if creates as named cursor by `connection.cursor()`, or `!None` if
it is a client side cursor. See :ref:`server-side-cursors`. it is a client side cursor. See :ref:`server-side-cursors`.
.. extension:: .. extension::
@ -132,51 +114,7 @@ The ``cursor`` class
The `name` attribute is a Psycopg extension to the |DBAPI|. The `name` attribute is a Psycopg extension to the |DBAPI|.
.. attribute:: scrollable
Read/write attribute: specifies if a named cursor is declared
:sql:`SCROLL`, hence is capable to scroll backwards (using
`~cursor.scroll()`). If `!True`, the cursor can be scrolled backwards,
if `!False` it is never scrollable. If `!None` (default) the cursor
scroll option is not specified, usually but not always meaning no
backward scroll (see the |declare-notes|__).
.. |declare-notes| replace:: :sql:`DECLARE` notes
.. __: https://www.postgresql.org/docs/current/static/sql-declare.html#SQL-DECLARE-NOTES
.. note::
set the value before calling `~cursor.execute()` or use the
`connection.cursor()` *scrollable* parameter, otherwise the value
will have no effect.
.. versionadded:: 2.5
.. extension::
The `scrollable` attribute is a Psycopg extension to the |DBAPI|.
.. attribute:: withhold
Read/write attribute: specifies if a named cursor lifetime should
extend outside of the current transaction, i.e., it is possible to
fetch from the cursor even after a `connection.commit()` (but not after
a `connection.rollback()`). See :ref:`server-side-cursors`
.. note::
set the value before calling `~cursor.execute()` or use the
`connection.cursor()` *withhold* parameter, otherwise the value
will have no effect.
.. versionadded:: 2.4.3
.. extension::
The `withhold` attribute is a Psycopg extension to the |DBAPI|.
.. |execute*| replace:: `execute*()` .. |execute*| replace:: `execute*()`
.. _execute*: .. _execute*:
@ -184,71 +122,43 @@ The ``cursor`` class
.. rubric:: Commands execution methods .. rubric:: Commands execution methods
.. method:: execute(query, vars=None) .. method:: execute(operation [, parameters])
Execute a database operation (query or command). Prepare and execute a database operation (query or command).
Parameters may be provided as sequence or mapping and will be bound to Parameters may be provided as sequence or mapping and will be bound to
variables in the operation. Variables are specified either with variables in the operation. Variables are specified either with
positional (``%s``) or named (:samp:`%({name})s`) placeholders. See positional (``%s``) or named (:samp:`%({name})s`) placeholders. See
:ref:`query-parameters`. :ref:`query-parameters`.
The method returns `!None`. If a query was executed, the returned The method returns `!None`. If a query was executed, the returned
values can be retrieved using |fetch*|_ methods. values can be retrieved using |fetch*|_ methods.
.. method:: executemany(query, vars_list) .. method:: executemany(operation, seq_of_parameters)
Execute a database operation (query or command) against all parameter Prepare a database operation (query or command) and then execute it
tuples or mappings found in the sequence *vars_list*. against all parameter tuples or mappings found in the sequence
`seq_of_parameters`.
The function is mostly useful for commands that update the database: The function is mostly useful for commands that update the database:
any result set returned by the query is discarded. any result set returned by the query is discarded.
Parameters are bounded to the query using the same rules described in Parameters are bounded to the query using the same rules described in
the `~cursor.execute()` method. the `~cursor.execute()` method.
.. code:: python
>>> nums = ((1,), (5,), (10,))
>>> cur.executemany("INSERT INTO test (num) VALUES (%s)", nums)
>>> tuples = ((123, "foo"), (42, "bar"), (23, "baz"))
>>> cur.executemany("INSERT INTO test (num, data) VALUES (%s, %s)", tuples)
.. warning::
In its current implementation this method is not faster than
executing `~cursor.execute()` in a loop. For better performance
you can use the functions described in :ref:`fast-exec`.
.. method:: callproc(procname [, parameters]) .. method:: callproc(procname [, parameters])
Call a stored database procedure with the given name. The sequence of Call a stored database procedure with the given name. The sequence of
parameters must contain one entry for each argument that the procedure parameters must contain one entry for each argument that the procedure
expects. Overloaded procedures are supported. Named parameters can be expects. The result of the call is returned as modified copy of the
used by supplying the parameters as a dictionary. input sequence. Input parameters are left untouched, output and
input/output parameters replaced with possibly new values.
The procedure may also provide a result set as output. This must then
be made available through the standard |fetch*|_ methods.
This function is, at present, not DBAPI-compliant. The return value is
supposed to consist of the sequence of parameters with modified output
and input/output parameters. In future versions, the DBAPI-compliant
return value may be implemented, but for now the function returns None.
The procedure may provide a result set as output. This is then made
available through the standard |fetch*|_ methods.
.. versionchanged:: 2.7
added support for named arguments.
.. note::
`!callproc()` can only be used with PostgreSQL functions__, not
with the procedures__ introduced in PostgreSQL 11, which require
the :sql:`CALL` statement to run. Please use a normal
`execute()` to run them.
.. __: https://www.postgresql.org/docs/current/sql-createfunction.html
.. __: https://www.postgresql.org/docs/current/sql-createprocedure.html
.. method:: mogrify(operation [, parameters]) .. method:: mogrify(operation [, parameters])
@ -256,8 +166,6 @@ The ``cursor`` class
exactly the one that would be sent to the database running the exactly the one that would be sent to the database running the
`~cursor.execute()` method or similar. `~cursor.execute()` method or similar.
The returned string is always a bytes string.
>>> cur.mogrify("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar')) >>> cur.mogrify("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar'))
"INSERT INTO test (num, data) VALUES (42, E'bar')" "INSERT INTO test (num, data) VALUES (42, E'bar')"
@ -266,7 +174,7 @@ The ``cursor`` class
The `mogrify()` method is a Psycopg extension to the |DBAPI|. The `mogrify()` method is a Psycopg extension to the |DBAPI|.
.. method:: setinputsizes(sizes) .. method:: setinputsizes(sizes)
This method is exposed in compliance with the |DBAPI|. It currently This method is exposed in compliance with the |DBAPI|. It currently
does nothing but it is safe to call it. does nothing but it is safe to call it.
@ -292,7 +200,7 @@ The ``cursor`` class
>>> cur.execute("SELECT * FROM test;") >>> cur.execute("SELECT * FROM test;")
>>> for record in cur: >>> for record in cur:
... print(record) ... print record
... ...
(1, 100, "abc'def") (1, 100, "abc'def")
(2, None, 'dada') (2, None, 'dada')
@ -312,17 +220,17 @@ The ``cursor`` class
>>> cur.execute("SELECT * FROM test WHERE id = %s", (3,)) >>> cur.execute("SELECT * FROM test WHERE id = %s", (3,))
>>> cur.fetchone() >>> cur.fetchone()
(3, 42, 'bar') (3, 42, 'bar')
A `~psycopg2.ProgrammingError` is raised if the previous call A `~psycopg2.ProgrammingError` is raised if the previous call
to |execute*|_ did not produce any result set or no call was issued to |execute*|_ did not produce any result set or no call was issued
yet. yet.
.. method:: fetchmany([size=cursor.arraysize]) .. method:: fetchmany([size=cursor.arraysize])
Fetch the next set of rows of a query result, returning a list of Fetch the next set of rows of a query result, returning a list of
tuples. An empty list is returned when no more rows are available. tuples. An empty list is returned when no more rows are available.
The number of rows to fetch per call is specified by the parameter. The number of rows to fetch per call is specified by the parameter.
If it is not given, the cursor's `~cursor.arraysize` determines If it is not given, the cursor's `~cursor.arraysize` determines
the number of rows to be fetched. The method should try to fetch as the number of rows to be fetched. The method should try to fetch as
@ -340,7 +248,7 @@ The ``cursor`` class
A `~psycopg2.ProgrammingError` is raised if the previous call to A `~psycopg2.ProgrammingError` is raised if the previous call to
|execute*|_ did not produce any result set or no call was issued yet. |execute*|_ did not produce any result set or no call was issued yet.
Note there are performance considerations involved with the size Note there are performance considerations involved with the size
parameter. For optimal performance, it is usually best to use the parameter. For optimal performance, it is usually best to use the
`~cursor.arraysize` attribute. If the size parameter is used, `~cursor.arraysize` attribute. If the size parameter is used,
@ -375,7 +283,10 @@ The ``cursor`` class
`~psycopg2.ProgrammingError` is raised and the cursor position is `~psycopg2.ProgrammingError` is raised and the cursor position is
not changed. not changed.
.. note:: The method can be used both for client-side cursors and
:ref:`server-side cursors <server-side-cursors>`.
.. note::
According to the |DBAPI|_, the exception raised for a cursor out According to the |DBAPI|_, the exception raised for a cursor out
of bound should have been `!IndexError`. The best option is of bound should have been `!IndexError`. The best option is
@ -386,16 +297,9 @@ The ``cursor`` class
except (ProgrammingError, IndexError), exc: except (ProgrammingError, IndexError), exc:
deal_with_it(exc) deal_with_it(exc)
The method can be used both for client-side cursors and
:ref:`server-side cursors <server-side-cursors>`. Server-side cursors
can usually scroll backwards only if declared `~cursor.scrollable`.
Moving out-of-bound in a server-side cursor doesn't result in an
exception, if the backend doesn't raise any (Postgres doesn't tell us
in a reliable way if we went out of bound).
.. attribute:: arraysize .. attribute:: arraysize
This read/write attribute specifies the number of rows to fetch at a This read/write attribute specifies the number of rows to fetch at a
time with `~cursor.fetchmany()`. It defaults to 1 meaning to fetch time with `~cursor.fetchmany()`. It defaults to 1 meaning to fetch
a single row at a time. a single row at a time.
@ -409,20 +313,20 @@ The ``cursor`` class
default is 2000. default is 2000.
.. versionadded:: 2.4 .. versionadded:: 2.4
.. extension:: .. extension::
The `itersize` attribute is a Psycopg extension to the |DBAPI|. The `itersize` attribute is a Psycopg extension to the |DBAPI|.
.. attribute:: rowcount .. attribute:: rowcount
This read-only attribute specifies the number of rows that the last This read-only attribute specifies the number of rows that the last
|execute*|_ produced (for :abbr:`DQL (Data Query Language)` statements |execute*|_ produced (for :abbr:`DQL (Data Query Language)` statements
like :sql:`SELECT`) or affected (for like :sql:`SELECT`) or affected (for
:abbr:`DML (Data Manipulation Language)` statements like :sql:`UPDATE` :abbr:`DML (Data Manipulation Language)` statements like :sql:`UPDATE`
or :sql:`INSERT`). or :sql:`INSERT`).
The attribute is -1 in case no |execute*| has been performed on The attribute is -1 in case no |execute*| has been performed on
the cursor or the row count of the last operation if it can't be the cursor or the row count of the last operation if it can't be
determined by the interface. determined by the interface.
@ -431,7 +335,7 @@ The ``cursor`` class
The |DBAPI|_ interface reserves to redefine the latter case to The |DBAPI|_ interface reserves to redefine the latter case to
have the object return `!None` instead of -1 in future versions have the object return `!None` instead of -1 in future versions
of the specification. of the specification.
.. attribute:: rownumber .. attribute:: rownumber
@ -461,20 +365,20 @@ The ``cursor`` class
more flexibility. more flexibility.
.. |CREATE-TABLE| replace:: :sql:`CREATE TABLE` .. |CREATE-TABLE| replace:: :sql:`CREATE TABLE`
.. __: https://www.postgresql.org/docs/current/static/sql-createtable.html .. __: http://www.postgresql.org/docs/9.0/static/sql-createtable.html
.. |INSERT-RETURNING| replace:: :sql:`INSERT ... RETURNING` .. |INSERT-RETURNING| replace:: :sql:`INSERT ... RETURNING`
.. __: https://www.postgresql.org/docs/current/static/sql-insert.html .. __: http://www.postgresql.org/docs/9.0/static/sql-insert.html
.. attribute:: query .. attribute:: query
Read-only attribute containing the body of the last query sent to the Read-only attribute containing the body of the last query sent to the
backend (including bound arguments) as bytes string. `!None` if no backend (including bound arguments). `!None` if no query has been
query has been executed yet: executed yet:
>>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar')) >>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar'))
>>> cur.query >>> cur.query
"INSERT INTO test (num, data) VALUES (42, E'bar')" "INSERT INTO test (num, data) VALUES (42, E'bar')"
.. extension:: .. extension::
@ -488,7 +392,7 @@ The ``cursor`` class
command: command:
>>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar')) >>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar'))
>>> cur.statusmessage >>> cur.statusmessage
'INSERT 0 1' 'INSERT 0 1'
.. extension:: .. extension::
@ -516,20 +420,18 @@ The ``cursor`` class
The time zone factory used to handle data types such as The time zone factory used to handle data types such as
:sql:`TIMESTAMP WITH TIME ZONE`. It should be a `~datetime.tzinfo` :sql:`TIMESTAMP WITH TIME ZONE`. It should be a `~datetime.tzinfo`
object. Default is `datetime.timezone`. object. A few implementations are available in the `psycopg2.tz`
module.
.. versionchanged:: 2.9
previosly the default factory was `psycopg2.tz.FixedOffsetTimezone`.
.. method:: nextset() .. method:: nextset()
This method is not supported (PostgreSQL does not have multiple data This method is not supported (PostgreSQL does not have multiple data
sets) and will raise a `~psycopg2.NotSupportedError` exception. sets) and will raise a `~psycopg2.NotSupportedError` exception.
.. method:: setoutputsize(size [, column]) .. method:: setoutputsize(size [, column])
This method is exposed in compliance with the |DBAPI|. It currently This method is exposed in compliance with the |DBAPI|. It currently
does nothing but it is safe to call it. does nothing but it is safe to call it.
@ -537,32 +439,25 @@ The ``cursor`` class
.. rubric:: COPY-related methods .. rubric:: COPY-related methods
Efficiently copy data from file-like objects to the database and back. See
:ref:`copy` for an overview.
.. extension:: .. extension::
The :sql:`COPY` command is a PostgreSQL extension to the SQL standard. The :sql:`COPY` command is a PostgreSQL extension to the SQL standard.
As such, its support is a Psycopg extension to the |DBAPI|. As such, its support is a Psycopg extension to the |DBAPI|.
.. method:: copy_from(file, table, sep='\\t', null='\\\\N', size=8192, columns=None) .. method:: copy_from(file, table, sep='\\t', null='\\N', columns=None)
Read data *from* the file-like object *file* appending them to Read data *from* the file-like object *file* appending them to
the table named *table*. the table named *table*. *file* must have both
`!read()` and `!readline()` method. See :ref:`copy` for an
overview.
:param file: file-like object to read data from. It must have both The optional argument *sep* is the columns separator and
`!read()` and `!readline()` methods. *null* represents :sql:`NULL` values in the file.
:param table: name of the table to copy data into.
:param sep: columns separator expected in the file. Defaults to a tab.
:param null: textual representation of :sql:`NULL` in the file.
The default is the two characters string ``\N``.
:param size: size of the buffer used to read from the file.
:param columns: iterable with name of the columns to import.
The length and types should match the content of the file to read.
If not specified, it is assumed that the entire table matches the
file structure.
Example:: The *columns* argument is a sequence containing the name of the
fields where the read data will be entered. Its length and column
type should match the content of the read file. If not specifies, it
is assumed that the entire table matches the file structure.
>>> f = StringIO("42\tfoo\n74\tbar\n") >>> f = StringIO("42\tfoo\n74\tbar\n")
>>> cur.copy_from(f, 'test', columns=('num', 'data')) >>> cur.copy_from(f, 'test', columns=('num', 'data'))
@ -578,26 +473,17 @@ The ``cursor`` class
are encoded in the connection `~connection.encoding` when sent to are encoded in the connection `~connection.encoding` when sent to
the backend. the backend.
.. versionchanged:: 2.9 .. method:: copy_to(file, table, sep='\\t', null='\\N', columns=None)
the table and fields names are now quoted. If you need to specify
a schema-qualified table please use `copy_expert()`.
.. method:: copy_to(file, table, sep='\\t', null='\\\\N', columns=None)
Write the content of the table named *table* *to* the file-like Write the content of the table named *table* *to* the file-like
object *file*. See :ref:`copy` for an overview. object *file*. *file* must have a `!write()` method.
See :ref:`copy` for an overview.
:param file: file-like object to write data into. It must have a The optional argument *sep* is the columns separator and
`!write()` method. *null* represents :sql:`NULL` values in the file.
:param table: name of the table to copy data from.
:param sep: columns separator expected in the file. Defaults to a tab.
:param null: textual representation of :sql:`NULL` in the file.
The default is the two characters string ``\N``.
:param columns: iterable with name of the columns to export.
If not specified, export all the columns.
Example:: The *columns* argument is a sequence of field names: if not
`!None` only the specified fields will be included in the dump.
>>> cur.copy_to(sys.stdout, 'test', sep="|") >>> cur.copy_to(sys.stdout, 'test', sep="|")
1|100|abc'def 1|100|abc'def
@ -612,35 +498,18 @@ The ``cursor`` class
are decoded in the connection `~connection.encoding` when read are decoded in the connection `~connection.encoding` when read
from the backend. from the backend.
.. versionchanged:: 2.9
the table and fields names are now quoted. If you need to specify
a schema-qualified table please use `copy_expert()`.
.. method:: copy_expert(sql, file [, size])
.. method:: copy_expert(sql, file, size=8192)
Submit a user-composed :sql:`COPY` statement. The method is useful to Submit a user-composed :sql:`COPY` statement. The method is useful to
handle all the parameters that PostgreSQL makes available (see handle all the parameters that PostgreSQL makes available (see
|COPY|__ command documentation). |COPY|__ command documentation).
:param sql: the :sql:`COPY` statement to execute. *file* must be an open, readable file for :sql:`COPY FROM` or an
:param file: a file-like object to read or write (according to *sql*). open, writeable file for :sql:`COPY TO`. The optional *size*
:param size: size of the read buffer to be used in :sql:`COPY FROM`. argument, when specified for a :sql:`COPY FROM` statement, will be
passed to *file*\ 's read method to control the read buffer
The *sql* statement should be in the form :samp:`COPY {table} TO size.
STDOUT` to export :samp:`{table}` to the *file* object passed as
argument or :samp:`COPY {table} FROM STDIN` to import the content of
the *file* object into :samp:`{table}`. If you need to compose a
:sql:`COPY` statement dynamically (because table, fields, or query
parameters are in Python variables) you may use the objects provided
by the `psycopg2.sql` module.
*file* must be a readable file-like object (as required by
`~cursor.copy_from()`) for *sql* statement :sql:`COPY ... FROM STDIN`
or a writable one (as required by `~cursor.copy_to()`) for :sql:`COPY
... TO STDOUT`.
Example:
>>> cur.copy_expert("COPY test TO STDOUT WITH CSV HEADER", sys.stdout) >>> cur.copy_expert("COPY test TO STDOUT WITH CSV HEADER", sys.stdout)
id,num,data id,num,data
@ -649,7 +518,7 @@ The ``cursor`` class
... ...
.. |COPY| replace:: :sql:`COPY` .. |COPY| replace:: :sql:`COPY`
.. __: https://www.postgresql.org/docs/current/static/sql-copy.html .. __: http://www.postgresql.org/docs/9.0/static/sql-copy.html
.. versionadded:: 2.0.6 .. versionadded:: 2.0.6
@ -658,24 +527,6 @@ The ``cursor`` class
using Unicode data instead of bytes. using Unicode data instead of bytes.
.. rubric:: Interoperation with other C API modules
.. attribute:: pgresult_ptr
Return the cursor's internal `!PGresult*` as integer. Useful to pass
the libpq raw result structure to C functions, e.g. via `ctypes`::
>>> import ctypes
>>> libpq = ctypes.pydll.LoadLibrary(ctypes.util.find_library('pq'))
>>> libpq.PQcmdStatus.argtypes = [ctypes.c_void_p]
>>> libpq.PQcmdStatus.restype = ctypes.c_char_p
>>> curs.execute("select 'x'")
>>> libpq.PQcmdStatus(curs.pgresult_ptr)
b'SELECT 1'
.. versionadded:: 2.8
.. testcode:: .. testcode::
:hide: :hide:

View File

@ -39,7 +39,7 @@ From PostgreSQL documentation:
.. seealso:: `PostgreSQL Error Codes table`__ .. seealso:: `PostgreSQL Error Codes table`__
.. __: https://www.postgresql.org/docs/current/static/errcodes-appendix.html#ERRCODES-TABLE .. __: http://www.postgresql.org/docs/9.0/static/errcodes-appendix.html#ERRCODES-TABLE
An example of the available constants defined in the module: An example of the available constants defined in the module:
@ -49,8 +49,8 @@ An example of the available constants defined in the module:
>>> errorcodes.UNDEFINED_TABLE >>> errorcodes.UNDEFINED_TABLE
'42P01' '42P01'
Constants representing all the error values defined by PostgreSQL versions Constants representing all the error values documented by PostgreSQL versions
between 8.1 and 15 are included in the module. between 8.1 and 9.0 are included in the module.
.. autofunction:: lookup(code) .. autofunction:: lookup(code)
@ -59,7 +59,7 @@ between 8.1 and 15 are included in the module.
>>> try: >>> try:
... cur.execute("SELECT ouch FROM aargh;") ... cur.execute("SELECT ouch FROM aargh;")
... except Exception as e: ... except Exception, e:
... pass ... pass
... ...
>>> errorcodes.lookup(e.pgcode[:2]) >>> errorcodes.lookup(e.pgcode[:2])

View File

@ -1,89 +0,0 @@
`psycopg2.errors` -- Exception classes mapping PostgreSQL errors
================================================================
.. sectionauthor:: Daniele Varrazzo <daniele.varrazzo@gmail.com>
.. index::
single: Error; Class
.. module:: psycopg2.errors
.. versionadded:: 2.8
.. versionchanged:: 2.8.4 added errors introduced in PostgreSQL 12
.. versionchanged:: 2.8.6 added errors introduced in PostgreSQL 13
.. versionchanged:: 2.9.2 added errors introduced in PostgreSQL 14
.. versionchanged:: 2.9.4 added errors introduced in PostgreSQL 15
.. versionchanged:: 2.9.10 added errors introduced in PostgreSQL 17
This module exposes the classes psycopg raises upon receiving an error from
the database with a :sql:`SQLSTATE` value attached (available in the
`~psycopg2.Error.pgcode` attribute). The content of the module is generated
from the PostgreSQL source code and includes classes for every error defined
by PostgreSQL in versions between 9.1 and 15.
Every class in the module is named after what referred as "condition name" `in
the documentation`__, converted to CamelCase: e.g. the error 22012,
``division_by_zero`` is exposed by this module as the class `!DivisionByZero`.
.. __: https://www.postgresql.org/docs/current/static/errcodes-appendix.html#ERRCODES-TABLE
Every exception class is a subclass of one of the :ref:`standard DB-API
exception <dbapi-exceptions>` and expose the `~psycopg2.Error` interface.
Each class' superclass is what used to be raised by psycopg in versions before
the introduction of this module, so everything should be compatible with
previously written code catching one the DB-API class: if your code used to
catch `!IntegrityError` to detect a duplicate entry, it will keep on working
even if a more specialised subclass such as `UniqueViolation` is raised.
The new classes allow a more idiomatic way to check and process a specific
error among the many the database may return. For instance, in order to check
that a table is locked, the following code could have been used previously:
.. code-block:: python
try:
cur.execute("LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE NOWAIT")
except psycopg2.OperationalError as e:
if e.pgcode == psycopg2.errorcodes.LOCK_NOT_AVAILABLE:
locked = True
else:
raise
While this method is still available, the specialised class allows for a more
idiomatic error handler:
.. code-block:: python
try:
cur.execute("LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE NOWAIT")
except psycopg2.errors.LockNotAvailable:
locked = True
.. autofunction:: lookup
.. code-block:: python
try:
cur.execute("LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE NOWAIT")
except psycopg2.errors.lookup("55P03"):
locked = True
SQLSTATE exception classes
--------------------------
The following table contains the list of all the SQLSTATE classes exposed by
the module.
Note that, for completeness, the module also exposes all the
:ref:`DB-API-defined exceptions <dbapi-exceptions>` and :ref:`a few
psycopg-specific ones <extension-exceptions>` exposed by the `!extensions`
module, which are not listed here.
.. include:: sqlstate_errors.rst

View File

@ -12,14 +12,8 @@
The module contains a few objects and function extending the minimum set of The module contains a few objects and function extending the minimum set of
functionalities defined by the |DBAPI|_. functionalities defined by the |DBAPI|_.
Classes definitions
-------------------
Instances of these classes are usually returned by factory functions or .. class:: connection
attributes. Their definitions are exposed here to allow subclassing,
introspection etc.
.. class:: connection(dsn, async=False)
Is the class usually returned by the `~psycopg2.connect()` function. Is the class usually returned by the `~psycopg2.connect()` function.
It is exposed by the `extensions` module in order to allow It is exposed by the `extensions` module in order to allow
@ -27,14 +21,13 @@ introspection etc.
`!connect()` function using the `connection_factory` parameter. `!connect()` function using the `connection_factory` parameter.
See also :ref:`subclassing-connection`. See also :ref:`subclassing-connection`.
Subclasses should have constructor signature :samp:`({dsn}, {async}=0)`.
For a complete description of the class, see `connection`. For a complete description of the class, see `connection`.
.. versionchanged:: 2.7 .. class:: cursor
*async_* can be used as alias for *async*.
.. class:: cursor(conn, name=None) It is the class usually returnded by the `connection.cursor()`
It is the class usually returned by the `connection.cursor()`
method. It is exposed by the `extensions` module in order to allow method. It is exposed by the `extensions` module in order to allow
subclassing to extend its behaviour: the subclass should be passed to the subclassing to extend its behaviour: the subclass should be passed to the
`!cursor()` method using the `cursor_factory` parameter. See `!cursor()` method using the `cursor_factory` parameter. See
@ -42,7 +35,6 @@ introspection etc.
For a complete description of the class, see `cursor`. For a complete description of the class, see `cursor`.
.. class:: lobject(conn [, oid [, mode [, new_oid [, new_file ]]]]) .. class:: lobject(conn [, oid [, mode [, new_oid [, new_file ]]]])
Wrapper for a PostgreSQL large object. See :ref:`large-objects` for an Wrapper for a PostgreSQL large object. See :ref:`large-objects` for an
@ -50,20 +42,18 @@ introspection etc.
The class can be subclassed: see the `connection.lobject()` to know The class can be subclassed: see the `connection.lobject()` to know
how to specify a `!lobject` subclass. how to specify a `!lobject` subclass.
.. versionadded:: 2.0.8 .. versionadded:: 2.0.8
.. attribute:: oid .. attribute:: oid
Database OID of the object. Database OID of the object.
.. attribute:: mode .. attribute:: mode
The mode the database was open. See `connection.lobject()` for a The mode the database was open. See `connection.lobject()` for a
description of the available modes. description of the available modes.
.. method:: read(bytes=-1) .. method:: read(bytes=-1)
Read a chunk of data from the current file position. If -1 (default) Read a chunk of data from the current file position. If -1 (default)
@ -76,7 +66,6 @@ introspection etc.
.. versionchanged:: 2.4 .. versionchanged:: 2.4
added Unicode support. added Unicode support.
.. method:: write(str) .. method:: write(str)
Write a string to the large object. Return the number of bytes Write a string to the large object. Return the number of bytes
@ -86,60 +75,35 @@ introspection etc.
.. versionchanged:: 2.4 .. versionchanged:: 2.4
added Unicode support. added Unicode support.
.. method:: export(file_name) .. method:: export(file_name)
Export the large object content to the file system. Export the large object content to the file system.
The method uses the efficient |lo_export|_ libpq function. The method uses the efficient |lo_export|_ libpq function.
.. |lo_export| replace:: `!lo_export()` .. |lo_export| replace:: `!lo_export()`
.. _lo_export: https://www.postgresql.org/docs/current/static/lo-interfaces.html#LO-EXPORT .. _lo_export: http://www.postgresql.org/docs/9.0/static/lo-interfaces.html#LO-EXPORT
.. method:: seek(offset, whence=0) .. method:: seek(offset, whence=0)
Set the lobject current position. Set the lobject current position.
.. versionchanged:: 2.6
added support for *offset* > 2GB.
.. method:: tell() .. method:: tell()
Return the lobject current position. Return the lobject current position.
.. versionadded:: 2.2
.. versionchanged:: 2.6
added support for return value > 2GB.
.. method:: truncate(len=0) .. method:: truncate(len=0)
.. versionadded:: 2.2.0
Truncate the lobject to the given size. Truncate the lobject to the given size.
The method will only be available if Psycopg has been built against The method will only be available if Psycopg has been built against libpq
libpq from PostgreSQL 8.3 or later and can only be used with from PostgreSQL 8.3 or later and can only be used with PostgreSQL servers
PostgreSQL servers running these versions. It uses the |lo_truncate|_ running these versions. It uses the |lo_truncate|_ libpq function.
libpq function.
.. |lo_truncate| replace:: `!lo_truncate()` .. |lo_truncate| replace:: `!lo_truncate()`
.. _lo_truncate: https://www.postgresql.org/docs/current/static/lo-interfaces.html#LO-TRUNCATE .. _lo_truncate: http://www.postgresql.org/docs/9.0/static/lo-interfaces.html#LO-TRUNCATE
.. versionadded:: 2.2
.. versionchanged:: 2.6
added support for *len* > 2GB.
.. warning::
If Psycopg is built with |lo_truncate| support or with the 64 bits API
support (resp. from PostgreSQL versions 8.3 and 9.3) but at runtime an
older version of the dynamic library is found, the ``psycopg2`` module
will fail to import. See :ref:`the lo_truncate FAQ <faq-lo_truncate>`
about the problem.
.. method:: close() .. method:: close()
@ -154,130 +118,6 @@ introspection etc.
Close the object and remove it from the database. Close the object and remove it from the database.
.. autoclass:: ConnectionInfo(connection)
.. versionadded:: 2.8
.. autoattribute:: dbname
.. autoattribute:: user
.. autoattribute:: password
.. autoattribute:: host
.. autoattribute:: port
.. autoattribute:: options
.. autoattribute:: dsn_parameters
Example::
>>> conn.info.dsn_parameters
{'dbname': 'test', 'user': 'postgres', 'port': '5432', 'sslmode': 'prefer'}
Requires libpq >= 9.3.
.. autoattribute:: status
.. autoattribute:: transaction_status
.. automethod:: parameter_status(name)
.. autoattribute:: protocol_version
Currently Psycopg supports only protocol 3, which allows connection
to PostgreSQL server from version 7.4. Psycopg versions previous than
2.3 support both protocols 2 and 3.
.. autoattribute:: server_version
The number is formed by converting the major, minor, and revision
numbers into two-decimal-digit numbers and appending them together.
After PostgreSQL 10 the minor version was dropped, so the second group
of digits is always ``00``. For example, version 9.3.5 will be
returned as ``90305``, version 10.2 as ``100002``.
.. autoattribute:: error_message
.. autoattribute:: socket
.. autoattribute:: backend_pid
.. autoattribute:: needs_password
.. autoattribute:: used_password
.. autoattribute:: ssl_in_use
.. automethod:: ssl_attribute(name)
.. autoattribute:: ssl_attribute_names
.. class:: Column(\*args, \*\*kwargs)
Description of one result column, exposed as items of the
`cursor.description` sequence.
.. versionadded:: 2.8
in previous version the `!description` attribute was a sequence of
simple tuples or namedtuples.
.. attribute:: name
The name of the column returned.
.. attribute:: type_code
The PostgreSQL OID of the column. You can use the |pg_type|_ system
table to get more informations about the type. This is the value used
by Psycopg to decide what Python type use to represent the value. See
also :ref:`type-casting-from-sql-to-python`.
.. attribute:: display_size
Supposed to be the actual length of the column in bytes. Obtaining
this value is computationally intensive, so it is always `!None`.
.. versionchanged:: 2.8
It was previously possible to obtain this value using a compiler
flag at builtin.
.. attribute:: internal_size
The size in bytes of the column associated to this column on the
server. Set to a negative value for variable-size types See also
PQfsize_.
.. attribute:: precision
Total number of significant digits in columns of type |NUMERIC|_.
`!None` for other types.
.. attribute:: scale
Count of decimal digits in the fractional part in columns of type
|NUMERIC|. `!None` for other types.
.. attribute:: null_ok
Always `!None` as not easy to retrieve from the libpq.
.. attribute:: table_oid
The oid of the table from which the column was fetched (matching
:sql:`pg_class.oid`). `!None` if the column is not a simple reference
to a table column. See also PQftable_.
.. versionadded:: 2.8
.. attribute:: table_column
The number of the column (within its table) making up the result
(matching :sql:`pg_attribute.attnum`, so it will start from 1).
`!None` if the column is not a simple reference to a table column. See
also PQftablecol_.
.. versionadded:: 2.8
.. |pg_type| replace:: :sql:`pg_type`
.. _pg_type: https://www.postgresql.org/docs/current/static/catalog-pg-type.html
.. _PQgetlength: https://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQGETLENGTH
.. _PQfsize: https://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQFSIZE
.. _PQftable: https://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQFTABLE
.. _PQftablecol: https://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQFTABLECOL
.. _NUMERIC: https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL
.. |NUMERIC| replace:: :sql:`NUMERIC`
.. autoclass:: Notify(pid, channel, payload='') .. autoclass:: Notify(pid, channel, payload='')
:members: pid, channel, payload :members: pid, channel, payload
@ -292,40 +132,13 @@ introspection etc.
.. automethod:: from_string(s) .. automethod:: from_string(s)
.. autoclass:: Diagnostics(exception) .. autofunction:: set_wait_callback(f)
.. versionadded:: 2.5 .. versionadded:: 2.2.0
The attributes currently available are: .. autofunction:: get_wait_callback()
.. attribute::
column_name
constraint_name
context
datatype_name
internal_position
internal_query
message_detail
message_hint
message_primary
schema_name
severity
severity_nonlocalized
source_file
source_function
source_line
sqlstate
statement_position
table_name
A string with the error field if available; `!None` if not available.
The attribute value is available only if the error sent by the server:
not all the fields are available for all the errors and for all the
server versions.
.. versionadded:: 2.8
The `!severity_nonlocalized` attribute.
.. versionadded:: 2.2.0
.. _sql-adaptation-objects: .. _sql-adaptation-objects:
@ -340,7 +153,7 @@ deal with Python objects adaptation:
.. function:: adapt(obj) .. function:: adapt(obj)
Return the SQL representation of *obj* as an `ISQLQuote`. Raise a Return the SQL representation of *obj* as a string. Raise a
`~psycopg2.ProgrammingError` if how to adapt the object is unknown. `~psycopg2.ProgrammingError` if how to adapt the object is unknown.
In order to allow new objects to be adapted, register a new adapter for it In order to allow new objects to be adapted, register a new adapter for it
using the `register_adapter()` function. using the `register_adapter()` function.
@ -354,7 +167,7 @@ deal with Python objects adaptation:
Register a new adapter for the objects of class *class*. Register a new adapter for the objects of class *class*.
*adapter* should be a function taking a single argument (the object *adapter* should be a function taking a single argument (the object
to adapt) and returning an object conforming to the `ISQLQuote` to adapt) and returning an object conforming the `ISQLQuote`
protocol (e.g. exposing a `!getquoted()` method). The `AsIs` is protocol (e.g. exposing a `!getquoted()` method). The `AsIs` is
often useful for this task. often useful for this task.
@ -413,9 +226,9 @@ deal with Python objects adaptation:
.. method:: getquoted() .. method:: getquoted()
Return the string enclosed in single quotes. Any single quote appearing Return the string enclosed in single quotes. Any single quote
in the string is escaped by doubling it according to SQL string appearing in the the string is escaped by doubling it according to SQL
constants syntax. Backslashes are escaped too. string constants syntax. Backslashes are escaped too.
>>> QuotedString(r"O'Reilly").getquoted() >>> QuotedString(r"O'Reilly").getquoted()
"'O''Reilly'" "'O''Reilly'"
@ -453,6 +266,13 @@ deal with Python objects adaptation:
Specialized adapters for Python datetime objects. Specialized adapters for Python datetime objects.
.. class:: DateFromMx
TimeFromMx
TimestampFromMx
IntervalFromMx
Specialized adapters for `mx.DateTime`_ objects.
.. data:: adapters .. data:: adapters
Dictionary of the currently registered object adapters. Use Dictionary of the currently registered object adapters. Use
@ -470,7 +290,7 @@ details.
.. function:: new_type(oids, name, adapter) .. function:: new_type(oids, name, adapter)
Create a new type caster to convert from a PostgreSQL type to a Python Create a new type caster to convert from a PostgreSQL type to a Python
object. The object created must be registered using object. The created object must be registered using
`register_type()` to be used. `register_type()` to be used.
:param oids: tuple of OIDs of the PostgreSQL type to convert. :param oids: tuple of OIDs of the PostgreSQL type to convert.
@ -489,38 +309,6 @@ details.
See :ref:`type-casting-from-sql-to-python` for an usage example. See :ref:`type-casting-from-sql-to-python` for an usage example.
.. function:: new_array_type(oids, name, base_caster)
Create a new type caster to convert from a PostgreSQL array type to a list
of Python object. The object created must be registered using
`register_type()` to be used.
:param oids: tuple of OIDs of the PostgreSQL type to convert. It should
probably contain the oid of the array type (e.g. the ``typarray``
field in the ``pg_type`` table).
:param name: the name of the new type adapter.
:param base_caster: a Psycopg typecaster, e.g. created using the
`new_type()` function. The caster should be able to parse a single
item of the desired type.
.. versionadded:: 2.4.3
.. _cast-array-unknown:
.. note::
The function can be used to create a generic array typecaster,
returning a list of strings: just use `psycopg2.STRING` as base
typecaster. For instance, if you want to receive an array of
:sql:`macaddr` from the database, each address represented by string,
you can use::
# select typarray from pg_type where typname = 'macaddr' -> 1040
psycopg2.extensions.register_type(
psycopg2.extensions.new_array_type(
(1040,), 'MACADDR[]', psycopg2.STRING))
.. function:: register_type(obj [, scope]) .. function:: register_type(obj [, scope])
Register a type caster created using `new_type()`. Register a type caster created using `new_type()`.
@ -540,31 +328,24 @@ details.
.. data:: encodings .. data:: encodings
Mapping from `PostgreSQL encoding`__ to `Python encoding`__ names. Mapping from `PostgreSQL encoding`__ names to `Python codec`__ names.
Used by Psycopg when adapting or casting unicode strings. See Used by Psycopg when adapting or casting unicode strings. See
:ref:`unicode-handling`. :ref:`unicode-handling`.
.. __: https://www.postgresql.org/docs/current/static/multibyte.html .. __: http://www.postgresql.org/docs/9.0/static/multibyte.html
.. __: https://docs.python.org/library/codecs.html#standard-encodings .. __: http://docs.python.org/library/codecs.html#standard-encodings
.. index:: .. index::
single: Exceptions; Additional single: Exceptions; Additional
.. _extension-exceptions:
Additional exceptions Additional exceptions
--------------------- ---------------------
The module exports a few exceptions in addition to the :ref:`standard ones The module exports a few exceptions in addition to the :ref:`standard ones
<dbapi-exceptions>` defined by the |DBAPI|_. <dbapi-exceptions>` defined by the |DBAPI|_.
.. note::
From psycopg 2.8 these error classes are also exposed by the
`psycopg2.errors` module.
.. exception:: QueryCanceledError .. exception:: QueryCanceledError
(subclasses `~psycopg2.OperationalError`) (subclasses `~psycopg2.OperationalError`)
@ -579,143 +360,13 @@ The module exports a few exceptions in addition to the :ref:`standard ones
(subclasses `~psycopg2.OperationalError`) (subclasses `~psycopg2.OperationalError`)
Error causing transaction rollback (deadlocks, serialization failures, Error causing transaction rollback (deadlocks, serialisation failures,
etc). It can be trapped specifically to detect a deadlock. etc). It can be trapped specifically to detect a deadlock.
.. versionadded:: 2.0.7 .. versionadded:: 2.0.7
.. _coroutines-functions:
Coroutines support functions
----------------------------
These functions are used to set and retrieve the callback function for
:ref:`cooperation with coroutine libraries <green-support>`.
.. versionadded:: 2.2
.. autofunction:: set_wait_callback(f)
.. autofunction:: get_wait_callback()
Other functions
---------------
.. function:: libpq_version()
Return the version number of the ``libpq`` dynamic library loaded as an
integer, in the same format of `~connection.server_version`.
Raise `~psycopg2.NotSupportedError` if the ``psycopg2`` module was
compiled with a ``libpq`` version lesser than 9.1 (which can be detected
by the `~psycopg2.__libpq_version__` constant).
.. versionadded:: 2.7
.. seealso:: libpq docs for `PQlibVersion()`__.
.. __: https://www.postgresql.org/docs/current/static/libpq-misc.html#LIBPQ-PQLIBVERSION
.. function:: make_dsn(dsn=None, \*\*kwargs)
Create a valid connection string from arguments.
Put together the arguments in *kwargs* into a connection string. If *dsn*
is specified too, merge the arguments coming from both the sources. If the
same argument name is specified in both the sources, the *kwargs* value
overrides the *dsn* value.
The input arguments are validated: the output should always be a valid
connection string (as far as `parse_dsn()` is concerned). If not raise
`~psycopg2.ProgrammingError`.
Example::
>>> from psycopg2.extensions import make_dsn
>>> make_dsn('dbname=foo host=example.com', password="s3cr3t")
'host=example.com password=s3cr3t dbname=foo'
.. versionadded:: 2.7
.. function:: parse_dsn(dsn)
Parse connection string into a dictionary of keywords and values.
Parsing is delegated to the libpq: different versions of the client
library may support different formats or parameters (for example,
`connection URIs`__ are only supported from libpq 9.2). Raise
`~psycopg2.ProgrammingError` if the *dsn* is not valid.
.. __: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
Example::
>>> from psycopg2.extensions import parse_dsn
>>> parse_dsn('dbname=test user=postgres password=secret')
{'password': 'secret', 'user': 'postgres', 'dbname': 'test'}
>>> parse_dsn("postgresql://someone@example.com/somedb?connect_timeout=10")
{'host': 'example.com', 'user': 'someone', 'dbname': 'somedb', 'connect_timeout': '10'}
.. versionadded:: 2.7
.. seealso:: libpq docs for `PQconninfoParse()`__.
.. __: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PQCONNINFOPARSE
.. function:: quote_ident(str, scope)
Return quoted identifier according to PostgreSQL quoting rules.
The *scope* must be a `connection` or a `cursor`, the underlying
connection encoding is used for any necessary character conversion.
.. versionadded:: 2.7
.. seealso:: libpq docs for `PQescapeIdentifier()`__
.. __: https://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQESCAPEIDENTIFIER
.. method:: encrypt_password(password, user, scope=None, algorithm=None)
Return the encrypted form of a PostgreSQL password.
:param password: the cleartext password to encrypt
:param user: the name of the user to use the password for
:param scope: the scope to encrypt the password into; if *algorithm* is
``md5`` it can be `!None`
:type scope: `connection` or `cursor`
:param algorithm: the password encryption algorithm to use
The *algorithm* ``md5`` is always supported. Other algorithms are only
supported if the client libpq version is at least 10 and may require a
compatible server version: check the `PostgreSQL encryption
documentation`__ to know the algorithms supported by your server.
.. __: https://www.postgresql.org/docs/current/static/encryption-options.html
Using `!None` as *algorithm* will result in querying the server to know the
current server password encryption setting, which is a blocking operation:
query the server separately and specify a value for *algorithm* if you
want to maintain a non-blocking behaviour.
.. versionadded:: 2.8
.. seealso:: PostgreSQL docs for the `password_encryption`__ setting, libpq `PQencryptPasswordConn()`__, `PQencryptPassword()`__ functions.
.. __: https://www.postgresql.org/docs/current/static/runtime-config-connection.html#GUC-PASSWORD-ENCRYPTION
.. __: https://www.postgresql.org/docs/current/static/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN
.. __: https://www.postgresql.org/docs/current/static/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORD
.. index:: .. index::
pair: Isolation level; Constants pair: Isolation level; Constants
@ -725,16 +376,15 @@ Isolation level constants
------------------------- -------------------------
Psycopg2 `connection` objects hold informations about the PostgreSQL Psycopg2 `connection` objects hold informations about the PostgreSQL
`transaction isolation level`_. By default Psycopg doesn't change the default `transaction isolation level`_. The current transaction level can be read
configuration of the server (`ISOLATION_LEVEL_DEFAULT`); the default for from the `~connection.isolation_level` attribute. The default isolation
PostgreSQL servers is typically :sql:`READ COMMITTED`, but this may be changed level is :sql:`READ COMMITTED`. A different isolation level con be set
in the server configuration files. A different isolation level can be set through the `~connection.set_isolation_level()` method. The level can be
through the `~connection.set_isolation_level()` or `~connection.set_session()` set to one of the following constants:
methods. The level can be set to one of the following constants:
.. data:: ISOLATION_LEVEL_AUTOCOMMIT .. data:: ISOLATION_LEVEL_AUTOCOMMIT
No transaction is started when commands are executed and no No transaction is started when command are issued and no
`~connection.commit()` or `~connection.rollback()` is required. `~connection.commit()` or `~connection.rollback()` is required.
Some PostgreSQL command such as :sql:`CREATE DATABASE` or :sql:`VACUUM` Some PostgreSQL command such as :sql:`CREATE DATABASE` or :sql:`VACUUM`
can't run into a transaction: to run such command use:: can't run into a transaction: to run such command use::
@ -751,75 +401,27 @@ methods. The level can be set to one of the following constants:
.. data:: ISOLATION_LEVEL_READ_COMMITTED .. data:: ISOLATION_LEVEL_READ_COMMITTED
This is usually the default PostgreSQL value, but a different default may This is the default value. A new transaction is started at the first
be set in the database configuration. `~cursor.execute()` command on a cursor and at each new
`!execute()` after a `~connection.commit()` or a
A new transaction is started at the first `~cursor.execute()` command on a
cursor and at each new `!execute()` after a `~connection.commit()` or a
`~connection.rollback()`. The transaction runs in the PostgreSQL `~connection.rollback()`. The transaction runs in the PostgreSQL
:sql:`READ COMMITTED` isolation level: a :sql:`SELECT` query sees only :sql:`READ COMMITTED` isolation level.
data committed before the query began; it never sees either uncommitted
data or changes committed during query execution by concurrent
transactions.
.. seealso:: `Read Committed Isolation Level`__ in PostgreSQL
documentation.
.. __: https://www.postgresql.org/docs/current/static/transaction-iso.html#XACT-READ-COMMITTED
.. data:: ISOLATION_LEVEL_REPEATABLE_READ .. data:: ISOLATION_LEVEL_REPEATABLE_READ
As in `!ISOLATION_LEVEL_READ_COMMITTED`, a new transaction is started at The :sql:`REPEATABLE READ` isolation level is defined in the SQL standard
the first `~cursor.execute()` command. Transactions run at a but not available in the |MVCC| model of PostgreSQL: it is replaced by the
:sql:`REPEATABLE READ` isolation level: all the queries in a transaction stricter :sql:`SERIALIZABLE`.
see a snapshot as of the start of the transaction, not as of the start of
the current query within the transaction. However applications using this
level must be prepared to retry transactions due to serialization
failures.
While this level provides a guarantee that each transaction sees a
completely stable view of the database, this view will not necessarily
always be consistent with some serial (one at a time) execution of
concurrent transactions of the same level.
.. versionchanged:: 2.4.2
The value was an alias for `!ISOLATION_LEVEL_SERIALIZABLE` before. The
two levels are distinct since PostgreSQL 9.1
.. seealso:: `Repeatable Read Isolation Level`__ in PostgreSQL
documentation.
.. __: https://www.postgresql.org/docs/current/static/transaction-iso.html#XACT-REPEATABLE-READ
.. data:: ISOLATION_LEVEL_SERIALIZABLE .. data:: ISOLATION_LEVEL_SERIALIZABLE
As in `!ISOLATION_LEVEL_READ_COMMITTED`, a new transaction is started at Transactions are run at a :sql:`SERIALIZABLE` isolation level. This is the
the first `~cursor.execute()` command. Transactions run at a strictest transactions isolation level, equivalent to having the
:sql:`SERIALIZABLE` isolation level. This is the strictest transactions transactions executed serially rather than concurrently. However
isolation level, equivalent to having the transactions executed serially applications using this level must be prepared to retry reansactions due
rather than concurrently. However applications using this level must be to serialization failures. See `serializable isolation level`_ in
prepared to retry transactions due to serialization failures. PostgreSQL documentation.
Starting from PostgreSQL 9.1, this mode monitors for conditions which
could make execution of a concurrent set of serializable transactions
behave in a manner inconsistent with all possible serial (one at a time)
executions of those transaction. In previous version the behaviour was the
same of the :sql:`REPEATABLE READ` isolation level.
.. seealso:: `Serializable Isolation Level`__ in PostgreSQL documentation.
.. __: https://www.postgresql.org/docs/current/static/transaction-iso.html#XACT-SERIALIZABLE
.. data:: ISOLATION_LEVEL_DEFAULT
A new transaction is started at the first `~cursor.execute()` command, but
the isolation level is not explicitly selected by Psycopg: the server will
use whatever level is defined in its configuration or by statements
executed within the session outside Pyscopg control. If you want to know
what the value is you can use a query such as :sql:`show
transaction_isolation`.
.. versionadded:: 2.7
.. index:: .. index::
@ -831,7 +433,7 @@ Transaction status constants
---------------------------- ----------------------------
These values represent the possible status of a transaction: the current value These values represent the possible status of a transaction: the current value
can be read using the `connection.info.transaction_status` property. can be read using the `connection.get_transaction_status()` method.
.. data:: TRANSACTION_STATUS_IDLE .. data:: TRANSACTION_STATUS_IDLE
@ -902,7 +504,7 @@ internal usage and Python code should not rely on them.
Poll constants Poll constants
-------------- --------------
.. versionadded:: 2.2 .. versionadded:: 2.2.0
These values can be returned by `connection.poll()` during asynchronous These values can be returned by `connection.poll()` during asynchronous
connection and communication. They match the values in the libpq enum connection and communication. They match the values in the libpq enum
@ -951,7 +553,6 @@ Python objects. All the typecasters are automatically registered, except
from the database. See :ref:`unicode-handling` for details. from the database. See :ref:`unicode-handling` for details.
.. data:: BOOLEAN .. data:: BOOLEAN
BYTES
DATE DATE
DECIMAL DECIMAL
FLOAT FLOAT
@ -961,14 +562,13 @@ from the database. See :ref:`unicode-handling` for details.
TIME TIME
UNICODE UNICODE
Typecasters for basic types. Note that a few other ones (`~psycopg2.BINARY`, Typecasters for basic types. Notice that a few other ones (`~psycopg2.BINARY`,
`~psycopg2.DATETIME`, `~psycopg2.NUMBER`, `~psycopg2.ROWID`, `~psycopg2.DATETIME`, `~psycopg2.NUMBER`, `~psycopg2.ROWID`,
`~psycopg2.STRING`) are exposed by the `psycopg2` module for |DBAPI|_ `~psycopg2.STRING`) are exposed by the `psycopg2` module for |DBAPI|_
compliance. compliance.
.. data:: BINARYARRAY .. data:: BINARYARRAY
BOOLEANARRAY BOOLEANARRAY
BYTESARRAY
DATEARRAY DATEARRAY
DATETIMEARRAY DATETIMEARRAY
DECIMALARRAY DECIMALARRAY
@ -985,26 +585,31 @@ from the database. See :ref:`unicode-handling` for details.
.. data:: PYDATE .. data:: PYDATE
PYDATETIME PYDATETIME
PYDATETIMETZ
PYINTERVAL PYINTERVAL
PYTIME PYTIME
PYDATEARRAY PYDATEARRAY
PYDATETIMEARRAY PYDATETIMEARRAY
PYDATETIMETZARRAY
PYINTERVALARRAY PYINTERVALARRAY
PYTIMEARRAY PYTIMEARRAY
Typecasters to convert time-related data types to Python `!datetime` Typecasters to convert time-related data types to Python `!datetime`
objects. objects.
.. versionchanged:: 2.2 .. data:: MXDATE
MXDATETIME
MXINTERVAL
MXTIME
MXDATEARRAY
MXDATETIMEARRAY
MXINTERVALARRAY
MXTIMEARRAY
Typecasters to convert time-related data types to `mx.DateTime`_ objects.
Only available if Psycopg was compiled with `!mx` support.
.. versionchanged:: 2.2.0
previously the `DECIMAL` typecaster and the specific time-related previously the `DECIMAL` typecaster and the specific time-related
typecasters (`!PY*` and `!MX*`) were not exposed by the `extensions` typecasters (`!PY*` and `!MX*`) were not exposed by the `extensions`
module. In older versions they can be imported from the implementation module. In older versions they can be imported from the implementation
module `!psycopg2._psycopg`. module `!psycopg2._psycopg`.
.. versionadded:: 2.7.2
the `!*DATETIMETZ*` objects.
.. versionadded:: 2.8
the `!BYTES` and `BYTESARRAY` objects.

File diff suppressed because it is too large Load Diff

View File

@ -7,36 +7,9 @@ Here are a few gotchas you may encounter using `psycopg2`. Feel free to
suggest new entries! suggest new entries!
Meta
----
.. _faq-question:
.. cssclass:: faq
How do I ask a question?
- Have you first checked if your question is answered already in the
documentation?
- If your question is about installing psycopg, have you checked the
:ref:`install FAQ <faq-compile>` and the :ref:`install docs
<installation>`?
- Have you googled for your error message?
- If you haven't found an answer yet, please write to the `Mailing List`_.
- If you haven't found a bug, DO NOT write to the bug tracker to ask
questions. You will only get piro grumpy.
.. _mailing list: https://www.postgresql.org/list/psycopg/
.. _faq-transactions:
Problems with transactions handling Problems with transactions handling
----------------------------------- -----------------------------------
.. _faq-idle-in-transaction:
.. cssclass:: faq .. cssclass:: faq
Why does `!psycopg2` leave database sessions "idle in transaction"? Why does `!psycopg2` leave database sessions "idle in transaction"?
@ -45,16 +18,12 @@ Why does `!psycopg2` leave database sessions "idle in transaction"?
:sql:`SELECT`. The transaction is not closed until an explicit :sql:`SELECT`. The transaction is not closed until an explicit
`~connection.commit()` or `~connection.rollback()`. `~connection.commit()` or `~connection.rollback()`.
If you are writing a long-living program, you should probably make sure to If you are writing a long-living program, you should probably ensure to
call one of the transaction closing methods before leaving the connection call one of the transaction closing methods before leaving the connection
unused for a long time (which may also be a few seconds, depending on the unused for a long time (which may also be a few seconds, depending on the
concurrency level in your database). Alternatively you can use a concurrency level in your database). Alternatively you can use a
connection in `~connection.autocommit` mode to avoid a new transaction to connection in :ref:`autocommit <autocommit>` mode to avoid a new
be started at the first command. transaction to be started at the first command.
.. _faq-transaction-aborted:
.. cssclass:: faq
I receive the error *current transaction is aborted, commands ignored until end of transaction block* and can't do anything else! I receive the error *current transaction is aborted, commands ignored until end of transaction block* and can't do anything else!
There was a problem *in the previous* command to the database, which There was a problem *in the previous* command to the database, which
@ -64,25 +33,18 @@ I receive the error *current transaction is aborted, commands ignored until end
PostgreSQL supports nested transactions using the |SAVEPOINT|_ command). PostgreSQL supports nested transactions using the |SAVEPOINT|_ command).
.. |SAVEPOINT| replace:: :sql:`SAVEPOINT` .. |SAVEPOINT| replace:: :sql:`SAVEPOINT`
.. _SAVEPOINT: https://www.postgresql.org/docs/current/static/sql-savepoint.html .. _SAVEPOINT: http://www.postgresql.org/docs/9.0/static/sql-savepoint.html
.. _faq-transaction-aborted-multiprocess:
.. cssclass:: faq
Why do I get the error *current transaction is aborted, commands ignored until end of transaction block* when I use `!multiprocessing` (or any other forking system) and not when use `!threading`? Why do I get the error *current transaction is aborted, commands ignored until end of transaction block* when I use `!multiprocessing` (or any other forking system) and not when use `!threading`?
Psycopg's connections can't be shared across processes (but are thread Psycopg's connections can't be shared across processes (but are thread
safe). If you are forking the Python process make sure to create a new safe). If you are forking the Python process ensure to create a new
connection in each forked child. See :ref:`thread-safety` for further connection in each forked child. See :ref:`thread-safety` for further
informations. informations.
.. _faq-types:
Problems with type conversions Problems with type conversions
------------------------------ ------------------------------
.. _faq-cant-adapt:
.. cssclass:: faq .. cssclass:: faq
Why does `!cursor.execute()` raise the exception *can't adapt*? Why does `!cursor.execute()` raise the exception *can't adapt*?
@ -91,23 +53,15 @@ Why does `!cursor.execute()` raise the exception *can't adapt*?
as query parameter an object for which there is no adapter registered for as query parameter an object for which there is no adapter registered for
its class. See :ref:`adapting-new-types` for informations. its class. See :ref:`adapting-new-types` for informations.
.. _faq-number-required:
.. cssclass:: faq
I can't pass an integer or a float parameter to my query: it says *a number is required*, but *it is* a number! I can't pass an integer or a float parameter to my query: it says *a number is required*, but *it is* a number!
In your query string, you always have to use ``%s`` placeholders, In your query string, you always have to use ``%s`` placeholders,
even when passing a number. All Python objects are converted by Psycopg event when passing a number. All Python objects are converted by Psycopg
in their SQL representation, so they get passed to the query as strings. in their SQL representation, so they get passed to the query as strings.
See :ref:`query-parameters`. :: See :ref:`query-parameters`. ::
>>> cur.execute("INSERT INTO numbers VALUES (%d)", (42,)) # WRONG >>> cur.execute("INSERT INTO numbers VALUES (%d)", (42,)) # WRONG
>>> cur.execute("INSERT INTO numbers VALUES (%s)", (42,)) # correct >>> cur.execute("INSERT INTO numbers VALUES (%s)", (42,)) # correct
.. _faq-not-all-arguments-converted:
.. cssclass:: faq
I try to execute a query but it fails with the error *not all arguments converted during string formatting* (or *object does not support indexing*). Why? I try to execute a query but it fails with the error *not all arguments converted during string formatting* (or *object does not support indexing*). Why?
Psycopg always require positional arguments to be passed as a sequence, even Psycopg always require positional arguments to be passed as a sequence, even
when the query takes a single parameter. And remember that to make a when the query takes a single parameter. And remember that to make a
@ -119,10 +73,6 @@ I try to execute a query but it fails with the error *not all arguments converte
>>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar",)) # correct >>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar",)) # correct
>>> cur.execute("INSERT INTO foo VALUES (%s)", ["bar"]) # correct >>> cur.execute("INSERT INTO foo VALUES (%s)", ["bar"]) # correct
.. _faq-unicode:
.. cssclass:: faq
My database is Unicode, but I receive all the strings as UTF-8 `!str`. Can I receive `!unicode` objects instead? My database is Unicode, but I receive all the strings as UTF-8 `!str`. Can I receive `!unicode` objects instead?
The following magic formula will do the trick:: The following magic formula will do the trick::
@ -131,23 +81,6 @@ My database is Unicode, but I receive all the strings as UTF-8 `!str`. Can I rec
See :ref:`unicode-handling` for the gory details. See :ref:`unicode-handling` for the gory details.
.. _faq-bytes:
.. cssclass:: faq
My database is in mixed encoding. My program was working on Python 2 but Python 3 fails decoding the strings. How do I avoid decoding?
From psycopg 2.8 you can use the following adapters to always return bytes
from strings::
psycopg2.extensions.register_type(psycopg2.extensions.BYTES)
psycopg2.extensions.register_type(psycopg2.extensions.BYTESARRAY)
See :ref:`unicode-handling` for an example.
.. _faq-float:
.. cssclass:: faq
Psycopg converts :sql:`decimal`\/\ :sql:`numeric` database types into Python `!Decimal` objects. Can I have `!float` instead? Psycopg converts :sql:`decimal`\/\ :sql:`numeric` database types into Python `!Decimal` objects. Can I have `!float` instead?
You can register a customized adapter for PostgreSQL decimal type:: You can register a customized adapter for PostgreSQL decimal type::
@ -158,57 +91,9 @@ Psycopg converts :sql:`decimal`\/\ :sql:`numeric` database types into Python `!D
psycopg2.extensions.register_type(DEC2FLOAT) psycopg2.extensions.register_type(DEC2FLOAT)
See :ref:`type-casting-from-sql-to-python` to read the relevant See :ref:`type-casting-from-sql-to-python` to read the relevant
documentation. If you find `!psycopg2.extensions.DECIMAL` not available, use documentation. If you find `!psycopg2.extensions.DECIMAL` not avalable, use
`!psycopg2._psycopg.DECIMAL` instead. `!psycopg2._psycopg.DECIMAL` instead.
.. _faq-json-adapt:
.. cssclass:: faq
Psycopg automatically converts PostgreSQL :sql:`json` data into Python objects. How can I receive strings instead?
The easiest way to avoid JSON parsing is to register a no-op function with
`~psycopg2.extras.register_default_json()`::
psycopg2.extras.register_default_json(loads=lambda x: x)
See :ref:`adapt-json` for further details.
.. _faq-jsonb-adapt:
.. cssclass:: faq
Psycopg converts :sql:`json` values into Python objects but :sql:`jsonb` values are returned as strings. Can :sql:`jsonb` be converted automatically?
Automatic conversion of :sql:`jsonb` values is supported from Psycopg
release 2.5.4. For previous versions you can register the :sql:`json`
typecaster on the :sql:`jsonb` oids (which are known and not supposed to
change in future PostgreSQL versions)::
psycopg2.extras.register_json(oid=3802, array_oid=3807, globally=True)
See :ref:`adapt-json` for further details.
.. _faq-identifier:
.. cssclass:: faq
How can I pass field/table names to a query?
The arguments in the `~cursor.execute()` methods can only represent data
to pass to the query: they cannot represent a table or field name::
# This doesn't work
cur.execute("insert into %s values (%s)", ["my_table", 42])
If you want to build a query dynamically you can use the objects exposed
by the `psycopg2.sql` module::
cur.execute(
sql.SQL("insert into %s values (%%s)") % [sql.Identifier("my_table")],
[42])
.. _faq-bytea-9.0:
.. cssclass:: faq
Transferring binary data from PostgreSQL 9.0 doesn't work. Transferring binary data from PostgreSQL 9.0 doesn't work.
PostgreSQL 9.0 uses by default `the "hex" format`__ to transfer PostgreSQL 9.0 uses by default `the "hex" format`__ to transfer
:sql:`bytea` data: the format can't be parsed by the libpq 8.4 and :sql:`bytea` data: the format can't be parsed by the libpq 8.4 and
@ -221,27 +106,13 @@ Transferring binary data from PostgreSQL 9.0 doesn't work.
session before reading binary data; session before reading binary data;
- upgrade the libpq library on the client to at least 9.0. - upgrade the libpq library on the client to at least 9.0.
.. __: https://www.postgresql.org/docs/current/static/datatype-binary.html .. __: http://www.postgresql.org/docs/9.0/static/datatype-binary.html
.. __: https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-BYTEA-OUTPUT .. __: http://www.postgresql.org/docs/9.0/static/runtime-config-client.html#GUC-BYTEA-OUTPUT
.. _faq-array:
.. cssclass:: faq
Arrays of *TYPE* are not casted to list.
Arrays are only casted to list when their oid is known, and an array
typecaster is registered for them. If there is no typecaster, the array is
returned unparsed from PostgreSQL (e.g. ``{a,b,c}``). It is easy to create
a generic arrays typecaster, returning a list of array: an example is
provided in the `~psycopg2.extensions.new_array_type()` documentation.
.. _faq-best-practices:
Best practices Best practices
-------------- --------------
.. _faq-reuse-cursors:
.. cssclass:: faq .. cssclass:: faq
When should I save and re-use a cursor as opposed to creating a new one as needed? When should I save and re-use a cursor as opposed to creating a new one as needed?
@ -253,10 +124,6 @@ When should I save and re-use a cursor as opposed to creating a new one as neede
them.) The only exception are tight loops where one usually use the same them.) The only exception are tight loops where one usually use the same
cursor for a whole bunch of :sql:`INSERT`\s or :sql:`UPDATE`\s. cursor for a whole bunch of :sql:`INSERT`\s or :sql:`UPDATE`\s.
.. _faq-reuse-connections:
.. cssclass:: faq
When should I save and re-use a connection as opposed to creating a new one as needed? When should I save and re-use a connection as opposed to creating a new one as needed?
Creating a connection can be slow (think of SSL over TCP) so the best Creating a connection can be slow (think of SSL over TCP) so the best
practice is to create a single connection and keep it open as long as practice is to create a single connection and keep it open as long as
@ -265,111 +132,28 @@ When should I save and re-use a connection as opposed to creating a new one as n
left "idle in transaction". See also `psycopg2.pool` for lightweight left "idle in transaction". See also `psycopg2.pool` for lightweight
connection pooling. connection pooling.
.. _faq-named-cursors:
.. cssclass:: faq
What are the advantages or disadvantages of using named cursors? What are the advantages or disadvantages of using named cursors?
The only disadvantages is that they use up resources on the server and The only disadvantages is that they use up resources on the server and
that there is a little overhead because at least two queries (one to that there is a little overhead because a at least two queries (one to
create the cursor and one to fetch the initial result set) are issued to create the cursor and one to fetch the initial result set) are issued to
the backend. The advantage is that data is fetched one chunk at a time: the backend. The advantage is that data is fetched one chunk at a time:
using small `~cursor.fetchmany()` values it is possible to use very using small `~cursor.fetchmany()` values it is possible to use very
little memory on the client and to skip or discard parts of the result set. little memory on the client and to skip or discard parts of the result set.
.. _faq-interrupt-query: Problems compiling and deploying psycopg2
.. cssclass:: faq -----------------------------------------
How do I interrupt a long-running query in an interactive shell?
Normally the interactive shell becomes unresponsive to :kbd:`Ctrl-C` when
running a query. Using a connection in green mode allows Python to
receive and handle the interrupt, although it may leave the connection
broken, if the async callback doesn't handle the `!KeyboardInterrupt`
correctly.
Starting from psycopg 2.6.2, the `~psycopg2.extras.wait_select` callback
can handle a :kbd:`Ctrl-C` correctly. For previous versions, you can use
`this implementation`__.
.. __: https://www.psycopg.org/articles/2014/07/20/cancelling-postgresql-statements-python/
.. code-block:: pycon
>>> psycopg2.extensions.set_wait_callback(psycopg2.extras.wait_select)
>>> cnn = psycopg2.connect('')
>>> cur = cnn.cursor()
>>> cur.execute("select pg_sleep(10)")
^C
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
QueryCanceledError: canceling statement due to user request
>>> cnn.rollback()
>>> # You can use the connection and cursor again from here
.. _faq-compile:
Problems compiling and installing psycopg2
------------------------------------------
.. _faq-wheels:
.. cssclass:: faq
Psycopg 2.8 fails to install, Psycopg 2.7 was working fine.
With Psycopg 2.7 you were installing binary packages, but they have proven
unreliable so now you have to install them explicitly using the
``psycopg2-binary`` package. See :ref:`binary-packages` for all the
details.
.. _faq-python-h:
.. cssclass:: faq .. cssclass:: faq
I can't compile `!psycopg2`: the compiler says *error: Python.h: No such file or directory*. What am I missing? I can't compile `!psycopg2`: the compiler says *error: Python.h: No such file or directory*. What am I missing?
You need to install a Python development package: it is usually called You need to install a Python development package: it is usually called
``python-dev`` or ``python3-dev`` according to your Python version. ``python-dev``.
.. _faq-libpq-fe-h:
.. cssclass:: faq
I can't compile `!psycopg2`: the compiler says *error: libpq-fe.h: No such file or directory*. What am I missing? I can't compile `!psycopg2`: the compiler says *error: libpq-fe.h: No such file or directory*. What am I missing?
You need to install the development version of the libpq: the package is You need to install the development version of the libpq: the package is
usually called ``libpq-dev``. usually called ``libpq-dev``.
.. _faq-lo_truncate:
.. cssclass:: faq
`!psycopg2` raises `!ImportError` with message *_psycopg.so: undefined symbol: lo_truncate* when imported.
This means that Psycopg was compiled with |lo_truncate|_ support (*i.e.*
the libpq used at compile time was version >= 8.3) but at runtime an older
libpq dynamic library is found.
Fast-forward several years, if the message reports *undefined symbol:
lo_truncate64* it means that Psycopg was built with large objects 64 bits
API support (*i.e.* the libpq used at compile time was at least 9.3) but
at runtime an older libpq dynamic library is found.
You can use:
.. code-block:: shell
$ ldd /path/to/packages/psycopg2/_psycopg.so | grep libpq
to find what is the libpq dynamic library used at runtime.
You can avoid the problem by using the same version of the
:program:`pg_config` at install time and the libpq at runtime.
.. |lo_truncate| replace:: `!lo_truncate()`
.. _lo_truncate: https://www.postgresql.org/docs/current/static/lo-interfaces.html#LO-TRUNCATE
.. _faq-import-mod_wsgi:
.. cssclass:: faq
Psycopg raises *ImportError: cannot import name tz* on import in mod_wsgi / ASP, but it works fine otherwise. Psycopg raises *ImportError: cannot import name tz* on import in mod_wsgi / ASP, but it works fine otherwise.
If `!psycopg2` is installed in an egg_ (e.g. because installed by If `!psycopg2` is installed in an egg_ (e.g. because installed by
:program:`easy_install`), the user running the program may be unable to :program:`easy_install`), the user running the program may be unable to
@ -378,5 +162,6 @@ Psycopg raises *ImportError: cannot import name tz* on import in mod_wsgi / ASP,
use the WSGIPythonEggs__ directive. use the WSGIPythonEggs__ directive.
.. _egg: http://peak.telecommunity.com/DevCenter/PythonEggs .. _egg: http://peak.telecommunity.com/DevCenter/PythonEggs
.. __: https://stackoverflow.com/questions/2192323/what-is-the-python-egg-cache-python-egg-cache .. __: http://stackoverflow.com/questions/2192323/what-is-the-python-egg-cache-python-egg-cache
.. __: https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIPythonEggs.html .. __: http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPythonEggs

View File

@ -4,29 +4,26 @@ Psycopg -- PostgreSQL database adapter for Python
.. sectionauthor:: Daniele Varrazzo <daniele.varrazzo@gmail.com> .. sectionauthor:: Daniele Varrazzo <daniele.varrazzo@gmail.com>
Psycopg_ is the most popular PostgreSQL_ database adapter for the Python_ Psycopg is a PostgreSQL_ database adapter for the Python_ programming
programming language. Its main features are the complete implementation of language. Its main advantages are that it supports the full Python |DBAPI|_
the Python |DBAPI|_ specification and the thread safety (several threads can and it is thread safe (threads can share the connections). It was designed for
share the same connection). It was designed for heavily multi-threaded heavily multi-threaded applications that create and destroy lots of cursors and
applications that create and destroy lots of cursors and make a large number make a conspicuous number of concurrent :sql:`INSERT`\ s or :sql:`UPDATE`\ s.
of concurrent :sql:`INSERT`\s or :sql:`UPDATE`\s. The psycopg distribution includes ZPsycopgDA, a Zope_ Database Adapter.
Psycopg 2 is mostly implemented in C as a libpq_ wrapper, resulting in being Psycopg 2 is an almost complete rewrite of the Psycopg 1.1.x branch. Psycopg 2
both efficient and secure. It features client-side and :ref:`server-side features complete libpq_ v3 protocol, |COPY-TO-FROM|__ and full :ref:`object
<server-side-cursors>` cursors, :ref:`asynchronous communication adaptation <python-types-adaptation>` for all basic Python types: strings (including unicode), ints,
<async-support>` and :ref:`notifications <async-notify>`, :ref:`COPY <copy>` longs, floats, buffers (binary objects), booleans, `mx.DateTime`_ and builtin
support. Many Python types are supported out-of-the-box and :ref:`adapted to datetime types. It also supports unicode queries and Python lists mapped to
matching PostgreSQL data types <python-types-adaptation>`; adaptation can be PostgreSQL arrays.
extended and customized thanks to a flexible :ref:`objects adaptation system
<adapting-new-types>`.
Psycopg 2 is both Unicode and Python 3 friendly. .. _PostgreSQL: http://www.postgresql.org/
.. _Python: http://www.python.org/
.. _Zope: http://www.zope.org/
.. _Psycopg: https://psycopg.org/ .. _libpq: http://www.postgresql.org/docs/9.0/static/libpq.html
.. _PostgreSQL: https://www.postgresql.org/ .. |COPY-TO-FROM| replace:: :sql:`COPY TO/COPY FROM`
.. _Python: https://www.python.org/ .. __: http://www.postgresql.org/docs/9.0/static/sql-copy.html
.. _libpq: https://www.postgresql.org/docs/current/static/libpq.html
.. rubric:: Contents .. rubric:: Contents
@ -34,22 +31,17 @@ Psycopg 2 is both Unicode and Python 3 friendly.
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
install
usage usage
module module
connection connection
cursor cursor
advanced advanced
extensions extensions
extras
errors
sql
tz tz
pool pool
extras
errorcodes errorcodes
faq faq
news
license
.. ifconfig:: builder != 'text' .. ifconfig:: builder != 'text'
@ -57,7 +49,6 @@ Psycopg 2 is both Unicode and Python 3 friendly.
.. rubric:: Indices and tables .. rubric:: Indices and tables
* :ref:`genindex` * :ref:`genindex`
* :ref:`modindex`
* :ref:`search` * :ref:`search`
@ -68,3 +59,4 @@ Psycopg 2 is both Unicode and Python 3 friendly.
**To Do items in the documentation** **To Do items in the documentation**
.. todolist:: .. todolist::

View File

@ -1,364 +0,0 @@
.. _installation:
Installation
============
.. sectionauthor:: Daniele Varrazzo <daniele.varrazzo@gmail.com>
Psycopg is a PostgreSQL_ adapter for the Python_ programming language. It is a
wrapper for the libpq_, the official PostgreSQL client library.
.. _PostgreSQL: https://www.postgresql.org/
.. _Python: https://www.python.org/
.. index::
single: Install; from PyPI
single: Install; wheel
single: Wheel
.. _binary-packages:
Quick Install
-------------
For most operating systems, the quickest way to install Psycopg is using the
wheel_ package available on PyPI_:
.. code-block:: console
$ pip install psycopg2-binary
This will install a pre-compiled binary version of the module which does not
require the build or runtime prerequisites described below. Make sure to use
an up-to-date version of :program:`pip` (you can upgrade it using something
like ``pip install -U pip``).
You may then import the ``psycopg2`` package, as usual:
.. code-block:: python
import psycopg2
# Connect to your postgres DB
conn = psycopg2.connect("dbname=test user=postgres")
# Open a cursor to perform database operations
cur = conn.cursor()
# Execute a query
cur.execute("SELECT * FROM my_data")
# Retrieve query results
records = cur.fetchall()
.. _PyPI: https://pypi.org/project/psycopg2-binary/
.. _wheel: https://pythonwheels.com/
psycopg vs psycopg-binary
^^^^^^^^^^^^^^^^^^^^^^^^^
The ``psycopg2-binary`` package is meant for beginners to start playing
with Python and PostgreSQL without the need to meet the build
requirements.
If you are the maintainer of a published package depending on `!psycopg2`
you shouldn't use ``psycopg2-binary`` as a module dependency. **For
production use you are advised to use the source distribution.**
The binary packages come with their own versions of a few C libraries,
among which ``libpq`` and ``libssl``, which will be used regardless of other
libraries available on the client: upgrading the system libraries will not
upgrade the libraries used by `!psycopg2`. Please build `!psycopg2` from
source if you want to maintain binary upgradeability.
.. warning::
The `!psycopg2` wheel package comes packaged, among the others, with its
own ``libssl`` binary. This may create conflicts with other extension
modules binding with ``libssl`` as well, for instance with the Python
`ssl` module: in some cases, under concurrency, the interaction between
the two libraries may result in a segfault. In case of doubts you are
advised to use a package built from source.
.. index::
single: Install; disable wheel
single: Wheel; disable
.. _disable-wheel:
Change in binary packages between Psycopg 2.7 and 2.8
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In version 2.7.x, :command:`pip install psycopg2` would have tried to install
automatically the binary package of Psycopg. Because of concurrency problems
binary packages have displayed, ``psycopg2-binary`` has become a separate
package, and from 2.8 it has become the only way to install the binary
package.
If you are using Psycopg 2.7 and you want to disable the use of wheel binary
packages, relying on the system libraries available on your client, you
can use the :command:`pip` |--no-binary option|__, e.g.:
.. code-block:: console
$ pip install --no-binary :all: psycopg2
.. |--no-binary option| replace:: ``--no-binary`` option
.. __: https://pip.pypa.io/en/stable/reference/pip_install/#install-no-binary
which can be specified in your :file:`requirements.txt` files too, e.g. use:
.. code-block:: none
psycopg2>=2.7,<2.8 --no-binary psycopg2
to use the last bugfix release of the `!psycopg2` 2.7 package, specifying to
always compile it from source. Of course in this case you will have to meet
the :ref:`build prerequisites <build-prerequisites>`.
.. index::
single: Prerequisites
Prerequisites
-------------
The current `!psycopg2` implementation supports:
..
NOTE: keep consistent with setup.py and the /features/ page.
- Python versions from 3.8 to 3.13
- PostgreSQL server versions from 7.4 to 17
- PostgreSQL client library version from 9.1
.. note::
Not all the psycopg2 versions support all the supported Python versions.
Please see the :ref:`release notes <news>` to verify when the support for
a new Python version was added and when the support for an old Python
version was removed.
.. _build-prerequisites:
Build prerequisites
^^^^^^^^^^^^^^^^^^^
The build prerequisites are to be met in order to install Psycopg from source
code, from a source distribution package, GitHub_ or from PyPI.
.. _GitHub: https://github.com/psycopg/psycopg2
Psycopg is a C wrapper around the libpq_ PostgreSQL client library. To install
it from sources you will need:
- A C compiler.
- The Python header files. They are usually installed in a package such as
**python-dev** or **python3-dev**. A message such as *error: Python.h: No
such file or directory* is an indication that the Python headers are
missing.
- The libpq header files. They are usually installed in a package such as
**libpq-dev**. If you get an *error: libpq-fe.h: No such file or directory*
you are missing them.
- The :program:`pg_config` program: it is usually installed by the
**libpq-dev** package but sometimes it is not in a :envvar:`PATH` directory.
Having it in the :envvar:`PATH` greatly streamlines the installation, so try
running ``pg_config --version``: if it returns an error or an unexpected
version number then locate the directory containing the :program:`pg_config`
shipped with the right libpq version (usually
``/usr/lib/postgresql/X.Y/bin/``) and add it to the :envvar:`PATH`:
.. code-block:: console
$ export PATH=/usr/lib/postgresql/X.Y/bin/:$PATH
You only need :program:`pg_config` to compile `!psycopg2`, not for its
regular usage.
Once everything is in place it's just a matter of running the standard:
.. code-block:: console
$ pip install psycopg2
or, from the directory containing the source code:
.. code-block:: console
$ python setup.py build
$ python setup.py install
Runtime requirements
^^^^^^^^^^^^^^^^^^^^
Unless you compile `!psycopg2` as a static library, or you install it from a
self-contained wheel package, it will need the libpq_ library at runtime
(usually distributed in a ``libpq.so`` or ``libpq.dll`` file). `!psycopg2`
relies on the host OS to find the library if the library is installed in a
standard location there is usually no problem; if the library is in a
non-standard location you will have to tell Psycopg how to find it,
which is OS-dependent (for instance setting a suitable
:envvar:`LD_LIBRARY_PATH` on Linux).
.. note::
The libpq header files used to compile `!psycopg2` should match the
version of the library linked at runtime. If you get errors about missing
or mismatching libraries when importing `!psycopg2` check (e.g. using
:program:`ldd`) if the module ``psycopg2/_psycopg.so`` is linked to the
right ``libpq.so``.
.. note::
Whatever version of libpq `!psycopg2` is compiled with, it will be
possible to connect to PostgreSQL servers of any supported version: just
install the most recent libpq version or the most practical, without
trying to match it to the version of the PostgreSQL server you will have
to connect to.
.. index::
single: setup.py
single: setup.cfg
Non-standard builds
-------------------
If you have less standard requirements such as:
- creating a :ref:`debug build <debug-build>`,
- using :program:`pg_config` not in the :envvar:`PATH`,
then take a look at the ``setup.cfg`` file.
Some of the options available in ``setup.cfg`` are also available as command
line arguments of the ``build_ext`` sub-command. For instance you can specify
an alternate :program:`pg_config` location using:
.. code-block:: console
$ python setup.py build_ext --pg-config /path/to/pg_config build
Use ``python setup.py build_ext --help`` to get a list of the options
supported.
.. index::
single: debug
single: PSYCOPG_DEBUG
.. _debug-build:
Creating a debug build
^^^^^^^^^^^^^^^^^^^^^^
In case of problems, Psycopg can be configured to emit detailed debug
messages, which can be very useful for diagnostics and to report a bug. In
order to create a debug package:
- `Download`__ and unpack the Psycopg *source package* (the ``.tar.gz``
package).
- Edit the ``setup.cfg`` file adding the ``PSYCOPG_DEBUG`` flag to the
``define`` option.
- :ref:`Compile and install <build-prerequisites>` the package.
- Set the :envvar:`PSYCOPG_DEBUG` environment variable:
.. code-block:: console
$ export PSYCOPG_DEBUG=1
- Run your program (making sure that the `!psycopg2` package imported is the
one you just compiled and not e.g. the system one): you will have a copious
stream of informations printed on stderr.
.. __: https://pypi.org/project/psycopg2/#files
Non-standard Python Implementation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The `psycopg2` package is the current mature implementation of the adapter: it
is a C extension and as such it is only compatible with CPython_. If you want
to use Psycopg on a different Python implementation (PyPy, Jython, IronPython)
there is a couple of alternative:
- a `Ctypes port`__, but it is not as mature as the C implementation yet
and it is not as feature-complete;
- a `CFFI port`__ which is currently more used and reported more efficient on
PyPy, but please be careful of its version numbers because they are not
aligned to the official psycopg2 ones and some features may differ.
.. _PostgreSQL: https://www.postgresql.org/
.. _Python: https://www.python.org/
.. _libpq: https://www.postgresql.org/docs/current/static/libpq.html
.. _CPython: https://en.wikipedia.org/wiki/CPython
.. _Ctypes: https://docs.python.org/library/ctypes.html
.. __: https://github.com/mvantellingen/psycopg2-ctypes
.. __: https://github.com/chtd/psycopg2cffi
.. index::
single: tests
.. _test-suite:
Running the test suite
----------------------
Once `!psycopg2` is installed you can run the test suite to verify it is
working correctly. From the source directory, you can run:
.. code-block:: console
$ python -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')" --verbose
The tests run against a database called ``psycopg2_test`` on UNIX socket and
the standard port. You can configure a different database to run the test by
setting the environment variables:
- :envvar:`PSYCOPG2_TESTDB`
- :envvar:`PSYCOPG2_TESTDB_HOST`
- :envvar:`PSYCOPG2_TESTDB_PORT`
- :envvar:`PSYCOPG2_TESTDB_USER`
The database should already exist before running the tests.
.. _other-problems:
If you still have problems
--------------------------
Try the following. *In order:*
- Read again the :ref:`build-prerequisites`.
- Read the :ref:`FAQ <faq-compile>`.
- Google for `!psycopg2` *your error message*. Especially useful the week
after the release of a new OS X version.
- Write to the `Mailing List`_.
- If you think that you have discovered a bug, test failure or missing feature
please raise a ticket in the `bug tracker`_.
- Complain on your blog or on Twitter that `!psycopg2` is the worst package
ever and about the quality time you have wasted figuring out the correct
:envvar:`ARCHFLAGS`. Especially useful from the Starbucks near you.
.. _mailing list: https://www.postgresql.org/list/psycopg/
.. _bug tracker: https://github.com/psycopg/psycopg2/issues

View File

@ -1,7 +0,0 @@
.. index::
single: License
License
=======
.. include:: ../../LICENSE

View File

@ -7,7 +7,7 @@ The `psycopg2` module content
The module interface respects the standard defined in the |DBAPI|_. The module interface respects the standard defined in the |DBAPI|_.
.. index:: .. index::
single: Connection string single: Connection string
double: Connection; Parameters double: Connection; Parameters
single: Username; Connection single: Username; Connection
@ -16,85 +16,43 @@ The module interface respects the standard defined in the |DBAPI|_.
single: Port; Connection single: Port; Connection
single: DSN (Database Source Name) single: DSN (Database Source Name)
.. function:: .. function:: connect(dsn or params [, connection_factory] [, async=0])
connect(dsn=None, connection_factory=None, cursor_factory=None, async=False, \*\*kwargs)
Create a new database session and return a new `connection` object. Create a new database session and return a new `connection` object.
The connection parameters can be specified as a `libpq connection You can specify the connection parameters either as a string::
string`__ using the *dsn* parameter::
conn = psycopg2.connect("dbname=test user=postgres password=secret") conn = psycopg2.connect("dbname=test user=postgres password=secret")
or using a set of keyword arguments:: or using a set of keyword arguments::
conn = psycopg2.connect(dbname="test", user="postgres", password="secret") conn = psycopg2.connect(database="test", user="postgres", password="secret")
or using a mix of both: if the same parameter name is specified in both The full list of available parameters is:
sources, the *kwargs* value will have precedence over the *dsn* value.
Note that either the *dsn* or at least one connection-related keyword - `!dbname` -- the database name (only in dsn string)
argument is required. - `!database` -- the database name (only as keyword argument)
The basic connection parameters are:
- `!dbname` -- the database name (`!database` is a deprecated alias)
- `!user` -- user name used to authenticate - `!user` -- user name used to authenticate
- `!password` -- password used to authenticate - `!password` -- password used to authenticate
- `!host` -- database host address (defaults to UNIX socket if not provided) - `!host` -- database host address (defaults to UNIX socket if not provided)
- `!port` -- connection port number (defaults to 5432 if not provided) - `!port` -- connection port number (defaults to 5432 if not provided)
- `!sslmode` -- `SSL TCP/IP negotiation`__ mode
Any other connection parameter supported by the client library/server can .. __: http://www.postgresql.org/docs/9.0/static/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS
be passed either in the connection string or as a keyword. The PostgreSQL
documentation contains the complete list of the `supported parameters`__.
Also note that the same parameters can be passed to the client library
using `environment variables`__.
.. __:
.. _connstring: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
.. __:
.. _connparams: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
.. __:
.. _connenvvars: https://www.postgresql.org/docs/current/static/libpq-envars.html
Using the *connection_factory* parameter a different class or Using the *connection_factory* parameter a different class or
connections factory can be specified. It should be a callable object connections factory can be specified. It should be a callable object
taking a *dsn* string argument. See :ref:`subclassing-connection` for taking a *dsn* argument. See :ref:`subclassing-connection` for
details. If a *cursor_factory* is specified, the connection's details.
`~connection.cursor_factory` is set to it. If you only need customized
cursors you can use this parameter instead of subclassing a connection.
Using *async*\=\ `!True` an asynchronous connection will be created: see Using *async*\=1 an asynchronous connection will be created: see
:ref:`async-support` to know about advantages and limitations. *async_* is :ref:`async-support` to know about advantages and limitations.
a valid alias for the Python version where ``async`` is a keyword.
.. versionchanged:: 2.4.3
any keyword argument is passed to the connection. Previously only the
basic parameters (plus `!sslmode`) were supported as keywords.
.. versionchanged:: 2.5
added the *cursor_factory* parameter.
.. versionchanged:: 2.7
both *dsn* and keyword arguments can be specified.
.. versionchanged:: 2.7
added *async_* alias.
.. seealso::
- `~psycopg2.extensions.parse_dsn`
- libpq `connection string syntax`__
- libpq supported `connection parameters`__
- libpq supported `environment variables`__
.. __: connstring_
.. __: connparams_
.. __: connenvvars_
.. extension:: .. extension::
The non-connection-related keyword parameters are Psycopg extensions The parameters *connection_factory* and *async* are Psycopg extensions
to the |DBAPI|_. to the |DBAPI|.
.. data:: apilevel .. data:: apilevel
@ -113,17 +71,9 @@ The module interface respects the standard defined in the |DBAPI|_.
by the interface. For `psycopg2` is ``pyformat``. See also by the interface. For `psycopg2` is ``pyformat``. See also
:ref:`query-parameters`. :ref:`query-parameters`.
.. data:: __libpq_version__
Integer constant reporting the version of the ``libpq`` library this
``psycopg2`` module was compiled with (in the same format of
`~psycopg2.extensions.ConnectionInfo.server_version`). If this value is
greater or equal than ``90100`` then you may query the version of the
actually loaded library using the `~psycopg2.extensions.libpq_version()`
function.
.. index:: .. index::
single: Exceptions; DB API single: Exceptions; DB API
.. _dbapi-exceptions: .. _dbapi-exceptions:
@ -134,18 +84,17 @@ Exceptions
In compliance with the |DBAPI|_, the module makes informations about errors In compliance with the |DBAPI|_, the module makes informations about errors
available through the following exceptions: available through the following exceptions:
.. exception:: Warning .. exception:: Warning
Exception raised for important warnings like data truncations while Exception raised for important warnings like data truncations while
inserting, etc. It is a subclass of the Python `StandardError` inserting, etc. It is a subclass of the Python `~exceptions.StandardError`.
(`Exception` on Python 3).
.. exception:: Error
.. exception:: Error
Exception that is the base class of all other error exceptions. You can Exception that is the base class of all other error exceptions. You can
use this to catch all errors with one single `!except` statement. Warnings use this to catch all errors with one single `!except` statement. Warnings
are not considered errors and thus not use this class as base. It are not considered errors and thus not use this class as base. It
is a subclass of the Python `StandardError` (`Exception` on Python 3). is a subclass of the Python `!StandardError`.
.. attribute:: pgerror .. attribute:: pgerror
@ -158,48 +107,31 @@ available through the following exceptions:
if not available. The `~psycopg2.errorcodes` module contains if not available. The `~psycopg2.errorcodes` module contains
symbolic constants representing PostgreSQL error codes. symbolic constants representing PostgreSQL error codes.
.. doctest:: .. extension::
:options: +NORMALIZE_WHITESPACE
>>> try: The `~Error.pgerror` and `~Error.pgcode` attributes are
... cur.execute("SELECT * FROM barf") Psycopg extensions.
... except psycopg2.Error as e:
... pass
>>> e.pgcode .. doctest::
'42P01' :options: +NORMALIZE_WHITESPACE
>>> print(e.pgerror)
ERROR: relation "barf" does not exist
LINE 1: SELECT * FROM barf
^
.. attribute:: cursor
The cursor the exception was raised from; `None` if not applicable.
.. attribute:: diag
A `~psycopg2.extensions.Diagnostics` object containing further
information about the error. ::
>>> try: >>> try:
... cur.execute("SELECT * FROM barf") ... cur.execute("SELECT * FROM barf")
... except psycopg2.Error as e: ... except Exception, e:
... pass ... pass
>>> e.diag.severity >>> e.pgcode
'ERROR' '42P01'
>>> e.diag.message_primary >>> print e.pgerror
'relation "barf" does not exist' ERROR: relation "barf" does not exist
LINE 1: SELECT * FROM barf
^
.. versionadded:: 2.5 .. versionchanged:: 2.0.7 added `Error.pgerror` and
`Error.pgcode` attributes.
.. extension::
The `~Error.pgerror`, `~Error.pgcode`, `~Error.cursor`, and
`~Error.diag` attributes are Psycopg extensions.
.. exception:: InterfaceError .. exception:: InterfaceError
Exception raised for errors that are related to the database interface Exception raised for errors that are related to the database interface
@ -209,41 +141,41 @@ available through the following exceptions:
Exception raised for errors that are related to the database. It is a Exception raised for errors that are related to the database. It is a
subclass of `Error`. subclass of `Error`.
.. exception:: DataError .. exception:: DataError
Exception raised for errors that are due to problems with the processed Exception raised for errors that are due to problems with the processed
data like division by zero, numeric value out of range, etc. It is a data like division by zero, numeric value out of range, etc. It is a
subclass of `DatabaseError`. subclass of `DatabaseError`.
.. exception:: OperationalError .. exception:: OperationalError
Exception raised for errors that are related to the database's operation Exception raised for errors that are related to the database's operation
and not necessarily under the control of the programmer, e.g. an and not necessarily under the control of the programmer, e.g. an
unexpected disconnect occurs, the data source name is not found, a unexpected disconnect occurs, the data source name is not found, a
transaction could not be processed, a memory allocation error occurred transaction could not be processed, a memory allocation error occurred
during processing, etc. It is a subclass of `DatabaseError`. during processing, etc. It is a subclass of `DatabaseError`.
.. exception:: IntegrityError .. exception:: IntegrityError
Exception raised when the relational integrity of the database is Exception raised when the relational integrity of the database is
affected, e.g. a foreign key check fails. It is a subclass of affected, e.g. a foreign key check fails. It is a subclass of
`DatabaseError`. `DatabaseError`.
.. exception:: InternalError .. exception:: InternalError
Exception raised when the database encounters an internal error, e.g. the Exception raised when the database encounters an internal error, e.g. the
cursor is not valid anymore, the transaction is out of sync, etc. It is a cursor is not valid anymore, the transaction is out of sync, etc. It is a
subclass of `DatabaseError`. subclass of `DatabaseError`.
.. exception:: ProgrammingError .. exception:: ProgrammingError
Exception raised for programming errors, e.g. table not found or already Exception raised for programming errors, e.g. table not found or already
exists, syntax error in the SQL statement, wrong number of parameters exists, syntax error in the SQL statement, wrong number of parameters
specified, etc. It is a subclass of `DatabaseError`. specified, etc. It is a subclass of `DatabaseError`.
.. exception:: NotSupportedError .. exception:: NotSupportedError
Exception raised in case a method or database API was used which is not Exception raised in case a method or database API was used which is not
supported by the database, e.g. requesting a `!rollback()` on a supported by the database, e.g. requesting a `!rollback()` on a
connection that does not support transaction or has transactions turned connection that does not support transaction or has transactions turned
@ -252,14 +184,13 @@ available through the following exceptions:
.. extension:: .. extension::
Psycopg actually raises a different exception for each :sql:`SQLSTATE` Psycopg may raise a few other, more specialized, exceptions: currently
error returned by the database: the classes are available in the `~psycopg2.extensions.QueryCanceledError` and
`psycopg2.errors` module. Every exception class is a subclass of one of `~psycopg2.extensions.TransactionRollbackError` are defined. These
the exception classes defined here though, so they don't need to be exceptions are not exposed by the main `!psycopg2` module but are
trapped specifically: trapping `!Error` or `!DatabaseError` is usually made available by the `~psycopg2.extensions` module. All the
what needed to write a generic error handler; trapping a specific error additional exceptions are subclasses of standard |DBAPI| exceptions, so
such as `!NotNullViolation` can be useful to write specific exception trapping them specifically is not required.
handlers.
This is the exception inheritance layout: This is the exception inheritance layout:
@ -273,6 +204,8 @@ This is the exception inheritance layout:
\|__ `DatabaseError` \|__ `DatabaseError`
\|__ `DataError` \|__ `DataError`
\|__ `OperationalError` \|__ `OperationalError`
\| \|__ `psycopg2.extensions.QueryCanceledError`
\| \|__ `psycopg2.extensions.TransactionRollbackError`
\|__ `IntegrityError` \|__ `IntegrityError`
\|__ `InternalError` \|__ `InternalError`
\|__ `ProgrammingError` \|__ `ProgrammingError`
@ -285,9 +218,7 @@ This is the exception inheritance layout:
Type Objects and Constructors Type Objects and Constructors
----------------------------- -----------------------------
.. note:: .. note:: This section is mostly copied verbatim from the |DBAPI|_
This section is mostly copied verbatim from the |DBAPI|_
specification. While these objects are exposed in compliance to the specification. While these objects are exposed in compliance to the
DB API, Psycopg offers very accurate tools to convert data between Python DB API, Psycopg offers very accurate tools to convert data between Python
and PostgreSQL formats. See :ref:`adapting-new-types` and and PostgreSQL formats. See :ref:`adapting-new-types` and
@ -316,15 +247,15 @@ the type codes for date, time and timestamp columns; see the
Implementation Hints below for details). Implementation Hints below for details).
The module exports the following constructors and singletons: The module exports the following constructors and singletons:
.. function:: Date(year,month,day) .. function:: Date(year,month,day)
This function constructs an object holding a date value. This function constructs an object holding a date value.
.. function:: Time(hour,minute,second) .. function:: Time(hour,minute,second)
This function constructs an object holding a time value. This function constructs an object holding a time value.
.. function:: Timestamp(year,month,day,hour,minute,second) .. function:: Timestamp(year,month,day,hour,minute,second)
This function constructs an object holding a time stamp value. This function constructs an object holding a time stamp value.
@ -336,11 +267,11 @@ The module exports the following constructors and singletons:
the standard Python time module for details). the standard Python time module for details).
.. function:: TimeFromTicks(ticks) .. function:: TimeFromTicks(ticks)
This function constructs an object holding a time value from the given This function constructs an object holding a time value from the given
ticks value (number of seconds since the epoch; see the documentation of ticks value (number of seconds since the epoch; see the documentation of
the standard Python time module for details). the standard Python time module for details).
.. function:: TimestampFromTicks(ticks) .. function:: TimestampFromTicks(ticks)
This function constructs an object holding a time stamp value from the This function constructs an object holding a time stamp value from the
@ -348,16 +279,10 @@ The module exports the following constructors and singletons:
documentation of the standard Python time module for details). documentation of the standard Python time module for details).
.. function:: Binary(string) .. function:: Binary(string)
This function constructs an object capable of holding a binary (long) This function constructs an object capable of holding a binary (long)
string value. string value.
.. note::
All the adapters returned by the module level factories (`!Binary`,
`!Date`, `!Time`, `!Timestamp` and the `!*FromTicks` variants) expose the
wrapped object (a regular Python object such as `!datetime`) in an
`!adapted` attribute.
.. data:: STRING .. data:: STRING
@ -368,17 +293,17 @@ The module exports the following constructors and singletons:
This type object is used to describe (long) binary columns in a database This type object is used to describe (long) binary columns in a database
(e.g. LONG, RAW, BLOBs). (e.g. LONG, RAW, BLOBs).
.. data:: NUMBER .. data:: NUMBER
This type object is used to describe numeric columns in a database. This type object is used to describe numeric columns in a database.
.. data:: DATETIME .. data:: DATETIME
This type object is used to describe date/time columns in a database. This type object is used to describe date/time columns in a database.
.. data:: ROWID .. data:: ROWID
This type object is used to describe the "Row ID" column in a database. This type object is used to describe the "Row ID" column in a database.

View File

@ -1,10 +0,0 @@
.. index::
single: Release notes
single: News
.. _news:
Release notes
=============
.. include:: ../../NEWS

View File

@ -10,7 +10,7 @@
Creating new PostgreSQL connections can be an expensive operation. This Creating new PostgreSQL connections can be an expensive operation. This
module offers a few pure Python classes implementing simple connection pooling module offers a few pure Python classes implementing simple connection pooling
directly in the client application. directly into the client application.
.. class:: AbstractConnectionPool(minconn, maxconn, \*args, \*\*kwargs) .. class:: AbstractConnectionPool(minconn, maxconn, \*args, \*\*kwargs)
@ -24,24 +24,17 @@ directly in the client application.
.. method:: getconn(key=None) .. method:: getconn(key=None)
Get a free connection from the pool. Get a free connection and assign it to *key* if not `!None`.
The *key* parameter is optional: if used, the connection will be .. method:: putconn(conn, key=None)
associated to the key and calling `!getconn()` with the same key again
will return the same connection.
.. method:: putconn(conn, key=None, close=False)
Put away a connection. Put away a connection.
If *close* is `!True`, discard the connection from the pool.
*key* should be used consistently with `getconn()`.
.. method:: closeall .. method:: closeall
Close all the connections handled by the pool. Close all the connections handled by the pool.
Note that all the connections are closed, including ones Notice that all the connections are closed, including ones
eventually in use by the application. eventually in use by the application.
@ -58,3 +51,12 @@ be used.
.. autoclass:: ThreadedConnectionPool .. autoclass:: ThreadedConnectionPool
.. note:: This pool class can be safely used in multi-threaded applications. .. note:: This pool class can be safely used in multi-threaded applications.
.. autoclass:: PersistentConnectionPool
.. note::
This pool class is mostly designed to interact with Zope and probably
not useful in generic applications.

View File

@ -1,147 +0,0 @@
`psycopg2.sql` -- SQL string composition
========================================
.. sectionauthor:: Daniele Varrazzo <daniele.varrazzo@gmail.com>
.. module:: psycopg2.sql
.. versionadded:: 2.7
The module contains objects and functions useful to generate SQL dynamically,
in a convenient and safe way. SQL identifiers (e.g. names of tables and
fields) cannot be passed to the `~cursor.execute()` method like query
arguments::
# This will not work
table_name = 'my_table'
cur.execute("insert into %s values (%s, %s)", [table_name, 10, 20])
The SQL query should be composed before the arguments are merged, for
instance::
# This works, but it is not optimal
table_name = 'my_table'
cur.execute(
"insert into %s values (%%s, %%s)" % table_name,
[10, 20])
This sort of works, but it is an accident waiting to happen: the table name
may be an invalid SQL literal and need quoting; even more serious is the
security problem in case the table name comes from an untrusted source. The
name should be escaped using `~psycopg2.extensions.quote_ident()`::
# This works, but it is not optimal
table_name = 'my_table'
cur.execute(
"insert into %s values (%%s, %%s)" % ext.quote_ident(table_name, cur),
[10, 20])
This is now safe, but it somewhat ad-hoc. In case, for some reason, it is
necessary to include a value in the query string (as opposite as in a value)
the merging rule is still different (`~psycopg2.extensions.adapt()` should be
used...). It is also still relatively dangerous: if `!quote_ident()` is
forgotten somewhere, the program will usually work, but will eventually crash
in the presence of a table or field name with containing characters to escape,
or will present a potentially exploitable weakness.
The objects exposed by the `!psycopg2.sql` module allow generating SQL
statements on the fly, separating clearly the variable parts of the statement
from the query parameters::
from psycopg2 import sql
cur.execute(
sql.SQL("insert into {} values (%s, %s)")
.format(sql.Identifier('my_table')),
[10, 20])
Module usage
------------
Usually you should express the template of your query as an `SQL` instance
with `{}`\-style placeholders and use `~SQL.format()` to merge the variable
parts into them, all of which must be `Composable` subclasses. You can still
have `%s`\ -style placeholders in your query and pass values to
`~cursor.execute()`: such value placeholders will be untouched by
`!format()`::
query = sql.SQL("select {field} from {table} where {pkey} = %s").format(
field=sql.Identifier('my_name'),
table=sql.Identifier('some_table'),
pkey=sql.Identifier('id'))
The resulting object is meant to be passed directly to cursor methods such as
`~cursor.execute()`, `~cursor.executemany()`, `~cursor.copy_expert()`, but can
also be used to compose a query as a Python string, using the
`~Composable.as_string()` method::
cur.execute(query, (42,))
If part of your query is a variable sequence of arguments, such as a
comma-separated list of field names, you can use the `SQL.join()` method to
pass them to the query::
query = sql.SQL("select {fields} from {table}").format(
fields=sql.SQL(',').join([
sql.Identifier('field1'),
sql.Identifier('field2'),
sql.Identifier('field3'),
]),
table=sql.Identifier('some_table'))
`!sql` objects
--------------
The `!sql` objects are in the following inheritance hierarchy:
| `Composable`: the base class exposing the common interface
| ``|__`` `SQL`: a literal snippet of an SQL query
| ``|__`` `Identifier`: a PostgreSQL identifier or dot-separated sequence of identifiers
| ``|__`` `Literal`: a value hardcoded into a query
| ``|__`` `Placeholder`: a `%s`\ -style placeholder whose value will be added later e.g. by `~cursor.execute()`
| ``|__`` `Composed`: a sequence of `!Composable` instances.
.. autoclass:: Composable
.. automethod:: as_string
.. autoclass:: SQL
.. autoattribute:: string
.. automethod:: format
.. automethod:: join
.. autoclass:: Identifier
.. versionchanged:: 2.8
added support for multiple strings.
.. autoattribute:: strings
.. versionadded:: 2.8
previous verions only had a `!string` attribute. The attribute
still exists but is deprecate and will only work if the
`!Identifier` wraps a single string.
.. autoclass:: Literal
.. autoattribute:: wrapped
.. autoclass:: Placeholder
.. autoattribute:: name
.. autoclass:: Composed
.. autoattribute:: seq
.. automethod:: join

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
""" """
extension extension
~~~~~~~~~ ~~~~~~~~~
@ -11,7 +12,7 @@
from docutils import nodes from docutils import nodes
from sphinx.locale import _ from sphinx.locale import _
from docutils.parsers.rst import Directive from sphinx.util.compat import Directive, make_admonition
class extension_node(nodes.Admonition, nodes.Element): pass class extension_node(nodes.Admonition, nodes.Element): pass
@ -28,11 +29,12 @@ class Extension(Directive):
option_spec = {} option_spec = {}
def run(self): def run(self):
node = extension_node('\n'.join(self.content)) nodes = make_admonition(extension_node,
node += nodes.title(_('DB API extension'), _('DB API extension')) self.name, [_('DB API extension')], self.options,
self.state.nested_parse(self.content, self.content_offset, node) self.content, self.lineno, self.content_offset,
node['classes'].append('dbapi-extension') self.block_text, self.state, self.state_machine)
return [node] nodes[0]['classes'].append('dbapi-extension')
return nodes
def visit_extension_node(self, node): def visit_extension_node(self, node):
@ -48,3 +50,4 @@ def setup(app):
text=(visit_extension_node, depart_extension_node)) text=(visit_extension_node, depart_extension_node))
app.add_directive('extension', Extension) app.add_directive('extension', Extension)

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
""" """
sql role sql role
~~~~~~~~ ~~~~~~~~
@ -11,9 +12,10 @@ from docutils import nodes, utils
from docutils.parsers.rst import roles from docutils.parsers.rst import roles
def sql_role(name, rawtext, text, lineno, inliner, options={}, content=[]): def sql_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
text = utils.unescape(text) text = utils.unescape(text)
options['classes'] = ['sql'] options['classes'] = ['sql']
return [nodes.literal(rawtext, text, **options)], [] return [nodes.literal(rawtext, text, **options)], []
def setup(app): def setup(app):
roles.register_local_role('sql', sql_role) roles.register_local_role('sql', sql_role)

View File

@ -1,57 +0,0 @@
"""
ticket role
~~~~~~~~~~~
An interpreted text role to link docs to tickets issues.
:copyright: Copyright 2013 by Daniele Varrazzo.
"""
import re
from docutils import nodes, utils
from docutils.parsers.rst import roles
def ticket_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
cfg = inliner.document.settings.env.app.config
if cfg.ticket_url is None:
msg = inliner.reporter.warning(
"ticket not configured: please configure ticket_url in conf.py")
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
rv = [nodes.Text(name + ' ')]
tokens = re.findall(r'(#?\d+)|([^\d#]+)', text)
for ticket, noise in tokens:
if ticket:
num = int(ticket.replace('#', ''))
# Push numbers of the oldel tickets ahead.
# We moved the tickets from a different tracker to GitHub and the
# latter already had a few ticket numbers taken (as merge
# requests).
remap_until = cfg.ticket_remap_until
remap_offset = cfg.ticket_remap_offset
if remap_until and remap_offset:
if num <= remap_until:
num += remap_offset
url = cfg.ticket_url % num
roles.set_classes(options)
node = nodes.reference(ticket, utils.unescape(ticket),
refuri=url, **options)
rv.append(node)
else:
assert noise
rv.append(nodes.Text(noise))
return rv, []
def setup(app):
app.add_config_value('ticket_url', None, 'env')
app.add_config_value('ticket_remap_until', None, 'env')
app.add_config_value('ticket_remap_offset', None, 'env')
app.add_role('ticket', ticket_role)
app.add_role('tickets', ticket_role)

View File

@ -1,57 +0,0 @@
#!/usr/bin/env python
"""Create the docs table of the sqlstate errors.
"""
import re
import sys
from collections import namedtuple
from psycopg2._psycopg import sqlstate_errors
def main():
sqlclasses = {}
clsfile = sys.argv[1]
with open(clsfile) as f:
for l in f:
m = re.match(r'/\* Class (..) - (.+) \*/', l)
if m is not None:
sqlclasses[m.group(1)] = m.group(2)
Line = namedtuple('Line', 'colstate colexc colbase sqlstate')
lines = [Line('SQLSTATE', 'Exception', 'Base exception', None)]
for k in sorted(sqlstate_errors):
exc = sqlstate_errors[k]
lines.append(Line(
f"``{k}``", f"`!{exc.__name__}`",
f"`!{get_base_exception(exc).__name__}`", k))
widths = [max(len(l[c]) for l in lines) for c in range(3)]
h = Line(*(['=' * w for w in widths] + [None]))
lines.insert(0, h)
lines.insert(2, h)
lines.append(h)
h1 = '-' * (sum(widths) + len(widths) - 1)
sqlclass = None
for l in lines:
cls = l.sqlstate[:2] if l.sqlstate else None
if cls and cls != sqlclass:
print(f"**Class {cls}**: {sqlclasses[cls]}")
print(h1)
sqlclass = cls
print("%-*s %-*s %-*s" % (
widths[0], l.colstate, widths[1], l.colexc, widths[2], l.colbase))
def get_base_exception(exc):
for cls in exc.__mro__:
if cls.__module__ == 'psycopg2':
return cls
if __name__ == '__main__':
sys.exit(main())

56
doc/src/tools/stitch_text.py Executable file
View File

@ -0,0 +1,56 @@
#! /usr/bin/env python
"""A script to stitch together the generated text files in the correct order.
"""
import os
import sys
def main():
if len(sys.argv) != 3:
print >>sys.stderr, "usage: %s index.rst text-dir"
return 2
_, index, txt_dir = sys.argv
for fb in iter_file_base(index):
emit(fb, txt_dir)
return 0
def iter_file_base(fn):
have_line = iter(open(fn)).next
while not have_line().startswith('.. toctree'):
pass
while have_line().strip().startswith(':'):
pass
yield os.path.splitext(os.path.basename(fn))[0]
n = 0
while 1:
line = have_line()
if line.isspace():
continue
if line.startswith(".."):
break
n += 1
yield line.strip()
if n < 5:
# maybe format changed?
raise Exception("Not enough files found. Format change in index.rst?")
def emit(basename, txt_dir):
for line in open(os.path.join(txt_dir, basename + ".txt")):
line = line.replace("``", "'")
sys.stdout.write(line)
# some space between sections
print
print
if __name__ == '__main__':
sys.exit(main())

View File

@ -5,15 +5,12 @@
.. module:: psycopg2.tz .. module:: psycopg2.tz
.. deprecated:: 2.9
The module will be dropped in psycopg 2.10. Use `datetime.timezone`
instead.
This module holds two different tzinfo implementations that can be used as the This module holds two different tzinfo implementations that can be used as the
`tzinfo` argument to `~datetime.datetime` constructors, directly passed to `tzinfo` argument to `~datetime.datetime` constructors, directly passed to
Psycopg functions or used to set the `cursor.tzinfo_factory` attribute in Psycopg functions or used to set the `cursor.tzinfo_factory` attribute in
cursors. cursors.
.. autoclass:: psycopg2.tz.FixedOffsetTimezone .. autoclass:: psycopg2.tz.FixedOffsetTimezone
.. autoclass:: psycopg2.tz.LocalTimezone .. autoclass:: psycopg2.tz.LocalTimezone

File diff suppressed because it is too large Load Diff

89
examples/binary.py Normal file
View File

@ -0,0 +1,89 @@
# binary.py - working with binary data
#
# Copyright (C) 2001-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 tis line (except for experimenting)
import sys
import psycopg2
if len(sys.argv) > 1:
DSN = sys.argv[1]
print "Opening connection using dns:", 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),
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),
open(new_name, 'wb').write(row[0])
print "done"
print " python type of image data is", type(row[0])
# this rollback is requires because we can't drop a table with a binary cusor
# 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!"

177
examples/copy_from.py Normal file
View File

@ -0,0 +1,177 @@
# copy_from.py -- example about copy_from
#
# Copyright (C) 2002 Tom Jenkins <tjenkins@devis.com>
# Copyright (C) 2005 Federico Di Gregorio <fog@initd.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
## put in DSN your DSN string
DSN = 'dbname=test'
## don't modify anything below tis 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 dns:", 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, err:
conn.rollback()
print " Catched error (as expected):\n", err
conn.rollback()
curs.execute("DROP TABLE test_copy")
os.unlink('copy_from.txt')
conn.commit()

103
examples/copy_to.py Normal file
View File

@ -0,0 +1,103 @@
# copy_to.py -- example about copy_to
#
# Copyright (C) 2002 Tom Jenkins <tjenkins@devis.com>
# Copyright (C) 2005 Federico Di Gregorio <fog@initd.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
## put in DSN your DSN string
DSN = 'dbname=test'
## don't modify anything below tis 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 dns:", 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,
# 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,
# 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,
# 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,
curs.execute("DROP TABLE test_copy")
os.unlink('copy_to.txt')
conn.commit()

63
examples/cursor.py Normal file
View File

@ -0,0 +1,63 @@
# cursor.py - how to subclass the cursor type
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# 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, err:
print "Exception caugth:", err
conn.rollback()

144
examples/dialtone.py Normal file
View File

@ -0,0 +1,144 @@
"""
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
try:
sorted()
except:
def sorted(seq):
seq.sort()
return seq
# 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 enable the programmer to glue most of the
code out there without many difficulties.
This recipe tries to focus the 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 line 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': <read-only buffer for 0x402de070, ...>,
'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.
"""

65
examples/dict.py Normal file
View File

@ -0,0 +1,65 @@
# dict.py - using DictCUrsor/DictRow
#
# Copyright (C) 2005-2010 Federico Di Gregorio <fog@debian.org>
#
# 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."

99
examples/dt.py Normal file
View File

@ -0,0 +1,99 @@
# datetime.py - example of using date and time types
#
# Copyright (C) 2001-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 tis 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 dns:", 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 is 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 is 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()

105
examples/encoding.py Normal file
View File

@ -0,0 +1,105 @@
# encoding.py - show to change client enkoding (and test it works)
# -*- encoding: utf8 -*-
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 dns:", 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)

80
examples/fetch.py Normal file
View File

@ -0,0 +1,80 @@
# fetch.py -- example about declaring cursors
#
# Copyright (C) 2001-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 tis line (except for experimenting)
import sys
import psycopg2
if len(sys.argv) > 1:
DSN = sys.argv[1]
print "Opening connection using dns:", 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 support 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()

59
examples/lastrowid.py Normal file
View File

@ -0,0 +1,59 @@
# lastrowid.py - example of using .lastrowid attribute
#
# Copyright (C) 2001-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 tis line (except for experimenting)
import sys, psycopg2
if len(sys.argv) > 1:
DSN = sys.argv[1]
print "Opening connection using dns:", 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()

91
examples/lobject.py Normal file
View File

@ -0,0 +1,91 @@
# lobject.py - lobject example
#
# Copyright (C) 2001-2006 Federico Di Gregorio <fog@debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 dns:", 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!"

47
examples/mogrify.py Normal file
View File

@ -0,0 +1,47 @@
# mogrify.py - test all possible simple type mogrifications
# -*- encoding: latin1 -*-
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 dns:", 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<EFBFBD>!'})
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<EFBFBD>!'})
print curs.mogrify("SELECT %(foo)s AS foo", {'foo':u'bar'})
conn.rollback()

126
examples/myfirstrecipe.py Normal file
View File

@ -0,0 +1,126 @@
"""
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 <fog@debian.org>
#
# 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))

44
examples/notify.py Normal file
View File

@ -0,0 +1,44 @@
# notify.py - example of getting notifies
#
# Copyright (C) 2001-2010 Federico Di Gregorio <fog@debian.org>
#
# 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 tis line (except for experimenting)
import sys
import psycopg2
import select
if len(sys.argv) > 1:
DSN = sys.argv[1]
print "Opening connection using dns:", DSN
conn = psycopg2.connect(DSN)
print "Encoding for this connection is", conn.encoding
conn.set_isolation_level(0)
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()

Some files were not shown because too many files have changed in this diff Show More