diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-03-26 12:03:54 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-03-26 12:03:54 -0400 |
| commit | db052dfba8db282516c353b1dc3984668ce93538 (patch) | |
| tree | be120e5c9486d45fe22b6f247f779fa90ea3c098 /lib/sqlalchemy/dialects/postgresql | |
| parent | 832d508816aae51af1f08e37a0e964ce41755104 (diff) | |
| download | sqlalchemy-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.py | 81 |
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: |
