diff --git a/sqlalchemy_utils/listeners.py b/sqlalchemy_utils/listeners.py index 03acb2f1..c2ed982f 100644 --- a/sqlalchemy_utils/listeners.py +++ b/sqlalchemy_utils/listeners.py @@ -24,7 +24,9 @@ def instant_defaults_listener(target, args, kwargs): for key, column in sa.inspect(target.__class__).columns.items(): if hasattr(column, 'default') and column.default is not None: - if callable(column.default.arg): + if not hasattr(column.default, 'arg'): + continue + elif callable(column.default.arg): kwargs[key] = column.default.arg(target) else: kwargs[key] = column.default.arg diff --git a/tests/test_instant_defaults_listener.py b/tests/test_instant_defaults_listener.py index 7db05f73..d3c9d7e8 100644 --- a/tests/test_instant_defaults_listener.py +++ b/tests/test_instant_defaults_listener.py @@ -28,6 +28,20 @@ def byline(self, value): return Article +@pytest.fixture +def Document(Base): + class Document(Base): + __tablename__ = 'document' + id = sa.Column( + sa.Integer, + sa.Sequence('document_id_seq'), + primary_key=True + ) + title = sa.Column(sa.Unicode(255), default='Untitled') + + return Document + + class TestInstantDefaultListener: def test_assigns_defaults_on_object_construction(self, Article): article = Article() @@ -40,3 +54,8 @@ def test_callables_as_defaults(self, Article): def test_override_default_with_setter_function(self, Article): article = Article(byline='provided byline') assert article.byline == 'provided byline' + + def test_handles_sequence_defaults(self, Document): + document = Document() + assert document.title == 'Untitled' + assert document.id is None