Skip to content

Commit

Permalink
Merge pull request #64 from DanCardin/dc/view_function
Browse files Browse the repository at this point in the history
feat: Allow __view__ to be a callable.
  • Loading branch information
DanCardin authored May 31, 2024
2 parents 9894b71 + 77e7c84 commit 77b3219
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "sqlalchemy-declarative-extensions"
version = "0.9.0"
version = "0.9.1"
authors = ["Dan Cardin <ddcardin@gmail.com>"]

description = "Library to declare additional kinds of objects not natively supported by SQLAlchemy/Alembic."
Expand Down
10 changes: 8 additions & 2 deletions src/sqlalchemy_declarative_extensions/view/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import inspect
import uuid
import warnings
from dataclasses import dataclass, field, replace
Expand Down Expand Up @@ -41,8 +42,10 @@ def view(
Given some object with the attributes: `__tablename__`, (optionally for schema) `__table_args__`,
and `__view__`, registers a View object.
The `__view__` attribute can be either a raw string query, or a SQLAlchemy object
capable of being compiled (namely :func:`~sqlalchemy.sql.expression.text` or :func:`~sqlalchemy.sql.expression.select`).
The `__view__` attribute can be either a raw string query, a SQLAlchemy object
capable of being compiled (namely :func:`~sqlalchemy.sql.expression.text` or
:func:`~sqlalchemy.sql.expression.select`), or a no-argument function which returns
either of the two.
This intentionally allows one to register a Model definition as a view,
and have it register in the same way you might otherwise manually define it.
Expand Down Expand Up @@ -128,6 +131,9 @@ def table_args(self):

@property
def view_def(self):
if inspect.isfunction(self.cls.__view__):
return self.cls.__view__()

return self.cls.__view__

@property
Expand Down
48 changes: 48 additions & 0 deletions tests/view/test_view_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from pytest_mock_resources import create_postgres_fixture
from sqlalchemy import Column, text, types

from sqlalchemy_declarative_extensions import (
declarative_database,
register_sqlalchemy_events,
view,
)
from sqlalchemy_declarative_extensions.sqlalchemy import declarative_base, select

_Base = declarative_base()


@declarative_database
class Base(_Base): # type: ignore
__abstract__ = True


class Foo(Base):
__tablename__ = "foo"
id = Column(types.Integer(), primary_key=True)


@view(Base)
class HighFoo:
__tablename__ = "high_foo"

@staticmethod
def __view__():
return select(Foo.__table__).where(Foo.__table__.c.id >= 10)


register_sqlalchemy_events(Base.metadata, schemas=True, views=True, rows=True)

pg = create_postgres_fixture(
scope="function", engine_kwargs={"echo": True}, session=True
)


def test_created_together(pg):
Base.metadata.create_all(pg.connection())

for i in range(8, 12):
pg.add(Foo(id=i))
pg.commit()

result = [i for (i,) in pg.execute(text('select id from "high_foo"'))]
assert result == [10, 11]

0 comments on commit 77b3219

Please sign in to comment.