Various fixes for bugs found in use of psycopg2.

This commit is contained in:
Ryan Leckey
2014-05-28 19:56:19 -07:00
parent 35d577f271
commit 5d741c1666
3 changed files with 31 additions and 9 deletions

View File

@@ -76,6 +76,9 @@ def database_exists(url):
url = copy(make_url(url))
database = url.database
if url.drivername.startswith('postgresql'):
url.database = 'template1'
else:
url.database = None
engine = sa.create_engine(url)
@@ -126,7 +129,10 @@ def create_database(url, encoding='utf8'):
url = copy(make_url(url))
database = url.database
if not url.drivername.startswith('sqlite'):
if url.drivername.startswith('postgresql'):
url.database = 'template1'
elif not url.drivername.startswith('sqlite'):
url.database = None
engine = sa.create_engine(url)
@@ -137,7 +143,8 @@ def create_database(url, encoding='utf8'):
engine.raw_connection().set_isolation_level(
ISOLATION_LEVEL_AUTOCOMMIT)
text = "CREATE DATABASE %s ENCODING = '%s'" % (database, encoding)
text = "CREATE DATABASE %s ENCODING '%s' TEMPLATE template0" % (
database, encoding)
engine.execute(text)
elif engine.dialect.name == 'mysql':
@@ -168,7 +175,10 @@ def drop_database(url):
url = copy(make_url(url))
database = url.database
if not url.drivername.startswith('sqlite'):
if url.drivername.startswith('postgresql'):
url.database = 'template1'
elif not url.drivername.startswith('sqlite'):
url.database = None
engine = sa.create_engine(url)
@@ -179,6 +189,17 @@ def drop_database(url):
elif engine.dialect.name == 'postgresql' and engine.driver == 'psycopg2':
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
engine.raw_connection().set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
# Disconnect all users from the database we are dropping.
text = '''
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '%s'
AND pid <> pg_backend_pid()
''' % database
engine.execute(text)
# Drop the database.
text = "DROP DATABASE %s" % database
engine.execute(text)

View File

@@ -143,7 +143,7 @@ class PasswordType(types.TypeDecorator, ScalarCoercible):
scheme = getattr(__import__('passlib.hash').hash, name)
length = 4 + len(scheme.name)
length += len(str(getattr(scheme, 'max_rounds', '')))
length += getattr(scheme, 'max_salt_size', 0)
length += (getattr(scheme, 'max_salt_size', 0) or 0)
length += getattr(
scheme,
'encoded_checksum_size',

View File

@@ -25,14 +25,15 @@ class UUIDType(types.TypeDecorator, ScalarCoercible):
python_type = uuid.UUID
def __init__(self, binary=True):
def __init__(self, binary=True, native=True):
"""
:param binary: Whether to use a BINARY(16) or CHAR(32) fallback.
"""
self.binary = binary
self.native = native
def load_dialect_impl(self, dialect):
if dialect.name == 'postgresql':
if dialect.name == 'postgresql' and self.native:
# Use the native UUID type.
return dialect.type_descriptor(postgresql.UUID())
@@ -59,7 +60,7 @@ class UUIDType(types.TypeDecorator, ScalarCoercible):
if not isinstance(value, uuid.UUID):
value = self._coerce(value)
if dialect.name == 'postgresql':
if self.native and dialect.name == 'postgresql':
return str(value)
return value.bytes if self.binary else value.hex
@@ -68,7 +69,7 @@ class UUIDType(types.TypeDecorator, ScalarCoercible):
if value is None:
return value
if dialect.name == 'postgresql':
if self.native and dialect.name == 'postgresql':
return uuid.UUID(value)
return uuid.UUID(bytes=value) if self.binary else uuid.UUID(value)