提交 eafb6364 编写于 作者: B Bruce Momjian

Update to PyGreSQL 3.1:

Fix some quoting functions. In particular handle NULLs better.

Use a method to add primary key information rather than direct
manipulation of the class structures.

Break decimal out in _quote (in pg.py) and treat it as float.

Treat timestamp like date for quoting purposes.

Remove a redundant SELECT from the get method speeding it, and
insert since it calls get, up a little.

Add test for BOOL type in typecast method to pgdbTypeCache class.
(tv@beamnet.de)

Fix pgdb.py to send port as integer to lower level function
(dildog@l0pht.com)

Change pg.py to speed up some operations

Allow updates on tables with no primary keys.

D'Arcy J.M. Cain
上级 960c1861
Announce: Release of PyGreSQL version 3.0
Announce: Release of PyGreSQL version 3.1
===============================================
PyGreSQL v3.0 has been released.
PyGreSQL v3.1 has been released.
It is available at: ftp://ftp.druid.net/pub/distrib/PyGreSQL.tgz. If
you are running NetBSD, look in the packages directory under databases.
There is also a package in the FreeBSD ports collection.
......@@ -25,16 +25,11 @@ PyGreSQL is a python module that interfaces to a PostgreSQL database. It
embeds the PostgreSQL query library to allow easy use of the powerful
PostgreSQL features from a Python script.
This release of PyGreSQL is the first DB-SIG API. That's why we have
a bump in the major number. There is also a potential problem in
backwards compatibility. Previously when there was a NULL in a returned
field it was returned as a blank. Now it is more properly returned as
a Python None. Any scripts that expect NULLs to be blanks will have
problems with this.
This release fixes a few bugs, adds a few minor features and makes a
few speedups in the code.
Due to the fact that the DB-API is brand new, it is expected that there
will be a 3.1 release shortly with corrections once many people have
had a chance to test it.
The next release (unless serious bugs are found) will be to match PyGreSQL
to version 2.0 of Python.
See the other changes below or in the Changelog file.
......@@ -44,7 +39,22 @@ andre@chimay.via.ecp.fr. I changed the version to 2.0 and updated the
code for Python 1.5 and PostgreSQL 6.2.1. While I was at it I upgraded
the code to use full ANSI style prototypes and changed the order of
arguments to connect. Later versions are fixes and enhancements to that.
The latest version of PyGreSQL works with Python 1.5.2 and PostgreSQL 6.5.
The latest version of PyGreSQL works with Python 1.5.2 and PostgreSQL 7.0.x
Important changes from PyGreSQL 3.0 to PyGreSQL 3.1
- Fix some quoting functions. In particular handle NULLs better.
- Use a method to add primary key information rather than direct
manipulation of the class structures.
- Break decimal out in _quote (in pg.py) and treat it as float.
- Treat timestamp like date for quoting purposes.
- Remove a redundant SELECT from the get method speeding it, and insert
since it calls get, up a little.
- Add test for BOOL type in typecast method to pgdbTypeCache class.
(tv@beamnet.de)
- Fix pgdb.py to send port as integer to lower level function
(dildog@l0pht.com)
- Change pg.py to speed up some operations
- Allow updates on tables with no primary keys.
Important changes from PyGreSQL 2.4 to PyGreSQL 3.0:
- Remove strlen() call from pglarge_write() and get size from object.
......
......@@ -5,6 +5,21 @@ This software is copyright (c) 1995, Pascal Andre (andre@via.ecp.fr)
Further copyright 1997, 1998 and 1999 by D'Arcy J.M. Cain (darcy@druid.net)
See file README for copyright information.
Version 3.1
- Fix some quoting functions. In particular handle NULLs better.
- Use a method to add primary key information rather than direct
manipulation of the class structures.
- Break decimal out in _quote (in pg.py) and treat it as float.
- Treat timestamp like date for quoting purposes.
- Remove a redundant SELECT from the get method speeding it, and insert
since it calls get, up a little.
- Add test for BOOL type in typecast method to pgdbTypeCache class.
(tv@beamnet.de)
- Fix pgdb.py to send port as integer to lower level function
(dildog@l0pht.com)
- Change pg.py to speed up some operations
- Allow updates on tables with no primary keys.
Version 3.0
- Remove strlen() call from pglarge_write() and get size from object.
(Richard@Bouska.cz)
......
......@@ -89,6 +89,9 @@ version of PyGreSQL works with PostgreSQL 6.5 and Python 1.5.2.
that uses RPMs, then you can pick up an RPM at
ftp://ftp.druid.net/pub/distrib/pygresql.i386.rpm
* Note that if you are using the DB-API module you must also install
mxDateTime from http://starship.python.net/~lemburg/mxDateTime.html.
* Also, check out setup.py for an alternate method of installing the package.
You have two options. You can compile PyGreSQL as a stand-alone module
......@@ -114,7 +117,7 @@ GENERAL
STAND-ALONE
* In the directory containing pgmodule.c, run the following command
cc -fpic -shared -o _pg.so -I[pyInc] -I[pgInc] -L[pgLib] -lpq # -lcrypt # needed on some systems
cc -fpic -shared -o _pg.so -I[pyInc] -I[pgInc] -L[pgLib] -lpq pgmodule.c
where:
[pyInc] = path of the Python include (usually Python.h)
[pgInc] = path of the PostgreSQL include (usually postgres.h)
......@@ -126,6 +129,9 @@ STAND-ALONE
-DNO_SNPRINTF - if running a system with no snprintf call
-DNO_PQSOCKET - if running an older PostgreSQL
On some systems you may need to include -lcrypt in the list of libraries
to make it compile.
Define NO_PQSOCKET if you are using a version of PostgreSQL before 6.4
that does not have the PQsocket function. The other options will be
described in the next sections.
......@@ -1050,6 +1056,8 @@ The C module needs to be cleaned up and redundant code merged.
The DB-API module needs to be documented.
The fetch method should use real cursers.
6. Future directions
====================
......
Thanks to thilo@eevolute.com for this README and the RPM
Thanks to thilo@eevolute.com and others for this README and the RPM
Note: The precompiled RPM package is not available at www.eevolute.com.
You may use the spec file provided with PyGreSQL to build your
......@@ -36,3 +36,11 @@ bash# cp _pg.so /usr/lib/python1.5/lib-dynload
done!
Oliver White (ojw@muzak.iinet.net.au) sent me the following information
about installing on Debian.
Hi, I thought you might want to upgrade your documentation for PyGreSQL
to let people know they can get it by simply typing 'apt-get install
python-pygresql', on debian (duh). This would have saved me a lot of
trouble.
......@@ -13,21 +13,30 @@ def _quote(d, t):
if d == None:
return "NULL"
if t in ['int', 'decimal', 'seq']:
if d == "": return 0
if t in ['int', 'seq']:
if d == "": return "NULL"
return "%d" % int(d)
if t == 'decimal':
if d == "": return "NULL"
return "%f" % float(d)
if t == 'money':
if d == "": return '0.00'
if d == "": return "NULL"
return "'%.2f'" % float(d)
if t == 'bool':
if string.upper(d) in ['T', 'TRUE', 'Y', 'YES', 1, '1', 'ON']:
# Can't run upper() on these
if d in (0, 1): return ('f', 't')[d]
if string.upper(d) in ['T', 'TRUE', 'Y', 'YES', '1', 'ON']:
return "'t'"
else:
return "'f'"
if d == "": return "null"
if t == 'date' and d == '': return "NULL"
if t in ('inet', 'cidr') and d == '': return "NULL"
return "'%s'" % string.strip(re.sub("'", "''", \
re.sub("\\\\", "\\\\\\\\", "%s" %d)))
......@@ -68,7 +77,11 @@ class DB:
print self.debug % qstr
return self.db.query(qstr)
def pkey(self, cl):
# If third arg supplied set primary key to it
def pkey(self, cl, newpkey = None):
if newpkey:
self.__pkeys__[cl] = newpkey
# will raise an exception if primary key doesn't exist
return self.__pkeys__[cl]
......@@ -115,6 +128,8 @@ class DB:
l[attname] = 'date'
elif re.match("^date", typname):
l[attname] = 'date'
elif re.match("^timestamp", typname):
l[attname] = 'date'
elif re.match("^bool", typname):
l[attname] = 'bool'
elif re.match("^float", typname):
......@@ -129,15 +144,20 @@ class DB:
# return a tuple from a database
def get(self, cl, arg, keyname = None, view = 0):
if cl[-1] == '*': # need parent table name
xcl = cl[:-1]
else:
xcl = cl
if keyname == None: # use the primary key by default
keyname = self.__pkeys__[cl]
keyname = self.__pkeys__[xcl]
fnames = self.get_attnames(cl)
fnames = self.get_attnames(xcl)
if type(arg) == type({}):
# To allow users to work with multiple tables we munge the
# name when the key is "oid"
if keyname == 'oid': k = arg['oid_%s' % cl]
if keyname == 'oid': k = arg['oid_%s' % xcl]
else: k = arg[keyname]
else:
k = arg
......@@ -151,7 +171,7 @@ class DB:
(cl, keyname, _quote(k, fnames[keyname]))
else:
q = "SELECT oid AS oid_%s, %s FROM %s WHERE %s = %s" % \
(cl, string.join(fnames.keys(), ','),\
(xcl, string.join(fnames.keys(), ','),\
cl, keyname, _quote(k, fnames[keyname]))
if self.debug != None: print self.debug % q
......@@ -175,8 +195,7 @@ class DB:
n = []
for f in fnames.keys():
if a.has_key(f):
if a[f] == "": l.append("null")
else: l.append(_quote(a[f], fnames[f]))
l.append(_quote(a[f], fnames[f]))
n.append(f)
try:
......@@ -197,44 +216,37 @@ class DB:
# otherwise use the primary key. Fail if neither.
def update(self, cl, a):
foid = 'oid_%s' % cl
pk = self.__pkeys__[cl]
if a.has_key(foid):
where = "oid = %s" % a[foid]
elif a.has_key(pk):
where = "%s = '%s'" % (pk, a[pk])
elif self.__pkeys__.has_key(cl) and a.has_key(self.__pkeys__[cl]):
where = "%s = '%s'" % (self.__pkeys__[cl], a[self.__pkeys__[cl]])
else:
raise error, "Update needs key (%s) or oid as %s" % (pk, foid)
q = "SELECT oid FROM %s WHERE %s" % (cl, where)
if self.debug != None: print self.debug % q
res = self.db.query(q).getresult()
if len(res) < 1:
raise error, "No record in %s where %s (%s)" % \
(cl, where, sys.exc_value)
else: a[foid] = res[0][0]
raise error, "Update needs primary key or oid as %s" % foid
v = []
k = 0
fnames = self.get_attnames(cl)
for ff in fnames.keys():
if a.has_key(ff) and a[ff] != res[0][k]:
if a.has_key(ff):
v.append("%s = %s" % (ff, _quote(a[ff], fnames[ff])))
if v == []:
return None
try:
q = "UPDATE %s SET %s WHERE oid = %s" % \
(cl, string.join(v, ','), a[foid])
q = "UPDATE %s SET %s WHERE %s" % \
(cl, string.join(v, ','), where)
if self.debug != None: print self.debug % q
self.db.query(q)
except:
raise error, "Can't update %s: %s" % (cl, sys.exc_value)
# reload the dictionary to catch things modified by engine
return self.get(cl, a, 'oid')
if a.has_key(foid):
return self.get(cl, a, 'oid')
else:
return self.get(cl, a)
# At some point we will need a way to get defaults from a table
def clear(self, cl, a = {}):
......
......@@ -120,6 +120,8 @@ class pgdbTypeCache:
pass
elif typ == BINARY:
pass
elif typ == BOOL:
value = (value[:1] in ['t','T'])
elif typ == INTEGER:
value = int(value)
elif typ == LONG:
......@@ -322,7 +324,7 @@ def connect(dsn = None, user = None, password = None, host = None, database = No
try:
params = string.split(host, ":")
dbhost = params[0]
dbport = params[1]
dbport = int(params[1])
except:
pass
......
......@@ -44,7 +44,7 @@
#define CASHOID 790
static PyObject *PGError;
static const char *PyPgVersion = "3.0";
static const char *PyPgVersion = "3.1";
/* taken from fileobject.c */
#define BUF(v) PyString_AS_STRING((PyStringObject *)(v))
......@@ -1502,7 +1502,7 @@ pgconnect(pgobject *self, PyObject *args, PyObject *dict)
if (pgport != -1)
{
bzero(port_buffer, sizeof(port_buffer));
memset(port_buffer, 0, sizeof(port_buffer));
sprintf(port_buffer, "%d", pgport);
npgobj->cnx = PQsetdbLogin(pghost, port_buffer, pgopt, pgtty, pgdbname,
pguser, pgpasswd);
......@@ -2976,8 +2976,7 @@ pgsetdefpasswd(PyObject * self, PyObject *args)
if (!PyArg_ParseTuple(args, "z", &temp))
{
PyErr_SetString(PyExc_TypeError,
"set_defpasswd(password), with password (string/
None).");
"set_defpasswd(password), with password (string/None).");
return NULL;
}
......
......@@ -24,7 +24,7 @@ optional_libs=['pq']
from distutils.core import setup
setup (name = "PyGreSQL",
version = "3.0",
version = "3.1",
description = "Python PostgreSQL Interfaces",
author = "D'Arcy J. M. Cain",
author_email = "darcy@druid.net",
......
......@@ -10,7 +10,7 @@ MODULE BASICS.PY : BASIC POSTGRES SQL COMMANDS TUTORIAL
This module is designed for being imported from python prompt
In order to run the samples included here, first create a connection
using : cnx = advanced.DB(...)
using : cnx = basics.DB(...)
The "..." should be replaced with whatever arguments you need to open an
existing database. Usually all you need is the name of the database and,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册