diff --git a/peewee.py b/peewee.py index ef9e02d6b..1e22db506 100644 --- a/peewee.py +++ b/peewee.py @@ -1344,6 +1344,14 @@ def __sql__(self, ctx): # For multi-part values (e.g. lists of IDs). return ctx.sql(EnclosedNodeList(self.values)) + # Under certain circumstances, we could end-up treating a model-class + # itself as a value. This check ensures that we drop the table alias + # into the query instead of trying to parameterize a model (for + # instance, when passing a model as a function argument). + if is_model(self.value): + with ctx.scope_column(): + return ctx.sql(self.value) + return ctx.value(self.value, self.converter) @@ -6153,6 +6161,9 @@ def __len__(self): def __bool__(self): return True __nonzero__ = __bool__ # Python 2. + def __sql__(self, ctx): + return ctx.sql(self._meta.table) + class _BoundModelsContext(_callable_context_manager): def __init__(self, models, database, bind_refs, bind_backrefs): diff --git a/tests/model_sql.py b/tests/model_sql.py index f5d02b0f4..b2dfe5c10 100644 --- a/tests/model_sql.py +++ b/tests/model_sql.py @@ -1076,3 +1076,21 @@ class Article(Model): self.assertSQL(aidx, ( 'CREATE UNIQUE INDEX IF NOT EXISTS "article_timestamp" ' 'ON "article" ("timestamp" DESC, ("flags" & ?))'), [4]) + + +class TestModelArgument(BaseTestCase): + database = SqliteDatabase(None) + + def test_model_as_argument(self): + class Post(TestModel): + content = TextField() + timestamp = DateTimeField() + class Meta: + database = self.database + + query = (Post + .select(Post.id, fn.score(Post).alias('score')) + .order_by(Post.timestamp)) + self.assertSQL(query, ( + 'SELECT "t1"."id", score("t1") AS "score" ' + 'FROM "post" AS "t1" ORDER BY "t1"."timestamp"'), [])