summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-03-26 12:03:54 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2010-03-26 12:03:54 -0400
commitdb052dfba8db282516c353b1dc3984668ce93538 (patch)
treebe120e5c9486d45fe22b6f247f779fa90ea3c098 /lib/sqlalchemy/dialects/postgresql
parent832d508816aae51af1f08e37a0e964ce41755104 (diff)
downloadsqlalchemy-db052dfba8db282516c353b1dc3984668ce93538.tar.gz
- the TIME and TIMESTAMP types are now availble from the
postgresql dialect directly, which add the PG-specific argument 'precision' to both. 'precision' and 'timezone' are correctly reflected for both TIME and TIMEZONE types. [ticket:997]
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql')
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py81
1 files changed, 53 insertions, 28 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index f45fc9671..bef2f1c61 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -78,7 +78,7 @@ from sqlalchemy import types as sqltypes
from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, VARCHAR, \
CHAR, TEXT, FLOAT, NUMERIC, \
- TIMESTAMP, TIME, DATE, BOOLEAN
+ DATE, BOOLEAN
class REAL(sqltypes.Float):
__visit_name__ = "REAL"
@@ -101,6 +101,16 @@ 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)
+ self.precision = precision
+
+class TIME(sqltypes.TIME):
+ def __init__(self, timezone=False, precision=None):
+ super(TIME, self).__init__(timezone=timezone)
+ self.precision = precision
+
class INTERVAL(sqltypes.TypeEngine):
__visit_name__ = 'INTERVAL'
def __init__(self, precision=None):
@@ -466,10 +476,16 @@ class PGTypeCompiler(compiler.GenericTypeCompiler):
return self.dialect.identifier_preparer.format_type(type_)
def visit_TIMESTAMP(self, type_):
- return "TIMESTAMP " + (type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE"
+ return "TIMESTAMP%s %s" % (
+ getattr(type_, 'precision', None) and "(%d)" % type_.precision or "",
+ (type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE"
+ )
def visit_TIME(self, type_):
- return "TIME " + (type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE"
+ return "TIME%s %s" % (
+ getattr(type_, 'precision', None) and "(%d)" % type_.precision or "",
+ (type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE"
+ )
def visit_INTERVAL(self, type_):
if type_.precision is not None:
@@ -875,39 +891,48 @@ class PGDialect(default.DefaultDialect):
# format columns
columns = []
for name, format_type, default, notnull, attnum, table_oid in rows:
- ## strip (30) from character varying(30)
- attype = re.search('([^\([]+)', format_type).group(1)
+ ## strip (5) from character varying(5), timestamp(5) with time zone, etc
+ attype = re.sub(r'\([\d,]+\)', '', format_type)
+
+ # strip '[]' from integer[], etc.
+ attype = re.sub(r'\[\]', '', attype)
+
nullable = not notnull
is_array = format_type.endswith('[]')
- try:
- charlen = re.search('\(([\d,]+)\)', format_type).group(1)
- except:
- charlen = False
- numericprec = False
- numericscale = False
+ charlen = re.search('\(([\d,]+)\)', format_type)
+ if charlen:
+ charlen = charlen.group(1)
+ kwargs = {}
+
if attype == 'numeric':
- if charlen is False:
- numericprec, numericscale = (None, None)
+ if charlen:
+ prec, scale = charlen.split(',')
+ args = (int(prec), int(scale))
else:
- numericprec, numericscale = charlen.split(',')
- charlen = False
+ args = ()
elif attype == 'double precision':
- numericprec, numericscale = (53, False)
- charlen = False
+ args = (53, )
elif attype == 'integer':
- numericprec, numericscale = (32, 0)
- charlen = False
- args = []
- for a in (charlen, numericprec, numericscale):
- if a is None:
- args.append(None)
- elif a is not False:
- args.append(int(a))
- kwargs = {}
- if attype == 'timestamp with time zone':
+ args = (32, 0)
+ elif attype in ('timestamp with time zone', 'time with time zone'):
kwargs['timezone'] = True
- elif attype == 'timestamp without time zone':
+ if charlen:
+ kwargs['precision'] = int(charlen)
+ args = ()
+ elif attype in ('timestamp without time zone', 'time without time zone', 'time'):
kwargs['timezone'] = False
+ if charlen:
+ kwargs['precision'] = int(charlen)
+ args = ()
+ elif attype in ('interval','interval year to month','interval day to second'):
+ if charlen:
+ kwargs['precision'] = int(charlen)
+ args = ()
+ elif charlen:
+ args = (int(charlen),)
+ else:
+ args = ()
+
if attype in self.ischema_names:
coltype = self.ischema_names[attype]
elif attype in enums: