I think the warning message is slightly misleading, probably because
of the inheritance, but the fundamental problem is likely that your
"process" table already has a "user" column, and you're trying to add
a second "user" column in the process_history table, which can't work.

If you use a different column name to store the user in the history
table, does the warning go away?

Simon

On Tue, Mar 23, 2021 at 7:17 PM JPLaverdure <jp.laverd...@gmail.com> wrote:
>
> It seems I lost my previous email.. Here it is again:
>
> Sure !
> Here are 2 classes for which the generated _history sister tables (generated 
> by history_meta.py) throw the warnings:
>
> The Parent class:
>
> class Process(Versioned, Base, UtilityMixin):
> __tablename__ = 'process'
> __table_args__ = {}
>
> id = Column(Integer, primary_key=True)
> discriminator = Column('type', String(64))
> timestamp = Column(DateTime, nullable=False)
> start_date = Column(Date, nullable=False)
> am_pm = Column(String(8))
> probable_end_date = Column(Date)
> end_date = Column(Date)
> user = Column(String(128), nullable=False)
> comments = Column(Text)
>
> __mapper_args__ = {'polymorphic_on': discriminator, 'polymorphic_identity': 
> 'process',
> 'order_by': [start_date.desc(), id.desc()]}
>
> protocol_id = Column(Integer, ForeignKey('protocol.id', onupdate='cascade', 
> ondelete='restrict'))
> process_type_id = Column(Integer, ForeignKey('process_type.id', 
> onupdate='cascade', ondelete='restrict'))
>
> protocol = relationship(Protocol, backref='processes', uselist=False)
> process_type = relationship(ProcessType, backref='processes', uselist=False)
>
> The Child class:
>
> class CompoundAdministration(Process):
> __tablename__ = 'compound_administration'
> __table_args__ = {}
> __mapper_args__ = {'polymorphic_identity': 'compound_admin'}
>
> id = Column(Integer, ForeignKey('process.id', onupdate='cascade', 
> ondelete='cascade'), primary_key=True)
> dose = Column(String(64))
> substance = Column(String(128))
> frequency = Column(String(64))
> duration = Column(String(64))
>
> route_id = Column(Integer, ForeignKey('administration_route.id', 
> onupdate='cascade', ondelete='restrict'))
> route = relationship(AdministrationRoute, uselist=False)
>
>
> As reminder, versioning was implemented using this recipe/example from SQLA:
> https://docs.sqlalchemy.org/en/13/_modules/examples/versioned_history/history_meta.html
>
> And here is the associated warning:
>
> SAWarning:
> Implicitly combining column process_history.user with column 
> compound_administration_history.user under attribute 'user'.
> Please configure one or more attributes for these same-named columns 
> explicitly.
>
> Thanks for your help resolving this,
>
> JP
> On Tuesday, March 23, 2021 at 6:24:03 a.m. UTC-4 Simon King wrote:
>>
>> Can you show us the mapping definitions that are triggering these warnings?
>>
>> On Mon, Mar 22, 2021 at 6:29 PM JPLaverdure <jp.lav...@gmail.com> wrote:
>> >
>> > Hi,
>> >
>> > Thanks for your support guys.
>> >
>> > I've implemented logging the user's email in the _history tables by adding 
>> > this Column definition inside my history_meta.py file:
>> > cols.append(
>> > Column(
>> > "user",
>> > String,
>> > info=version_meta,
>> > )
>> > )
>> > but i'm running into a good load of SAWarnings stating that there is an 
>> > implicit combining of the "user" column taking place
>> > (I have multi-table inheritance setup for some entities, those are the 
>> > ones throwing the warning)
>> > I don't get why the column "changed" (which holds the timestamp of the 
>> > change) and is defined in exactly the same way does not generate these 
>> > warnings ?
>> > What configuration setting am I missing here ?
>> >
>> > I found this
>> > https://docs.sqlalchemy.org/en/13/faq/ormconfiguration.html#i-m-getting-a-warning-or-error-about-implicitly-combining-column-x-under-attribute-y
>> > But it doesn't seem to fit 100% with what I'm seeing inside history_meta.py
>> >
>> > Thanks !!
>> > On Monday, March 15, 2021 at 4:33:40 p.m. UTC-4 Jonathan Vanasco wrote:
>> >>
>> >> Going beyond what Simon did..
>> >>
>> >> I typically make make a table like `user_transaction`, which has all of 
>> >> the relevant information for the transaction:
>> >>
>> >> * User ID
>> >> * Timestamp
>> >> * Remote IP
>> >>
>> >> Using the sqlalchemy hooks, I'll then do something like:
>> >>
>> >> * update the object table with the user_transaction id
>> >> or
>> >> * use an association table that tracks a user_transaction_id to an object 
>> >> id and version
>> >>
>> >> FYI, Simon -- as of a few weeks ago, that pattern is now part of the 
>> >> pyramid sqlalchemy starter template!
>> >>
>> >> On Monday, March 15, 2021 at 6:46:02 AM UTC-4 Simon King wrote:
>> >>>
>> >>> I use pyramid as a web framework, and when I create the DB session for
>> >>> each request, I add a reference to the current request object to the
>> >>> DB session. The session object has an "info" attribute which is
>> >>> intended for application-specific things like this:
>> >>>
>> >>> https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.info
>> >>>
>> >>> Then, in the before_flush event handler, I retrieve the request object
>> >>> from session.info, and then I can add whatever request-specific info I
>> >>> want to the DB.
>> >>>
>> >>> Simon
>> >>>
>> >>> On Sun, Mar 14, 2021 at 4:05 PM JPLaverdure <jp.lav...@gmail.com> wrote:
>> >>> >
>> >>> > Hi Elmer,
>> >>> >
>> >>> > Thanks for your reply !
>> >>> > My issue is not with obtaining the info I want to inject (the logged 
>> >>> > in users's email), I already have that all ready to go :)
>> >>> >
>> >>> > My whole database is versioned using the history_meta.py example from 
>> >>> > SQLAlchemy
>> >>> > https://docs.sqlalchemy.org/en/13/_modules/examples/versioned_history/history_meta.html
>> >>> >
>> >>> > I was hoping for a simple way to inject the user info into the 
>> >>> > _history row creation steps.
>> >>> >
>> >>> > The SQLAlchemy example makes use of this event listener:
>> >>> >
>> >>> > def versioned_session(session):
>> >>> >
>> >>> > @event.listens_for(session, "before_flush")
>> >>> > def before_flush(session, flush_context, instances):
>> >>> > for obj in versioned_objects(session.dirty):
>> >>> > create_version(obj, session)
>> >>> > for obj in versioned_objects(session.deleted):
>> >>> > create_version(obj, session, deleted=True)
>> >>> >
>> >>> > So I'm tempted to follow the same strategy and just override this 
>> >>> > listener to supplement it with the user info but I'm wondering how to 
>> >>> > pass in non SQLAlchemy info into its execution context...
>> >>> >
>> >>> > So basically, I have the info I want to inject, I'm just not sure how 
>> >>> > to pass it to SQLAlchemy
>> >>> >
>> >>> > Thanks,
>> >>> >
>> >>> > JP
>> >>> >
>> >>> > On Friday, March 12, 2021 at 6:55:19 p.m. UTC-5 elmer....@gmail.com 
>> >>> > wrote:
>> >>> >>
>> >>> >> Hi JP,
>> >>> >>
>> >>> >> Depending on how you've implemented your history tracking, that 
>> >>> >> routine is quite far removed from your web framework and getting a 
>> >>> >> neat, clean way of dealing with that might not be within reach.
>> >>> >>
>> >>> >> However, most web frameworks have some concept of a threadlocal 
>> >>> >> request (or function to retrieve it), which you could invoke and if 
>> >>> >> such a request exists, you could use that to load whatever user 
>> >>> >> identity you have available on there (again, the details differ, but 
>> >>> >> this tends to be a shared feature). From there you can store the user 
>> >>> >> either as a foreign key, or a unique identifier like email. Which one 
>> >>> >> you pick would depend on how you want the history to be affected when 
>> >>> >> you delete a user record for example.
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> On Fri, Mar 12, 2021 at 11:58 PM JPLaverdure <jp.lav...@gmail.com> 
>> >>> >> wrote:
>> >>> >>>
>> >>> >>> Hello everyone,
>> >>> >>>
>> >>> >>> We already have the ability to timestamp the creation of the history 
>> >>> >>> row, but it would also be interesting to be able to track the user 
>> >>> >>> responsible for the content update.
>> >>> >>> I would like to get suggestions on the best way to achieve this.
>> >>> >>>
>> >>> >>> I realize this is somewhat outside the scope of sqlalchemy as the 
>> >>> >>> notion of a "logged in user" is more closely related to the context 
>> >>> >>> of the app/webapp using SQLAlchemy as its ORM but maybe other people 
>> >>> >>> would benefit from having a way to inject arbitrary data in the 
>> >>> >>> history table.
>> >>> >>>
>> >>> >>> Ideally, I would like the insert in the _history table to be atomic, 
>> >>> >>> so I feel like hooking an update statement to an event might not be 
>> >>> >>> the way to go.
>> >>> >>> I'm tempted to modify the signature of before_flush but I'm not sure 
>> >>> >>> where it gets called.
>> >>> >>>
>> >>> >>> Any help is welcome !
>> >>> >>> Thanks
>> >>> >>>
>> >>> >>> JP
>> >>> >>>
>> >>> >>> --
>> >>> >>> 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+...@googlegroups.com.
>> >>> >>> To view this discussion on the web visit 
>> >>> >>> https://groups.google.com/d/msgid/sqlalchemy/82a24998-14e1-4ff4-a725-dd25c20a8bf2n%40googlegroups.com.
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> --
>> >>> >>
>> >>> >> Elmer
>> >>> >
>> >>> > --
>> >>> > 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+...@googlegroups.com.
>> >>> > To view this discussion on the web visit 
>> >>> > https://groups.google.com/d/msgid/sqlalchemy/58bb6713-18f4-4d69-8d7b-a27772711bd5n%40googlegroups.com.
>> >
>> > --
>> > 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+...@googlegroups.com.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/sqlalchemy/262ddd37-0dc9-410e-94a0-25b8a82730e0n%40googlegroups.com.
>
> --
> 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/69246876-4fa1-4824-8ac0-c1f41bf779f7n%40googlegroups.com.

-- 
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/CAFHwexeiLo%2By%2B%3DB_-qR%3DdZFzbBTLmjxkCYeLbP59JjGSmKzGkw%40mail.gmail.com.

Reply via email to