]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
(no commit message)
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 23 Sep 2005 06:04:05 +0000 (06:04 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 23 Sep 2005 06:04:05 +0000 (06:04 +0000)
lib/sqlalchemy/schema.py

index 1e36117a655a13fe44e7ce321313e079edd1baf9..bbe21ab4be1de864a5d93c32a86189142f6ac4bd 100644 (file)
@@ -17,7 +17,7 @@
 
 from sqlalchemy.util import *
 from sqlalchemy.types import *
-import copy
+import copy, re
 
 
 __ALL__ = ['Table', 'Column', 'Sequence', 'ForeignKey']
@@ -43,6 +43,8 @@ class SchemaItem(object):
 
     def __getattr__(self, key):
         """proxies method calls to an underlying implementation object for methods not found locally"""
+        if not hasattr(self, '_impl'):
+            raise AttributeError(key)
         return getattr(self._impl, key)
 
 
@@ -51,6 +53,8 @@ class TableSingleton(type):
         try:
             return engine.tables[name]
         except:
+            if kwargs.get('mustexist', False):
+                raise "Table '%s' not defined" % name
             table = type.__call__(self, name, engine, *args, **kwargs)
             engine.tables[name] = table
             # load column definitions from the database if 'autoload' is defined
@@ -58,6 +62,7 @@ class TableSingleton(type):
             # circular foreign keys
             if kwargs.get('autoload', False):
                 engine.reflecttable(table)
+
             return table
 
         
@@ -115,12 +120,12 @@ class Column(SchemaItem):
         
         if self.foreign_key is not None:
             self._init_items(self.foreign_key)
-            table.foreign_keys[self.foreign_key.column.key] = self.foreign_key
+#            table.foreign_keys[self.foreign_key.column.key] = self.foreign_key
 
     def set_foreign_key(self, fk):
         self.foreign_key = fk
         self._init_items(self.foreign_key)
-        self.table.foreign_keys[self.foreign_key.column.key] = self.foreign_key
+#        self.table.foreign_keys[self.foreign_key.column.key] = self.foreign_key
     
     def _make_proxy(self, selectable, name = None):
         """creates a copy of this Column for use in a new selectable unit"""
@@ -129,6 +134,7 @@ class Column(SchemaItem):
         #if name is not None:
          #   c.name = name
          #   c.key = name
+        # TODO: do we want the same foreign_key object here ?  
         c = Column(name or self.name, self.type, key = name or self.key, primary_key = self.primary_key, foreign_key = self.foreign_key, sequence = self.sequence)
         c.table = selectable
         c.engine = self.engine
@@ -150,7 +156,32 @@ class Column(SchemaItem):
 
 class ForeignKey(SchemaItem):
     def __init__(self, column):
-        self.column = column
+        self._colspec = column
+        self._column = None
+
+    def _init_column(self):
+        # ForeignKey inits its remote column as late as possible, so tables can
+        # be defined without dependencies
+        if self._column is None:
+            if isinstance(self._colspec, str):
+                m = re.match(r"([\w_-]+)(?:\.([\w_-]+))?", self._colspec)
+                if m is None:
+                    raise "Invalid foreign key column specification: " + self._colspec
+                (tname, colname) = m.group(1, 2)
+                table = Table(tname, self.parent.engine, mustexist = True)
+                if colname is None:
+                    key = self.parent
+                    self._column = table.c[self.parent.key]
+                else:
+                    self._column = table.c[colname]
+            else:
+                self._column = self._colspec
+
+            self.parent.table.foreign_keys[self._column.key] = self
+        return self._column
+            
+    column = property(lambda s: s._init_column())
+    
     def _set_parent(self, column):
         self.parent = column