FWIW, I often use the events to ensure an object or column is "read only".  

Sometimes I also will use two different attributes, where `Object.foo` is a 
getter for `Object._foo` in the database.  The database will raise an error 
(hopefully) if I try to write to a 'protected column', and SQLAlchemy code 
is somewhat easy to audit to ensure I am only reading and never accessing 
the protected column.  I generally like to integrate that approach because 
I know something special is going on with the columns that have a leading _ 
and will immediately check the table's schema to remind myself.   


On Friday, April 14, 2023 at 4:18:05 PM UTC-4 Mike Bayer wrote:

>
>
> On Fri, Apr 14, 2023, at 3:02 PM, Lele Gaifax wrote:
> > "Mike Bayer" <mike_not_...@zzzcomputing.com> writes:
> >
> >> On Fri, Apr 14, 2023, at 8:03 AM, Lele Gaifax wrote:
> >>> I now have
> >>>
> >>> CREATE TABLE something (id SERIAL, name TEXT)
> >>>
> >>> CREATE FUNCTION counter(something)
> >>> RETURNS INTEGER AS $$
> >>> SELECT count(*) FROM something_else se
> >>> WHERE se.something_id = $1.id
> >>> $$ STABLE SQL
> >>>
> >>> and thus existing queries such as
> >>>
> >>> SELECT s.name, s.counter
> >>> FROM something AS s
> >>>
> >>> work as before.
> >>
> >> how does "SELECT s.counter" work if the table does not have an actual 
> "counter" column? 
> >
> > As explained here [1], "the field notation and functional notation are
> > equivalent", that is "SELECT a.foo FROM t AS a" and "SELECT foo(a) FROM
> > t AS a" means the same, when "foo" is a function accepting the "implicit
> > composite type corresponding to a row in the table t".
>
> oh geez it's that silly PostgreSQL syntax. not a fan. you can use that but 
> you'd be on your own....
>
> >
> >>
> >> Using Computed in this way is equivalent to using FetchedValue. Why is 
> that a problem? 
> >
> > No, it's not a problem, but the following
> >
> > stmt = something.update().values(counter=42).where(something.c.id=1)
> > connection.execute(stmt)
> > 
> > will raise an error at execution time, as will, assuming
> > "instance_of_something" is an instance of the ORM class mapped to the
> > table "something"
>
> So what then is a "read only column" if not one that raises an error if 
> someone tries to write to it explicitly?
>
> > instance_of_something.counter = 42
> > session.flush()
> >
> > I was just imagining something that could raise an error earlier.
>
> well you have the ORM validates and the before_cursor_execute approaches, 
> but I would think if this is simple developer level programming guards, the 
> PG exception is perfect
>
>
> >
> > Unfortunately in this case PG does not help: the closest thing is a
> > "GENERATED" column [2], but (up to version 15 at least) it "is a special
> > column that is always computed from other columns", it cannot be an
> > arbitrary subquery.
>
> trigger, then. im sure this is a thing PG can do
>
> >
> >> Without using server-side constructs, in a practical sense, simply
> >> omitting the column from the Table or using mapper.exclude_properties
> >> is in my experience sufficient.
> >
> > Uhm, how could I then select that value, to be returned by an API that
> > queries the "something" table?
>
> OK so the "readonly" you are looking for includes one where your 
> application actually needs to load it, then fine, dont exclude it from your 
> mappings.
>
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/4cf77276-32bf-4ba7-8510-83197384feden%40googlegroups.com.

Reply via email to