]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- support for None as precision/length in numeric types for postgres, sqlite, mysql
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 9 Dec 2006 03:21:18 +0000 (03:21 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 9 Dec 2006 03:21:18 +0000 (03:21 +0000)
- postgres reflection fixes: [ticket:349] [ticket:382]

CHANGES
lib/sqlalchemy/databases/mysql.py
lib/sqlalchemy/databases/postgres.py
lib/sqlalchemy/databases/sqlite.py
test/engine/reflection.py

diff --git a/CHANGES b/CHANGES
index 8614d8dde8e4191903bdbef82cb2e4f6d3b98804..21a2307cd18a76782dcf28597ccaa1c407d1aee9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -11,6 +11,7 @@ accidentally [ticket:387]
 to have it be weak referencing, use create_session(weak_identity_map=True)
 - MySQL detects errors 2006 (server has gone away) and 2014
 (commands out of sync) and invalidates the connection on which it occured.
+- postgres reflection fixes: [ticket:349] [ticket:382]
 - added keywords for EXCEPT, INTERSECT, EXCEPT ALL, INTERSECT ALL
 [ticket:247]
 - assign_mapper in assignmapper extension returns the created mapper
index 662d276e930efd8b176f55ef093611c52b486a48..b87e2d6e942297223aa4e904072c7babd069e514 100644 (file)
@@ -29,7 +29,10 @@ class MSNumeric(sqltypes.Numeric):
         self.zerofill = 'zerofill' in kw
         super(MSNumeric, self).__init__(precision, length)
     def get_col_spec(self):
-        return kw_colspec(self, "NUMERIC(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length})
+        if self.precision is None:
+            return kw_colspec(self, "NUMERIC")
+        else:
+            return kw_colspec(self, "NUMERIC(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length})
 class MSDecimal(MSNumeric):
     def get_col_spec(self):
         if self.precision is not None and self.length is not None:
index 5c78e2f5201b957c1a2b79f2150269b9cdf13eba..a3ecab825302a66e073e1c44f95404e2ed566701 100644 (file)
@@ -34,10 +34,16 @@ except:
 
 class PGNumeric(sqltypes.Numeric):
     def get_col_spec(self):
-        return "NUMERIC(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length}
+        if not self.precision:
+            return "NUMERIC"
+        else:
+            return "NUMERIC(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length}
 class PGFloat(sqltypes.Float):
     def get_col_spec(self):
-        return "FLOAT(%(precision)s)" % {'precision': self.precision}
+        if not self.precision:
+            return "FLOAT"
+        else:
+            return "FLOAT(%(precision)s)" % {'precision': self.precision}
 class PGInteger(sqltypes.Integer):
     def get_col_spec(self):
         return "INTEGER"
@@ -345,24 +351,29 @@ class PGDialect(ansisql.ANSIDialect):
                 try:
                     charlen = re.search('\(([\d,]+)\)',row['format_type']).group(1)
                 except:
-                    charlen = None
+                    charlen = False
     
-                numericprec = None
-                numericscale = None
+                numericprec = False
+                numericscale = False
                 default = row['default']
                 if attype == 'numeric':
-                    numericprec, numericscale = charlen.split(',')
-                    charlen = None
+                    if charlen is False:
+                        numericprec, numericscale = (None, None)
+                    else:
+                        numericprec, numericscale = charlen.split(',')
+                    charlen = False
                 if attype == 'double precision':
                     numericprec, numericscale = (53, None)
-                    charlen = None
+                    charlen = False
                 if attype == 'integer':
                     numericprec, numericscale = (32, 0)
-                    charlen = None
+                    charlen = False
 
                 args = []
                 for a in (charlen, numericprec, numericscale):
-                    if a is not None:
+                    if a is None:
+                        args.append(None)
+                    elif a is not False:
                         args.append(int(a))
 
                 kwargs = {}
@@ -421,22 +432,15 @@ class PGDialect(ansisql.ANSIDialect):
                 if row is None:
                     break
 
-                identifier = '(?:[a-z_][a-z0-9_$]+|"(?:[^"]|"")+")'
-                identifier_group = '%s(?:, %s)*' % (identifier, identifier)
-                identifiers = '(%s)(?:, (%s))*' % (identifier, identifier)
-                f = re.compile(identifiers)
-                # FOREIGN KEY (mail_user_id,"Mail_User_ID2") REFERENCES "mYschema".euro_user(user_id,"User_ID2")
-                foreign_key_pattern = 'FOREIGN KEY \((%s)\) REFERENCES (?:(%s)\.)?(%s)\((%s)\)' % (identifier_group, identifier, identifier, identifier_group)
-                p = re.compile(foreign_key_pattern)
-                
-                m = p.search(row['condef'])
+                foreign_key_pattern = 'FOREIGN KEY \((.*?)\) REFERENCES (?:(.*?)\.)?(.*?)\((.*?)\)'
+                m = re.search(foreign_key_pattern, row['condef'])
                 (constrained_columns, referred_schema, referred_table, referred_columns) = m.groups() 
                 
-                constrained_columns = [preparer._unquote_identifier(x) for x in f.search(constrained_columns).groups() if x]
+                constrained_columns = [preparer._unquote_identifier(x) for x in re.split(r'\s*,\s*', constrained_columns)]
                 if referred_schema:
                     referred_schema = preparer._unquote_identifier(referred_schema)
                 referred_table = preparer._unquote_identifier(referred_table)
-                referred_columns = [preparer._unquote_identifier(x) for x in f.search(referred_columns).groups() if x]
+                referred_columns = [preparer._unquote_identifier(x) for x in re.split(r'\s*,\s', referred_columns)]
                 
                 refspec = []
                 if referred_schema is not None:
index 4eee8e4d03a282c6a93a0f39c196d53198ae93c3..6300250b34bafd386197a954b1c4c63cea4e1582 100644 (file)
@@ -27,7 +27,10 @@ except ImportError:
 
 class SLNumeric(sqltypes.Numeric):
     def get_col_spec(self):
-        return "NUMERIC(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length}
+        if self.precision is None:
+            return "NUMERIC"
+        else:
+            return "NUMERIC(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length}
 class SLInteger(sqltypes.Integer):
     def get_col_spec(self):
         return "INTEGER"
index 6c367159b41c74c8bedd514f2ffad22073415871..3467c6ae423beb26a1de53e8f4af8b546bededf1 100644 (file)
@@ -49,6 +49,7 @@ class ReflectionTest(PersistTest):
             Column('test_passivedefault2', Integer, PassiveDefault("5")),
             Column('test_passivedefault3', deftype2, PassiveDefault(defval2)),
             Column('test9', Binary(100)),
+            Column('test_numeric', Numeric(None, None)),
             mysql_engine='InnoDB'
         )
 
@@ -58,7 +59,8 @@ class ReflectionTest(PersistTest):
             Column('email_address', String(20)),
             mysql_engine='InnoDB'
         )
-
+        meta.drop_all()
+        
         users.create()
         addresses.create()
 
@@ -169,7 +171,6 @@ class ReflectionTest(PersistTest):
                 autoload=True)
             u2 = Table('users', meta2, autoload=True)
 
