Various fixes for bugs found in use of psycopg2.
This commit is contained in:
@@ -76,7 +76,10 @@ def database_exists(url):
|
|||||||
|
|
||||||
url = copy(make_url(url))
|
url = copy(make_url(url))
|
||||||
database = url.database
|
database = url.database
|
||||||
url.database = None
|
if url.drivername.startswith('postgresql'):
|
||||||
|
url.database = 'template1'
|
||||||
|
else:
|
||||||
|
url.database = None
|
||||||
|
|
||||||
engine = sa.create_engine(url)
|
engine = sa.create_engine(url)
|
||||||
|
|
||||||
@@ -126,7 +129,10 @@ def create_database(url, encoding='utf8'):
|
|||||||
url = copy(make_url(url))
|
url = copy(make_url(url))
|
||||||
|
|
||||||
database = url.database
|
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
|
url.database = None
|
||||||
|
|
||||||
engine = sa.create_engine(url)
|
engine = sa.create_engine(url)
|
||||||
@@ -137,7 +143,8 @@ def create_database(url, encoding='utf8'):
|
|||||||
engine.raw_connection().set_isolation_level(
|
engine.raw_connection().set_isolation_level(
|
||||||
ISOLATION_LEVEL_AUTOCOMMIT)
|
ISOLATION_LEVEL_AUTOCOMMIT)
|
||||||
|
|
||||||
text = "CREATE DATABASE %s ENCODING = '%s'" % (database, encoding)
|
text = "CREATE DATABASE %s ENCODING '%s' TEMPLATE template0" % (
|
||||||
|
database, encoding)
|
||||||
engine.execute(text)
|
engine.execute(text)
|
||||||
|
|
||||||
elif engine.dialect.name == 'mysql':
|
elif engine.dialect.name == 'mysql':
|
||||||
@@ -168,7 +175,10 @@ def drop_database(url):
|
|||||||
url = copy(make_url(url))
|
url = copy(make_url(url))
|
||||||
|
|
||||||
database = url.database
|
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
|
url.database = None
|
||||||
|
|
||||||
engine = sa.create_engine(url)
|
engine = sa.create_engine(url)
|
||||||
@@ -179,6 +189,17 @@ def drop_database(url):
|
|||||||
elif engine.dialect.name == 'postgresql' and engine.driver == 'psycopg2':
|
elif engine.dialect.name == 'postgresql' and engine.driver == 'psycopg2':
|
||||||
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
||||||
engine.raw_connection().set_isolation_level(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
|
text = "DROP DATABASE %s" % database
|
||||||
engine.execute(text)
|
engine.execute(text)
|
||||||
|
|
||||||
|
@@ -143,7 +143,7 @@ class PasswordType(types.TypeDecorator, ScalarCoercible):
|
|||||||
scheme = getattr(__import__('passlib.hash').hash, name)
|
scheme = getattr(__import__('passlib.hash').hash, name)
|
||||||
length = 4 + len(scheme.name)
|
length = 4 + len(scheme.name)
|
||||||
length += len(str(getattr(scheme, 'max_rounds', '')))
|
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(
|
length += getattr(
|
||||||
scheme,
|
scheme,
|
||||||
'encoded_checksum_size',
|
'encoded_checksum_size',
|
||||||
|
@@ -25,14 +25,15 @@ class UUIDType(types.TypeDecorator, ScalarCoercible):
|
|||||||
|
|
||||||
python_type = uuid.UUID
|
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.
|
:param binary: Whether to use a BINARY(16) or CHAR(32) fallback.
|
||||||
"""
|
"""
|
||||||
self.binary = binary
|
self.binary = binary
|
||||||
|
self.native = native
|
||||||
|
|
||||||
def load_dialect_impl(self, dialect):
|
def load_dialect_impl(self, dialect):
|
||||||
if dialect.name == 'postgresql':
|
if dialect.name == 'postgresql' and self.native:
|
||||||
# Use the native UUID type.
|
# Use the native UUID type.
|
||||||
return dialect.type_descriptor(postgresql.UUID())
|
return dialect.type_descriptor(postgresql.UUID())
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ class UUIDType(types.TypeDecorator, ScalarCoercible):
|
|||||||
if not isinstance(value, uuid.UUID):
|
if not isinstance(value, uuid.UUID):
|
||||||
value = self._coerce(value)
|
value = self._coerce(value)
|
||||||
|
|
||||||
if dialect.name == 'postgresql':
|
if self.native and dialect.name == 'postgresql':
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
return value.bytes if self.binary else value.hex
|
return value.bytes if self.binary else value.hex
|
||||||
@@ -68,7 +69,7 @@ class UUIDType(types.TypeDecorator, ScalarCoercible):
|
|||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
if dialect.name == 'postgresql':
|
if self.native and dialect.name == 'postgresql':
|
||||||
return uuid.UUID(value)
|
return uuid.UUID(value)
|
||||||
|
|
||||||
return uuid.UUID(bytes=value) if self.binary else uuid.UUID(value)
|
return uuid.UUID(bytes=value) if self.binary else uuid.UUID(value)
|
||||||
|
Reference in New Issue
Block a user