summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql/base.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql/base.py')
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py148
1 files changed, 86 insertions, 62 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index f1061c90b..c7e84751d 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -154,9 +154,10 @@ Operator Classes
^^^^^^^^^^^^^^^^^
PostgreSQL allows the specification of an *operator class* for each column of
-an index (see http://www.postgresql.org/docs/8.3/interactive/indexes-opclass.html).
-The :class:`.Index` construct allows these to be specified via the ``postgresql_ops``
-keyword argument::
+an index (see
+http://www.postgresql.org/docs/8.3/interactive/indexes-opclass.html).
+The :class:`.Index` construct allows these to be specified via the
+``postgresql_ops`` keyword argument::
Index('my_index', my_table.c.id, my_table.c.data,
postgresql_ops={
@@ -168,15 +169,15 @@ keyword argument::
``postgresql_ops`` keyword argument to :class:`.Index` construct.
Note that the keys in the ``postgresql_ops`` dictionary are the "key" name of
-the :class:`.Column`, i.e. the name used to access it from the ``.c`` collection
-of :class:`.Table`, which can be configured to be different than the actual
-name of the column as expressed in the database.
+the :class:`.Column`, i.e. the name used to access it from the ``.c``
+collection of :class:`.Table`, which can be configured to be different than
+the actual name of the column as expressed in the database.
Index Types
^^^^^^^^^^^^
-PostgreSQL provides several index types: B-Tree, Hash, GiST, and GIN, as well as
-the ability for users to create their own (see
+PostgreSQL provides several index types: B-Tree, Hash, GiST, and GIN, as well
+as the ability for users to create their own (see
http://www.postgresql.org/docs/8.3/static/indexes-types.html). These can be
specified on :class:`.Index` using the ``postgresql_using`` keyword argument::
@@ -226,24 +227,30 @@ _DECIMAL_TYPES = (1231, 1700)
_FLOAT_TYPES = (700, 701, 1021, 1022)
_INT_TYPES = (20, 21, 23, 26, 1005, 1007, 1016)
+
class BYTEA(sqltypes.LargeBinary):
__visit_name__ = 'BYTEA'
+
class DOUBLE_PRECISION(sqltypes.Float):
__visit_name__ = 'DOUBLE_PRECISION'
+
class INET(sqltypes.TypeEngine):
__visit_name__ = "INET"
PGInet = INET
+
class CIDR(sqltypes.TypeEngine):
__visit_name__ = "CIDR"
PGCidr = CIDR
+
class MACADDR(sqltypes.TypeEngine):
__visit_name__ = "MACADDR"
PGMacAddr = MACADDR
+
class TIMESTAMP(sqltypes.TIMESTAMP):
def __init__(self, timezone=False, precision=None):
super(TIMESTAMP, self).__init__(timezone=timezone)
@@ -255,6 +262,7 @@ class TIME(sqltypes.TIME):
super(TIME, self).__init__(timezone=timezone)
self.precision = precision
+
class INTERVAL(sqltypes.TypeEngine):
"""Postgresql INTERVAL type.
@@ -263,6 +271,7 @@ class INTERVAL(sqltypes.TypeEngine):
"""
__visit_name__ = 'INTERVAL'
+
def __init__(self, precision=None):
self.precision = precision
@@ -276,8 +285,10 @@ class INTERVAL(sqltypes.TypeEngine):
PGInterval = INTERVAL
+
class BIT(sqltypes.TypeEngine):
__visit_name__ = 'BIT'
+
def __init__(self, length=None, varying=False):
if not varying:
# BIT without VARYING defaults to length 1
@@ -289,6 +300,7 @@ class BIT(sqltypes.TypeEngine):
PGBit = BIT
+
class UUID(sqltypes.TypeEngine):
"""Postgresql UUID type.
@@ -313,8 +325,8 @@ class UUID(sqltypes.TypeEngine):
"""
if as_uuid and _python_UUID is None:
raise NotImplementedError(
- "This version of Python does not support the native UUID type."
- )
+ "This version of Python does not support the native UUID type."
+ )
self.as_uuid = as_uuid
def bind_processor(self, dialect):
@@ -339,9 +351,11 @@ class UUID(sqltypes.TypeEngine):
PGUuid = UUID
+
class _Slice(expression.ColumnElement):
__visit_name__ = 'slice'
type = sqltypes.NULLTYPE
+
def __init__(self, slice_, source_comparator):
self.start = source_comparator._check_literal(
source_comparator.expr,
@@ -350,6 +364,7 @@ class _Slice(expression.ColumnElement):
source_comparator.expr,
operators.getitem, slice_.stop)
+
class array(expression.Tuple):
"""A Postgresql ARRAY literal.
@@ -399,6 +414,7 @@ class array(expression.Tuple):
def self_group(self, against):
return self
+
class ARRAY(sqltypes.Concatenable, sqltypes.TypeEngine):
"""Postgresql ARRAY type.
@@ -436,8 +452,8 @@ class ARRAY(sqltypes.Concatenable, sqltypes.TypeEngine):
to optimize itself to expect exactly that number of dimensions.
Note that Postgresql itself still allows N dimensions with such a type.
- SQL expressions of type :class:`.ARRAY` have support for "index" and "slice"
- behavior. The Python ``[]`` operator works normally here, given
+ SQL expressions of type :class:`.ARRAY` have support for "index" and
+ "slice" behavior. The Python ``[]`` operator works normally here, given
integer indexes or slices. Note that Postgresql arrays default
to 1-based indexing. The operator produces binary expression
constructs which will produce the appropriate SQL, both for
@@ -539,6 +555,7 @@ class ARRAY(sqltypes.Concatenable, sqltypes.TypeEngine):
item_proc = self.item_type.\
dialect_impl(dialect).\
bind_processor(dialect)
+
def process(value):
if value is None:
return value
@@ -554,6 +571,7 @@ class ARRAY(sqltypes.Concatenable, sqltypes.TypeEngine):
item_proc = self.item_type.\
dialect_impl(dialect).\
result_processor(dialect, coltype)
+
def process(value):
if value is None:
return value
@@ -567,6 +585,7 @@ class ARRAY(sqltypes.Concatenable, sqltypes.TypeEngine):
PGArray = ARRAY
+
class ENUM(sqltypes.Enum):
"""Postgresql ENUM type.
@@ -703,45 +722,44 @@ class ENUM(sqltypes.Enum):
self.drop(bind=bind, checkfirst=checkfirst)
colspecs = {
- sqltypes.Interval:INTERVAL,
- sqltypes.Enum:ENUM,
+ sqltypes.Interval: INTERVAL,
+ sqltypes.Enum: ENUM,
}
ischema_names = {
- 'integer' : INTEGER,
- 'bigint' : BIGINT,
- 'smallint' : SMALLINT,
- 'character varying' : VARCHAR,
- 'character' : CHAR,
- '"char"' : sqltypes.String,
- 'name' : sqltypes.String,
- 'text' : TEXT,
- 'numeric' : NUMERIC,
- 'float' : FLOAT,
- 'real' : REAL,
+ 'integer': INTEGER,
+ 'bigint': BIGINT,
+ 'smallint': SMALLINT,
+ 'character varying': VARCHAR,
+ 'character': CHAR,
+ '"char"': sqltypes.String,
+ 'name': sqltypes.String,
+ 'text': TEXT,
+ 'numeric': NUMERIC,
+ 'float': FLOAT,
+ 'real': REAL,
'inet': INET,
'cidr': CIDR,
'uuid': UUID,
'bit': BIT,
'bit varying': BIT,
'macaddr': MACADDR,
- 'double precision' : DOUBLE_PRECISION,
- 'timestamp' : TIMESTAMP,
- 'timestamp with time zone' : TIMESTAMP,
- 'timestamp without time zone' : TIMESTAMP,
- 'time with time zone' : TIME,
- 'time without time zone' : TIME,
- 'date' : DATE,
+ 'double precision': DOUBLE_PRECISION,
+ 'timestamp': TIMESTAMP,
+ 'timestamp with time zone': TIMESTAMP,
+ 'timestamp without time zone': TIMESTAMP,
+ 'time with time zone': TIME,
+ 'time without time zone': TIME,
+ 'date': DATE,
'time': TIME,
- 'bytea' : BYTEA,
- 'boolean' : BOOLEAN,
- 'interval':INTERVAL,
- 'interval year to month':INTERVAL,
- 'interval day to second':INTERVAL,
+ 'bytea': BYTEA,
+ 'boolean': BOOLEAN,
+ 'interval': INTERVAL,
+ 'interval year to month': INTERVAL,
+ 'interval day to second': INTERVAL,
}
-
class PGCompiler(compiler.SQLCompiler):
def visit_array(self, element, **kw):
@@ -814,7 +832,7 @@ class PGCompiler(compiler.SQLCompiler):
elif isinstance(select._distinct, (list, tuple)):
return "DISTINCT ON (" + ', '.join(
[self.process(col) for col in select._distinct]
- )+ ") "
+ ) + ") "
else:
return "DISTINCT ON (" + self.process(select._distinct) + ") "
else:
@@ -861,6 +879,7 @@ class PGCompiler(compiler.SQLCompiler):
return "EXTRACT(%s FROM %s)" % (
field, self.process(expr))
+
class PGDDLCompiler(compiler.DDLCompiler):
def get_column_specification(self, column, **kwargs):
colspec = self.preparer.format_column(column)
@@ -1046,6 +1065,7 @@ class PGIdentifierPreparer(compiler.IdentifierPreparer):
name = self.quote_schema(type_.schema, type_.quote) + "." + name
return name
+
class PGInspector(reflection.Inspector):
def __init__(self, conn):
@@ -1057,11 +1077,14 @@ class PGInspector(reflection.Inspector):
return self.dialect.get_table_oid(self.bind, table_name, schema,
info_cache=self.info_cache)
+
class CreateEnumType(schema._CreateDropBase):
- __visit_name__ = "create_enum_type"
+ __visit_name__ = "create_enum_type"
+
class DropEnumType(schema._CreateDropBase):
- __visit_name__ = "drop_enum_type"
+ __visit_name__ = "drop_enum_type"
+
class PGExecutionContext(default.DefaultExecutionContext):
def fire_sequence(self, seq, type_):
@@ -1091,7 +1114,8 @@ class PGExecutionContext(default.DefaultExecutionContext):
col = column.name
tab = tab[0:29 + max(0, (29 - len(col)))]
col = col[0:29 + max(0, (29 - len(tab)))]
- column._postgresql_seq_name = seq_name = "%s_%s_seq" % (tab, col)
+ name = "%s_%s_seq" % (tab, col)
+ column._postgresql_seq_name = seq_name = name
sch = column.table.schema
if sch is not None:
@@ -1105,6 +1129,7 @@ class PGExecutionContext(default.DefaultExecutionContext):
return super(PGExecutionContext, self).get_insert_default(column)
+
class PGDialect(default.DefaultDialect):
name = 'postgresql'
supports_alter = True
@@ -1226,9 +1251,10 @@ class PGDialect(default.DefaultDialect):
return connection.scalar("select current_schema()")
def has_schema(self, connection, schema):
+ query = "select nspname from pg_namespace where lower(nspname)=:schema"
cursor = connection.execute(
sql.text(
- "select nspname from pg_namespace where lower(nspname)=:schema",
+ query,
bindparams=[
sql.bindparam(
'schema', unicode(schema.lower()),
@@ -1365,7 +1391,7 @@ class PGDialect(default.DefaultDialect):
sql.bindparam('table_name', type_=sqltypes.Unicode),
sql.bindparam('schema', type_=sqltypes.Unicode)
],
- typemap={'oid':sqltypes.Integer}
+ typemap={'oid': sqltypes.Integer}
)
c = connection.execute(s, table_name=table_name, schema=schema)
table_oid = c.scalar()
@@ -1404,12 +1430,11 @@ class PGDialect(default.DefaultDialect):
"AND '%s' = (select nspname from pg_namespace n "
"where n.oid = c.relnamespace) " %
current_schema,
- typemap = {'relname':sqltypes.Unicode}
+ typemap={'relname': sqltypes.Unicode}
)
)
return [row[0] for row in result]
-
@reflection.cache
def get_view_names(self, connection, schema=None, **kw):
if schema is not None:
@@ -1484,8 +1509,8 @@ class PGDialect(default.DefaultDialect):
# format columns
columns = []
for name, format_type, default, notnull, attnum, table_oid in rows:
- column_info = self._get_column_info(name, format_type, default,
- notnull, domains, enums, schema)
+ column_info = self._get_column_info(
+ name, format_type, default, notnull, domains, enums, schema)
columns.append(column_info)
return columns
@@ -1670,8 +1695,8 @@ class PGDialect(default.DefaultDialect):
"""
t = sql.text(FK_SQL, typemap={
- 'conname':sqltypes.Unicode,
- 'condef':sqltypes.Unicode})
+ 'conname': sqltypes.Unicode,
+ 'condef': sqltypes.Unicode})
c = connection.execute(t, table=table_oid)
fkeys = []
for conname, condef, conschema in c.fetchall():
@@ -1697,11 +1722,11 @@ class PGDialect(default.DefaultDialect):
referred_columns = [preparer._unquote_identifier(x)
for x in re.split(r'\s*,\s', referred_columns)]
fkey_d = {
- 'name' : conname,
- 'constrained_columns' : constrained_columns,
- 'referred_schema' : referred_schema,
- 'referred_table' : referred_table,
- 'referred_columns' : referred_columns
+ 'name': conname,
+ 'constrained_columns': constrained_columns,
+ 'referred_schema': referred_schema,
+ 'referred_table': referred_table,
+ 'referred_columns': referred_columns
}
fkeys.append(fkey_d)
return fkeys
@@ -1732,7 +1757,7 @@ class PGDialect(default.DefaultDialect):
i.relname
"""
- t = sql.text(IDX_SQL, typemap={'attname':sqltypes.Unicode})
+ t = sql.text(IDX_SQL, typemap={'attname': sqltypes.Unicode})
c = connection.execute(t, table_oid=table_oid)
index_names = {}
@@ -1756,7 +1781,7 @@ class PGDialect(default.DefaultDialect):
if idx_name in index_names:
index_d = index_names[idx_name]
else:
- index_d = {'column_names':[]}
+ index_d = {'column_names': []}
indexes.append(index_d)
index_names[idx_name] = index_d
index_d['name'] = idx_name
@@ -1785,8 +1810,8 @@ class PGDialect(default.DefaultDialect):
"""
s = sql.text(SQL_ENUMS, typemap={
- 'attname':sqltypes.Unicode,
- 'label':sqltypes.Unicode})
+ 'attname': sqltypes.Unicode,
+ 'label': sqltypes.Unicode})
c = connection.execute(s)
enums = {}
@@ -1823,7 +1848,7 @@ class PGDialect(default.DefaultDialect):
WHERE t.typtype = 'd'
"""
- s = sql.text(SQL_DOMAINS, typemap={'attname':sqltypes.Unicode})
+ s = sql.text(SQL_DOMAINS, typemap={'attname': sqltypes.Unicode})
c = connection.execute(s)
domains = {}
@@ -1840,10 +1865,9 @@ class PGDialect(default.DefaultDialect):
name = "%s.%s" % (domain['schema'], domain['name'])
domains[name] = {
- 'attype':attype,
+ 'attype': attype,
'nullable': domain['nullable'],
'default': domain['default']
}
return domains
-