Michael,

I took a look at the recipe you indicated, it looks promising but the check 
should be constructed from database results. Another issue is that this project 
is implemented in my web based desktop/Os which uses SQLAlchemy from the bottem 
up. So modifiing the session object globally is with a PreFilteredQuery is not 
a real option. Creating a session for this "program" only might be an option 
but I am not sure how that will turn out.

Being it a web based (and so Handle request and die), Persistence is (to me) 
not very usefull and I need to "reload" everything for every action.

the @reconstructor hook seems too outdated. I moved to 0.6.6 last week, and 
only will upgrade to stable/production versions since in my case there is a lot 
to it.

I need to transparently add "being queried" functionality to mapped objects. 
This functionality is will be mixed in and should be able to limit the results 
when being queried. Since my class definitions are so complex I would like to 
make a (not functional) example on what I am in search of. and I will not 
bother you with chemistry stuff...


Class ACL(Base):
        Id = Column(Integer, primary_key=True)

        tablename = Column(Unicode(...
        tableId        = Column(Integer

        RecordId = ForeignKeyContruct( / ForeignKey   (not sure yet)

        Record = relation( self.tablename

        User_Group = relation to Person, group 

        Bool columns......
        MayRead
        MayWrite
        MayCreate


Class Mixinstuff(Object)

        Rights = {}  # Rights["MayRead"] etc. will be set upon load....
        
        

Class Person(Base,Mixinstuff)

        Id = Column(Integer, primary_key=True)

        ACLs = relation('ACL'   All ACL records which have   tablename = 
'person' and tableID = Person.Id, cascade="delete" and ACL record for me ) # 
ACL's work on many tables
        I might not define the relation here but backref from the acl record 
depending on how to build what I want

        addresses = relation( ....

Class Address(Base, ACLMixinstuff)

        Id = Column(Integer, primary_key=True)

        ACLs = relation('ACL'   All ACL records which have   tablename = 
'person' and tableID = Person.Id, cascade="delete") # ACL's work on many tables
        I might not define the relation here but backref from the acl record 
depending on how to build what I want

class ME()
        userId =  1 (foreignkey to Person)
        groups = [1,2,3,4]  (relationship with groups (same polymorhic 
baseclass)


Now consider ME being a member of "Everyone" not "guest"

ACLS for Person
        ME                      | table = person | Id =  1| MayRead = F
        Everyone        | table = person | Id = 1 | MayRead = T
        Guest           | table = person | Id = 1 | MayRead = F


user = ME, GROUPS = [Everyone]

A query for Session.query(Persons).all() should NOT return Person.Id although 
Everyone says True, personal Permissions overrule group permissions , simple 
boolean operations. If no ACLs are found It all defaults to false or true not 
sure yet on how this will work on my real data model, since this will be the 
model on which atoms and molecule connections are "Allowed"

If However the ACL's turn out that ME.MayRead = T, I will only get related 
addresses I actually may read. This should "work" automatically for each class 
with Mixedinstuff inherited....

This is whilst I do not want the "Users" of this model to be bothered with 
this, the should add data to their model and query to generate list of possible 
new molecules.

I am some sort of clueless on how to do this properly

the MapperExtention.append_result still seems the best way...   

        if calculate_ACLs(Session = object_session(self), tablename = 
instance.__tablename__, TableId = instance.__=TableId__, CheckFor = ME, Right = 
"MayRead" ):
                EXT_CONTINUE
        else:
                EXT_STOP

Dont you?

One other thing, the CalculateACLs query should be as light as possible It will 
only need to return True or False if possible using database functions and if 
possible be database independant.
Can you help me on that one too?


def calculate-ACLs(.......):
        BOOLGROUP =     Session.query(ACL).filter(and_(tablename= .., tableId 
=...,USER_GROUP in me.literal_colum(..?..?..?))......
        BOOLME = the same but now for ME, is easy no boolean calculation needed 
in query  

        if BoolME:
                return BOOLME
        else:
                return BOOLGROUP




Martijn

        









On Feb 7, 2011, at 5:55 PM, Michael Bayer wrote:

> 
> On Feb 7, 2011, at 11:42 AM, Martijn Moeling wrote:
> 
>> I think, I might be helped with the create_instance "event"
> 
> Assuming you're talking about when the ORM establishes an instance from a 
> newly fetched row, you can use the @reconstructor hook for that.   0.7 
> publishes this event additionally as the "load" event.
> 
> 
> 
>> 
>> I will never ever stop a class from being saved/persistent, 
>> 
>> it is the other way around. I thought I was able to use joins and or 
>> relations to limit for "allowed" results from a query.
>> With all the polymorphic and self references I have got and the fact that I 
>> need to do so for multiple Polymorphic colums I came up with the ACL idea.
>> 
>> Im not sure it if will perform, but in the create_instance I will look up 
>> the ACL and set additional properties on the instance or create an empty one.
>> 
>> This whole system is getting very complex now and limiting returned data 
>> involves modifying relationsships a lot. I'm really glad I got that working.
>> 
>> Many classes are base on top of that and I the only IT guy working on this 
>> together with "programmers" with a chemistry degree. Who will need the API I 
>> am working on to do their stuff without knowing anything about 
>> Databases........
>> 
>> To have that I Inherit polymorphicly, have many-to-many self references, use 
>> mixins. 
> 
> 
> 
>> 
>> I'll have a look at the PreFilteredQuery example you gave me, Any thoughts 
>> are helpful, I'll see If I can make up an example with persons and addresses 
>> again since the molecule stuff makes it even more confusing..
>> Will take me some time though 
>> 
>> Martijn
>> 
>> 
>> 
>> 
>> On Feb 7, 2011, at 5:18 PM, Michael Bayer wrote:
>> 
>>> 
>>> On Feb 7, 2011, at 10:55 AM, Martijn Moeling wrote:
>>> 
>>>> Hi,
>>>> 
>>>> It is me again with an interesting thing, I've searched the net, this 
>>>> group etc. Not a lot of people seem interested in append_result, I AM!!
>>>> 
>>>> I am looking for a way to implement the following:
>>>> 
>>>> 
>>>> I have many tables, a lot with polymorphic inheritance and self and cross 
>>>> references.
>>>> 
>>>> In order to control "available" data I have set up a system similar to ACL 
>>>> (Access Control Lists)
>>>> 
>>>> Depending on "Who I am" I can get data from the database.
>>>> 
>>>> I want to do so within the MapperExtension I already have set up to do 
>>>> some "before update" and "before insert"
>>> 
>>> Limitations on inserts, updates and queries are best done outside of the 
>>> Mapper.   By the time the mapper is dealing with instructions to persist or 
>>> load a row, its usually too late, unless you're looking to raise an 
>>> exception upon certain conditions.       For example there's no way to 
>>> "stop" the insert from happening inside of a "before insert" operation, 
>>> short of raising an exception (maybe that's what you're doing).    
>>> 
>>> A SessionExtension.before_flush() OTOH allows you to modify everything 
>>> that's going to happen before any flush plans are made.
>>> 
>>> Regarding append_result(), its a very old hook from 0.1 that's never had 
>>> any real use.   In this case I would instead be ensure that the undesired 
>>> rows are not in the result set to start with.   The recipe at 
>>> http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PreFilteredQuery is a 
>>> decent starting point for such a recipe.
>>> 
>>> 
>>>> 
>>>> 
>>>> def append_result(self, mapper, selectcontext, row, instance, result, 
>>>> **flags):
>>>>     if instance.__tablename__ == 'he':
>>>>         return EXT_STOP
>>>>     else:
>>>>         return EXT_CONTINUE
>>>> 
>>>> would do such a thing, but I want (for the sake of the code behind that) 
>>>> to continue with a heavily modified instance.
>>>> 
>>>> To avoid making this long code (a lot of different object types pass 
>>>> through here, remember the polymorhic bit)
>>>> 
>>>> Does anyone have an interesting approach to this? basically I need to do 
>>>> something like instance= instance_class_type(new, configuration, based, 
>>>> on, the, ACL)
>>>> 
>>>> 
>>>> 
>>>> Any help would be wonderfull,
>>>> 
>>>> Martijn
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "sqlalchemy" group.
>>>> To post to this group, send email to sqlalchemy@googlegroups.com.
>>>> To unsubscribe from this group, send email to 
>>>> sqlalchemy+unsubscr...@googlegroups.com.
>>>> For more options, visit this group at 
>>>> http://groups.google.com/group/sqlalchemy?hl=en.
>>>> 
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "sqlalchemy" group.
>>> To post to this group, send email to sqlalchemy@googlegroups.com.
>>> To unsubscribe from this group, send email to 
>>> sqlalchemy+unsubscr...@googlegroups.com.
>>> For more options, visit this group at 
>>> http://groups.google.com/group/sqlalchemy?hl=en.
>>> 
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "sqlalchemy" group.
>> To post to this group, send email to sqlalchemy@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> sqlalchemy+unsubscr...@googlegroups.com.
>> For more options, visit this group at 
>> http://groups.google.com/group/sqlalchemy?hl=en.
>> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to