]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- 'name' is no longer a require constructor argument for Column(). It (and .key...
authorJason Kirtland <jek@discorporate.us>
Tue, 18 Mar 2008 00:15:34 +0000 (00:15 +0000)
committerJason Kirtland <jek@discorporate.us>
Tue, 18 Mar 2008 00:15:34 +0000 (00:15 +0000)
CHANGES
lib/sqlalchemy/schema.py
test/sql/alltests.py
test/sql/columns.py [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 695c73035336a4587be464e64f7710aba3d4afbb..b31a9dac24624351af4686f3b98c5f9d64fd8920 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -24,6 +24,11 @@ CHANGES
       had only been implemented for foreign-key nulling behavior
       in 0.4.2 and not actual cascading deletes [ticket:895]
 
+- sql
+    - 'name' is no longer a required constructor argument for
+      Column().  It (and .key) may now be deferred until the column
+      is added to a Table.
+
 - extensions
     - The "synonym" function is now directly usable with
       "declarative".  Pass in the decorated property using the
index 8d0b3d26d2f8d43de50942897f035b30444d609a..c3db8bfad3da00d37edbd6d05ba75474b5f7fcc7 100644 (file)
@@ -405,7 +405,7 @@ class Column(SchemaItem, expression._ColumnClause):
     ``TableClause``/``Table``.
     """
 
-    def __init__(self, name, type_, *args, **kwargs):
+    def __init__(self, *args, **kwargs):
         """Construct a new ``Column`` object.
 
         Arguments are:
@@ -497,6 +497,24 @@ class Column(SchemaItem, expression._ColumnClause):
             auto-detect conditions where quoting is required.
         """
 
+        name = kwargs.pop('name', None)
+        type_ = kwargs.pop('type_', None)
+        if args:
+            args = list(args)
+            if isinstance(args[0], basestring):
+                if name is not None:
+                    raise exceptions.ArgumentError(
+                        "May not pass name positionally and as a keyword.")
+                name = args.pop(0)
+        if args:
+            if (isinstance(args[0], types.AbstractType) or
+                (isinstance(args[0], type) and
+                 issubclass(args[0], types.AbstractType))):
+                if type_ is not None:
+                    raise exceptions.ArgumentError(
+                        "May not pass type_ positionally and as a keyword.")
+                type_ = args.pop(0)
+
         super(Column, self).__init__(name, None, type_)
         self.args = args
         self.key = kwargs.pop('key', name)
@@ -561,6 +579,10 @@ class Column(SchemaItem, expression._ColumnClause):
             ["%s=%s" % (k, repr(getattr(self, k))) for k in kwarg])
 
     def _set_parent(self, table):
+        if self.name is None:
+            raise exceptions.ArgumentError(
+                "Column must be constructed with a name or assign .name "
+                "before adding to a Table.")
         self.metadata = table.metadata
         if getattr(self, 'table', None) is not None:
             raise exceptions.ArgumentError("this Column already has a table!")
index f49cf14d4bf73bc598bf740ca5a6867a9fc36158..173b04632729aa735b94f4a9e91412ccc221f38d 100644 (file)
@@ -5,6 +5,7 @@ import unittest
 def suite():
     modules_to_test = (
         'sql.testtypes',
+        'sql.columns',
         'sql.constraints',
 
         'sql.generative',
diff --git a/test/sql/columns.py b/test/sql/columns.py
new file mode 100644 (file)
index 0000000..0a904be
--- /dev/null
@@ -0,0 +1,48 @@
+import testenv; testenv.configure_for_tests()
+from sqlalchemy import *
+from sqlalchemy import exceptions, sql
+from testlib import *
+from sqlalchemy import Table, Column  # don't use testlib's wrappers
+
+
+class ColumnDefinitionTest(TestBase):
+    """Test Column() construction."""
+
+    # flesh this out with explicit coverage...
+
+    def columns(self):
+        return [ Column(),
+                 Column('b'),
+                 Column(Integer),
+                 Column('d', Integer),
+                 Column(name='e'),
+                 Column(type_=Integer),
+                 Column(Integer()),
+                 Column('h', Integer()),
+                 Column(type_=Integer()) ]
+
+    def test_basic(self):
+        c = self.columns()
+
+        for i, v in ((0, 'a'), (2, 'c'), (5, 'f'), (6, 'g'), (8, 'i')):
+            c[i].name = v
+            c[i].key = v
+        del i, v
+
+        tbl = Table('table', MetaData(), *c)
+
+        for i, col in enumerate(tbl.c):
+            assert col.name == c[i].name
+
+    def test_incomplete(self):
+        c = self.columns()
+
+        self.assertRaises(exceptions.ArgumentError, Table, 't', MetaData(), *c)
+
+    def test_bogus(self):
+        self.assertRaises(exceptions.ArgumentError, Column, 'foo', name='bar')
+        self.assertRaises(exceptions.ArgumentError, Column, 'foo', Integer,
+                          type_=Integer())
+
+if __name__ == "__main__":
+    testenv.main()