summaryrefslogtreecommitdiff
path: root/python/skytools
diff options
context:
space:
mode:
Diffstat (limited to 'python/skytools')
-rw-r--r--python/skytools/__init__.py2
-rw-r--r--python/skytools/dbstruct.py4
-rw-r--r--python/skytools/quoting.py9
-rw-r--r--python/skytools/scripting.py5
-rw-r--r--python/skytools/skylog.py10
-rw-r--r--python/skytools/sqltools.py39
6 files changed, 57 insertions, 12 deletions
diff --git a/python/skytools/__init__.py b/python/skytools/__init__.py
index ed2b39bc..f1ef7197 100644
--- a/python/skytools/__init__.py
+++ b/python/skytools/__init__.py
@@ -4,7 +4,7 @@
from config import *
from dbstruct import *
from gzlog import *
-from quoting import *
from scripting import *
from sqltools import *
+from quoting import *
diff --git a/python/skytools/dbstruct.py b/python/skytools/dbstruct.py
index 22333429..ece0ea54 100644
--- a/python/skytools/dbstruct.py
+++ b/python/skytools/dbstruct.py
@@ -364,8 +364,8 @@ class TableStruct(object):
return res
def test():
- import psycopg
- db = psycopg.connect("dbname=fooz")
+ from skytools import connect_database
+ db = connect_database("dbname=fooz")
curs = db.cursor()
s = TableStruct(curs, "public.data1")
diff --git a/python/skytools/quoting.py b/python/skytools/quoting.py
index 0ce50080..7df56fee 100644
--- a/python/skytools/quoting.py
+++ b/python/skytools/quoting.py
@@ -2,7 +2,12 @@
"""Various helpers for string quoting/unquoting."""
-import psycopg, urllib, re
+import urllib, re
+
+try:
+ from psycopg2.extensions import QuotedString
+except:
+ from psycopg import QuotedString
__all__ = [
"quote_literal", "quote_copy", "quote_bytea_raw",
@@ -23,7 +28,7 @@ def quote_literal(s):
if s == None:
return "null"
- s = psycopg.QuotedString(str(s))
+ s = QuotedString(str(s))
return str(s)
def quote_copy(s):
diff --git a/python/skytools/scripting.py b/python/skytools/scripting.py
index 456fff69..136c89ef 100644
--- a/python/skytools/scripting.py
+++ b/python/skytools/scripting.py
@@ -1,10 +1,11 @@
"""Useful functions and classes for database scripts."""
-import sys, os, signal, psycopg, optparse, traceback, time
+import sys, os, signal, optparse, traceback, time
import logging, logging.handlers, logging.config
from skytools.config import *
+from skytools.sqltools import connect_database
import skytools.skylog
__all__ = ['daemonize', 'run_single_process', 'DBScript',
@@ -178,7 +179,7 @@ class DBCachedConn(object):
# new conn?
if not self.conn:
self.isolation_level = isolation_level
- self.conn = psycopg.connect(self.loc)
+ self.conn = connect_database(self.loc)
self.conn.set_isolation_level(isolation_level)
self.conn_time = time.time()
diff --git a/python/skytools/skylog.py b/python/skytools/skylog.py
index 2f6344ae..bde6f153 100644
--- a/python/skytools/skylog.py
+++ b/python/skytools/skylog.py
@@ -1,10 +1,12 @@
"""Our log handlers for Python's logging package.
"""
-import sys, os, time, socket, psycopg
+import sys, os, time, socket
import logging, logging.handlers
-from quoting import quote_json
+from skytools.quoting import quote_json
+from skytools.sqltools import connect_database
+
# configurable file logger
class EasyRotatingFileHandler(logging.handlers.RotatingFileHandler):
@@ -93,9 +95,9 @@ class LogDBHandler(logging.handlers.SocketHandler):
def makeSocket(self):
"""Create server connection.
- In this case its not socket but psycopg conection."""
+ In this case its not socket but database connection."""
- db = psycopg.connect(self.connect_string)
+ db = connect_database(self.connect_string)
db.autocommit(1)
return db
diff --git a/python/skytools/sqltools.py b/python/skytools/sqltools.py
index f9144031..e0d53bf8 100644
--- a/python/skytools/sqltools.py
+++ b/python/skytools/sqltools.py
@@ -12,9 +12,33 @@ __all__ = [
"exists_function", "exists_language", "Snapshot", "magic_insert",
"db_copy_from_dict", "db_copy_from_list", "CopyPipe", "full_copy",
"DBObject", "DBSchema", "DBTable", "DBFunction", "DBLanguage",
- "db_install"
+ "db_install", "connect_database"
]
+
+try:
+ ##from psycopg2.psycopg1 import connect as _pgconnect
+ # psycopg2.psycopg1.cursor is too backwards compatible,
+ # to the point of avoiding optimized access.
+
+ ## only backwards compat thing we need is dict* methods
+ import psycopg2.extensions, psycopg2.extras
+ class _CompatCursor(psycopg2.extras.DictCursor):
+ """Regular psycopg2 DictCursor with dict* methods."""
+ dictfetchone = psycopg2.extras.DictCursor.fetchone
+ dictfetchall = psycopg2.extras.DictCursor.fetchall
+ dictfetchmany = psycopg2.extras.DictCursor.fetchmany
+ class _CompatConnection(psycopg2.extensions.connection):
+ """Connection object that uses _CompatCursor."""
+ def cursor(self):
+ return psycopg2.extensions.connection.cursor(self, cursor_factory = _CompatCursor)
+ def _pgconnect(cstr):
+ """Create a psycopg2 connection."""
+ return _CompatConnection(cstr)
+except ImportError:
+ # use psycopg 1
+ from psycopg import connect as _pgconnect
+
#
# Fully qualified table name
#
@@ -412,3 +436,16 @@ def db_install(curs, list, log = None):
if log:
log.info('%s is installed' % obj.name)
+def connect_database(connstr):
+ """Create a db connection with connect_timeout option.
+
+ Default connect_timeout is 15, to change put it directly into dsn.
+ """
+
+ # allow override
+ if connstr.find("connect_timeout") < 0:
+ connstr += " connect_timeout=15"
+
+ # create connection
+ return _pgconnect(connstr)
+