On Wed, Nov 15, 2017 at 3:49 PM, Jonathan Vanasco <jonat...@findmeon.com> wrote:
> This is a bit of an odd request, but here goes:
>
> A table in postgresql has some columns with sensitive data which should be
> secured against visibility by one of our applications (we use a central
> SqlAlchemy model for multiple applications)
>
> Currently we use an environment var to determine if the column is in the
> class definition for the table (nesting the column in an "if" statement).
>
> A new feature I'd like to implement is allowing one of the applications to
> search on that column, but ensuring that it doesn't appear in the result.
>
> currently we have this:
>
>     class Foo(Base):
>         __tablename__ = 'foo'
>         id = sa_Column(sa_Integer, primary_key=True)
>         if allow_bar:
>             bar = sa_Column(sa_Text)
>
> and it would be ideal to allow `bar` to be used in filter() queries, but
> never retrieved and exceptions raised if accessed.
>
> has anyone tried to do something like this before?

well not mapping a column is pretty easy, but yes, then you can't search on it.

If you had the column in Table metadata but then excluded it from the
mapping, that would work.   that was easy pre-declarative. with
declarative, I guess we would say:

Base = declarative_base()


class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)
    x = Column(Integer)
    y = Column(Integer)

    __mapper_args__ = {"exclude_properties": ['y']}

e = create_engine("sqlite://", echo=True)

Base.metadata.create_all(e)
e.execute("INSERT INTO a (x, y) VALUES (1, 2)")


s = Session(e)

a1 = s.query(A).filter_by(y=2).first()

print a1.x
print a1.y



seems to work.  doesn't raise an error though, it just says, "a.y",
e.g. A.y is just a Column object - it isn't any kind of attribute.

more traditional way, use deferred() but then also catch it on the load:

class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)
    x = Column(Integer)
    y = deferred(Column(Integer))


@event.listens_for(A, "load")
@event.listens_for(A, "refresh")
def _verboten(target, context, attrs=None):
    if 'y' in target.__dict__:
        raise Exception("nein!")

e = create_engine("sqlite://", echo=True)

Base.metadata.create_all(e)
e.execute("INSERT INTO a (x, y) VALUES (1, 2)")


s = Session(e)

a1 = s.query(A).filter_by(y=2).first()

print a1.x
print a1.y

you can look in "attrs" for "y", but in case someone did undefer() on
the query, just seeing if it's there at all catches that.








>
>
> --
> 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 post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to