-            print "ITS", list(a2.primary_key)
             assert list(a2.primary_key) == [a2.c.id]
             assert list(u2.primary_key) == [u2.c.id]
             assert u2.join(a2).onclause == u2.c.id==a2.c.id
@@ -304,6 +305,7 @@ class ReflectionTest(PersistTest):
             'multi', meta, 
             Column('multi_id', Integer, primary_key=True),
             Column('multi_rev', Integer, primary_key=True),
+            Column('multi_hoho', Integer, primary_key=True),
             Column('name', String(50), nullable=False),
             Column('val', String(100)),
             mysql_engine='InnoDB'
@@ -312,10 +314,12 @@ class ReflectionTest(PersistTest):
             Column('id', Integer, primary_key=True),
             Column('foo', Integer),
             Column('bar', Integer),
+            Column('lala', Integer),
             Column('data', String(50)),
-            ForeignKeyConstraint(['foo', 'bar'], ['multi.multi_id', 'multi.multi_rev']),
+            ForeignKeyConstraint(['foo', 'bar', 'lala'], ['multi.multi_id', 'multi.multi_rev', 'multi.multi_hoho']),
             mysql_engine='InnoDB'
         )
+        assert table.c.multi_hoho
         meta.create_all()
         meta.clear()
         
@@ -327,11 +331,10 @@ class ReflectionTest(PersistTest):
             print table2
             j = join(table, table2)
             print str(j.onclause)
-            self.assert_(and_(table.c.multi_id==table2.c.foo, table.c.multi_rev==table2.c.bar).compare(j.onclause))
+            self.assert_(and_(table.c.multi_id==table2.c.foo, table.c.multi_rev==table2.c.bar, table.c.multi_hoho==table2.c.lala).compare(j.onclause))
 
         finally:
-            pass
-#            meta.drop_all()
+            meta.drop_all()
 
     def testcheckfirst(self):
         meta = BoundMetaData(testbase.db)