On Thu, May 16, 2019 at 9:22 AM Marcel Zoll
<[email protected]> wrote:
>>
>>
>> it's the "functional at each level" part that I think goes beyond what
>> is practical.   When you run an operation on a superclass, and it
>> expects to do ORM operations, it has to be referring to the ultimate
>> mapped class.  The ORM is designed with the idea that the concrete
>> instantiation classes are the ones that are ultimately mapped and
>> dealt with in terms of persistence.
>
>
> Okay, that is something that I get. However, if you extend the baseclass 
> strictly hierarchical and only make one concrete class for each derived level 
> that you want to operate at (lets say each level isolated in a package), the 
> notion of an 'ultimate' derived class should be well defined, and so should 
> be programming-technically resolvable (So i understand sqlalchemy already 
> does some class-inspections under the hood, even though I do not know by 
> which mechanics that is governed):
> I mean something like this (\/ and > should mean 'derives to'):
>
> --- level 0 ---
> Base
> \/
> OBJ01_Declared_lvl0 > OBJ01_Mapped_lvl0
>
> --- level A ---
> \/
> OBJ01_Extended_lvlA > OBJ01_Mapped_lvlA
>
> --- level B ---
> \/
> OBJ01_Extended_lvlB > OBJ01_Mapped_lvlB
>
>
>
>>   It should be apparent that it
>> would be vastly more complicated to make it also "know" about all
>> kinds of arbitrary subclasses.
>
>
> You are correct, that from one derived concrete class knowing the identity of 
> another other derived concrete class of the object it should relate to 
> (relationship(<>)) is hard, and cannot be defined at the baseclass level 
> (possibly where you declare the table) alone. However, I also saw that 
> relationships can be specified by either giving the class of the to be 
> related to object or by its class-name (a string). As this name needs to be 
> resolved to some object at some point by inspection of the namespace (or 
> brute forcing it), cant this resolving not be delayed until this very 
> relationship is used?
> A way to potentially resolve this could be that you would kind of use a 
> 'derived_level_Mixin' that you assign to all Mapped classes at each level; so 
> inspecting for this trait in your querying class and the class to be resulted 
> should make things uniquely identifiable.
>
> My Ideal solution would look so that all mapped would actually go by the same 
> class-name, however, by being in different modules they fully-qualified names 
> should still be unique. This would make it more convenient to use, as the 
> classes follow the same basic-interface, while the highest derived class in 
> the highest level package provides most functionality
>
> --- script1.py ---
> from myproj_lvlA import Source
> ...
> session.add(Source('MySource'))
> session.commit()
> s = session.query(Source).first()
> print(Source)
>
> --- script2.py ---
>
> from myproj_lvlB import Source  #<< import from higher level module
> ...
> session.add(Source('MySource'))
> session.commit()
> s = session.query(Source).first()
> print(Source)
> s.move_to_loc_by_name('MyLocation') #<< functionality only accessible at 
> myprojB
>
>
>
>>
>>   How would you propose the identity
>> map issue I illustrated before function? That is, if i query for
>> Class_lvlA and later for Class_lvlB, what identity key should they
>> have?   If you say they should have the same identity key, what if
>> both Class_lvlA and Class_lvlB perform an operation against the same
>> Session - there is only one Class_<xyz> object in the identity map,
>> suppose it is Class_lvlA, now Class_lvlB consults for its own class
>> and gets the wrong answer.   If you propose they should have
>> individual identity keys, then how do these two classes consult for
>> the same row in the identity map?
>
>
> You are correct, that a session should not be expected to handle objects of 
> different level (Class_lvlA & Class_lvlB) at the same time, as this could 
> potentially lead to conflicts, also as I understand it is not allowed to map 
> the same table to multiple different, inherently distinct, classes at the 
> same time (which i think is good). I am not
>
>
>>
>>       I appreciate that you are
>> going for some particular level of purity in your design, however I
>> believe there is some conflation here of separation of concerns vs.
>> concrete instantiation patterns.
>
>
> Yesterday, I found out some interesting properties, that one can make 
> declarations which use the sqlalchemy-metadata and declarative base, but 
> without visiting/importing the module in question this code is not actually 
> executed, resp. the definitions are not actually added to the metadata or the 
> mappers. It might be possible to exploit this to make a construct as depicted 
> above happen (i.e. not visiting/importing the modules declaring mappers for 
> all mapped classes below the current level). I am not sure if this will not 
> eventually violate some rules of good programming practice...
>
> Thanks Marcel
>

I very much doubt you are going to find a way to get SQLAlchemy to do
what you want automatically. I think you might be better off writing
your classes *without* SQLAlchemy, and then have a separate mechanism
that uses SA's classical mapping tools
(https://docs.sqlalchemy.org/en/13/orm/mapping_styles.html#classical-mapping)
to map them. You can inspect the classes and traverse the hierarchy in
whatever way makes sense to you.

Simon

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/CAFHwexeb9-1kvF1vGVt2Q31cjpmFkTGpBDst3drMnVq7zCV5gg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to