Re: [sqlalchemy] Injecting User info into _history table to track who performed the change

2021-03-24 Thread JPLaverdure
Yup, makes perfect sense.

So what the code/fix is achieving, in effect, is what is described here:
https://docs.sqlalchemy.org/en/13/faq/ormconfiguration.html#i-m-getting-a-warning-or-error-about-implicitly-combining-column-x-under-attribute-y
Just using a different approach because of the inheritance. 

Cheers,

JP
On Wednesday, March 24, 2021 at 3:49:12 p.m. UTC-4 Simon King wrote:

> I'm not 100% confident here (the history_meta code does some pretty
> complicated stuff to deal with inheritance), but I'll give it a go:
>
> 1. You've adapted history_meta to add an extra column to history
> tables, called "accountable".
> 2. You've got an inheritance hierarchy (CompoundAdministration
> inherits from Process)
> 3. Both CompoundAdministration and Process use the Versioned mixin
> 4. This results in 2 new mapped classes, ProcessHistory and
> CompoundAdministrationHistory.
> 5. CompoundAdministrationHistory inherits from ProcessHistory
>
> Step 5 is the problem: CompoundAdministrationHistory inherits from
> ProcessHistory, but both tables have an "accountable" column. Normally
> that's a problem - when you set the
> CompoundAdministrationHistory.accountable attribute, should SQLAlchemy
> update the column in the compound_administration_history table, or
> process_history, or both? SQLAlchemy defaults to updating both, but
> warns you about the ambiguity.
>
> In this case, you really do want that property to target both columns,
> so your fix is correct:
>
> properties["accountable"] = (table.c.accountable,) + tuple(
> super_history_mapper.attrs.accountable.columns
> )
>
> This says that the "accountable" property should target the column on
> the local (inheriting) table as well as whatever columns the parent
> class was targeting.
>
> You should test that when you modify a CompoundAdministration object,
> you get a new row in both the compound_administration_history and the
> process_history tables, and that the "accountable" column is set
> correctly.
>
> I hope that makes sense,
>
> Simon
>
> On Wed, Mar 24, 2021 at 2:25 PM JPLaverdure  wrote:
> >
> > Hi Simon,
> >
> > Thanks for pointing out the collision, it kinda flew under the radar !
> > I renamed the column from "user" to "accountable" and but still got
> >
> > SAWarning:
> > Implicitly combining column process_history.accountable with column 
> compound_administration_history.accountable under attribute 'accountable'.
> > Please configure one or more attributes for these same-named columns 
> explicitly.
> >
> > As mentioned, these tables both also have a "changed" attribute, but did 
> not throw the warnings...
> > Looking a bit further, I spotted this piece of code in history_meta:
> > properties["changed"] = (table.c.changed,) + tuple(
> > super_history_mapper.attrs.changed.columns
> > )
> > So I added:
> > properties["accountable"] = (table.c.accountable,) + tuple(
> > super_history_mapper.attrs.accountable.columns
> > )
> >
> > And the warnings have disappeared.
> >
> > Could you explain what these instructions actually do ?
> >
> > Thanks
> > On Wednesday, March 24, 2021 at 5:18:02 a.m. UTC-4 Simon King wrote:
> >>
> >> 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  
> 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))
> >> > prob

Re: [sqlalchemy] Injecting User info into _history table to track who performed the change

2021-03-24 Thread JPLaverdure
Hi Simon,

Thanks for pointing out the collision, it kinda flew under the radar !
I renamed the column from "user" to "accountable" and but still got 

SAWarning: 
Implicitly combining column process_history.accountable with column 
compound_administration_history.accountable under attribute 'accountable'.  
Please configure one or more attributes for these same-named columns 
explicitly.

As mentioned, these tables both also have a "changed" attribute, but did 
not throw the warnings...
Looking a bit further, I spotted this piece of code in history_meta:
properties["changed"] = (table.c.changed,) + tuple(
super_history_mapper.attrs.changed.columns
)
So I added:
properties["accountable"] = (table.c.accountable,) + tuple(
super_history_mapper.attrs.accountable.columns
)

And the warnings have disappeared.

Could you explain what these instructions actually do ?

Thanks
On Wednesday, March 24, 2021 at 5:18:02 a.m. UTC-4 Simon King wrote:

> 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  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  
> 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,
&

Re: [sqlalchemy] Injecting User info into _history table to track who performed the change

2021-03-24 Thread JPLaverdure
Sure !  Here's an example.
This is the base 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'))

an one of the child classes:

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)


I have many types of processes that derive from the parent class and all of 
these throws a warning linked to the "user" Column Added in their 
respective _history.
For reference I implemented versioning using this recipe:
https://docs.sqlalchemy.org/en/13/_modules/examples/versioned_history/history_meta.html

I added my "user" column definition right under the "changed" column in 
history_meta.py.
The "changed" column does not trigger the warnings but my newly added 
"user" column does. 
So I'm guessing there is a extra step I forgot to add in the 
history_meta.py file but I cannot find what or where..

Thanks !
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  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

Re: [sqlalchemy] Injecting User info into _history table to track who performed the change

2021-03-23 Thread JPLaverdure
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  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 be

Re: [sqlalchemy] Injecting User info into _history table to track who performed the change

2021-03-22 Thread JPLaverdure
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  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.
>&g

Re: [sqlalchemy] Injecting User info into _history table to track who performed the change

2021-03-14 Thread JPLaverdure
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  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
>>  
>> <https://groups.google.com/d/msgid/sqlalchemy/82a24998-14e1-4ff4-a725-dd25c20a8bf2n%40googlegroups.com?utm_medium=email_source=footer>
>> .
>>
>
>
> -- 
>
> 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+unsubscr...@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] Injecting User info into _history table to track who performed the change

2021-03-12 Thread JPLaverdure
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/82a24998-14e1-4ff4-a725-dd25c20a8bf2n%40googlegroups.com.


Re: [sqlalchemy] SAWarnings when using history_meta.py versioning and Inheritance.

2014-10-21 Thread JPLaverdure
Hi Michael,

I quite agree that child entities don't need their own copy of the 
changed attribute, but this is also the way that the version attribute 
is handled.
(ie: both parent and child entities have their own copy of version)
Is there any way we can fix the both of them ?

As for the option to remove the changed attribute... Well, I'm the one 
who suggested its addition and submitted the pull request :)

Thanks,

JP

On Friday, 17 October 2014 16:05:15 UTC-4, Michael Bayer wrote:


 On Oct 17, 2014, at 3:50 PM, JPLaverdure jp.lav...@gmail.com 
 javascript: wrote:

 Hi Michael,

 My bad, they do indeed only show up on mapping... which takes place when 
 my pyramid app instantiates. Sorry for the confusion :)
 Still, they could be unnerving for someone deploying the app. Any way to 
 not have these show up ?
 I did look into version_meta.py and tried to make some tweaks when I saw 
 anything having to do with the version atribute.. But to no avail.

 Your help is greatly appreciated !


 it’s not clear why a class that inherits from another needs a separate 
 “changed” column in any case. The recipe indicates on line 68 this 
 column is optional so I’d remove it, or just make it conditional if 
 “super_mapper” is not present to have it only on the base table.   or maybe 
 just map it differently, or not at all, down where it calls mapper():

 m = mapper(
 versioned_cls,
 table,
 inherits=super_history_mapper,
 polymorphic_on=polymorphic_on,
 polymorphic_identity=local_mapper.polymorphic_identity,
 exclude_columns=[‘changed’]
 )







 JP   

 On Friday, 17 October 2014 14:52:22 UTC-4, JPLaverdure wrote:

 Hello,

 It seems a number of SAWarnings are being thrown whenever I instantiate 
 Versioned objects which make use of inheritance:

 SAWarning: Implicitly combining column container_history.changed with 
 column barcoded_container_history.changed under attribute 'changed'.  
 Please configure one or more attributes for these same-named columns 
 explicitly.
 prop = self._property_from_column(key, prop)

 Unfortunately, since these objects are instantiated auto-magically by 
 the Versioned mixin class, I can't see a way to make these go away or 
 address the issue.
 I tried looking into the history_meta.py source and cannot understand why 
 this same warning is not being thrown for the version attribute.

 Anyone has an idea ?

 Thanks !

 JP


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




-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] SAWarnings when using history_meta.py versioning and Inheritance.

2014-10-21 Thread JPLaverdure
I fully agree with you and had forgotten that version was part of the 
primary key.
I believe I made the appropriate changes to history_meta.py and will submit 
a pull request shortly

As always, thanks for your help !

JP

On Tuesday, 21 October 2014 14:41:15 UTC-4, Michael Bayer wrote:

 “version” is part of the primary key and is FK’ed to the superclass table, 
 so the warning isn’t generated for that one.

 it wouldn’t be appropriate for a datetime “changed” to have a foreign key. 
  IMO it only needs to be on the base table.




 On Oct 21, 2014, at 2:35 PM, JPLaverdure jp.lav...@gmail.com 
 javascript: wrote:

 Hi Michael,

 I quite agree that child entities don't need their own copy of the 
 changed attribute, but this is also the way that the version attribute 
 is handled.
 (ie: both parent and child entities have their own copy of version)
 Is there any way we can fix the both of them ?

 As for the option to remove the changed attribute... Well, I'm the one 
 who suggested its addition and submitted the pull request :)

 Thanks,

 JP

 On Friday, 17 October 2014 16:05:15 UTC-4, Michael Bayer wrote:


 On Oct 17, 2014, at 3:50 PM, JPLaverdure jp.lav...@gmail.com wrote:

 Hi Michael,

 My bad, they do indeed only show up on mapping... which takes place when 
 my pyramid app instantiates. Sorry for the confusion :)
 Still, they could be unnerving for someone deploying the app. Any way to 
 not have these show up ?
 I did look into version_meta.py and tried to make some tweaks when I saw 
 anything having to do with the version atribute.. But to no avail.

 Your help is greatly appreciated !


 it’s not clear why a class that inherits from another needs a separate 
 “changed” column in any case. The recipe indicates on line 68 this 
 column is optional so I’d remove it, or just make it conditional if 
 “super_mapper” is not present to have it only on the base table.   or maybe 
 just map it differently, or not at all, down where it calls mapper():

 m = mapper(
 versioned_cls,
 table,
 inherits=super_history_mapper,
 polymorphic_on=polymorphic_on,
 polymorphic_identity=local_mapper.polymorphic_identity,
 exclude_columns=[‘changed’]
 )







 JP   

 On Friday, 17 October 2014 14:52:22 UTC-4, JPLaverdure wrote:

 Hello,

 It seems a number of SAWarnings are being thrown whenever I instantiate 
 Versioned objects which make use of inheritance:

 SAWarning: Implicitly combining column container_history.changed with 
 column barcoded_container_history.changed under attribute 'changed'.  
 Please configure one or more attributes for these same-named columns 
 explicitly.
 prop = self._property_from_column(key, prop)

 Unfortunately, since these objects are instantiated auto-magically by 
 the Versioned mixin class, I can't see a way to make these go away or 
 address the issue.
 I tried looking into the history_meta.py source and cannot understand 
 why this same warning is not being thrown for the version attribute.

 Anyone has an idea ?

 Thanks !

 JP


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



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




-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Multi-Level inheritance and history_meta versioning issue

2013-11-08 Thread JPLaverdure
Hi Michael,

Thanks for your response.

Is release 0.9 stable enough to use in a production env ?

When you mention that it isn't supported I'm a bit surprised/confused..
As such, the inheritance scheme has worked fine using 0.8 as long as I 
wan't dipping in the history of the objects.  
(_history is a necessary evil in my case, and to be frank, I tend to avoid 
going into it.. it's more of a last ditch security net)

This is actually the first time I need to retrieve some data from the 
history layer of a 3rd inheritance level object.

Anyhow,  I'll certainly give the latest version a spin but remain nervous 
of the fact that it's still in beta. 
Will get back to you shortly.

JP


On Thursday, November 7, 2013 8:36:53 PM UTC-5, Michael Bayer wrote:

 try out r29a07fc09a6c11b3e05457e2a from git master or rel_0_9, I have 
 multilevel joined inheritance working there now.


 On Nov 7, 2013, at 8:23 PM, Michael Bayer 
 mik...@zzzcomputing.comjavascript: 
 wrote:

 I can’t even get multi-level inheritance to set up the mappers correctly, 
 it’s not supported right now.   Would need some fixes.




 On Nov 7, 2013, at 11:38 AM, JPLaverdure jp.lav...@gmail.comjavascript: 
 wrote:

 I seem to be having an issue when calling up the history of a versioned 
 SQLAlchemy class.
 I have the following inheritance structure setup:

 Node(Versioned, Base)
 Specimen(Node)
 Animal(Specimen)


 If I attempt to fetch the animal history using the query generated by :

 AnimalHistory = self.__history_mapper__.class_
 q = object_session(self).query(AnimalHistory).filter(AnimalHistory.id == 
 self.id).order_by(AnimalHistory.version.desc())
 
 logger.debug(q)


 I get the following query:

 SELECT bla bla #trimmed for brevity 
 FROM node_history 
 JOIN specimen_history ON node_history.id = specimen_history.id AND 
 node_history.version = specimen_history.version 
 JOIN animal_history ON specimen_history.id = animal_history.id 
 WHERE animal_history.id = 28 
 ORDER BY animal_history.version DESC


 Basically, I seem to be missing the appropriate AND statement on the 
 animal_history JOIN.
 Because of this, I get an unwanted cartesian product between animal and 
 (specimen, node)

 Could anyone point out the modification needed inside history_meta.py in 
 order to fix this ?

 Thanks !!

 -- 
 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 javascript:.
 To post to this group, send email to sqlal...@googlegroups.comjavascript:
 .
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.





-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] Multi-Level inheritance and history_meta versioning issue

2013-11-08 Thread JPLaverdure
Hey Michael,

Tried out the new version and the _history now functions as it should :)

Many thanks !

Also: over time, I had added an extra field to the _history tables 
corresponding to the modification datetime (as a timestamp), along with an 
extra param in the table creation call to support the presence of schemas 
(I mainly work on postgresql).
Maybe those could be included in the main distro ?
I'll submit a pull request with those changes in case you deem them 
interesting.

Cheers !

JP


On Friday, November 8, 2013 9:52:13 AM UTC-5, JPLaverdure wrote:

 Hi Michael,

 Thanks for your response.

 Is release 0.9 stable enough to use in a production env ?

 When you mention that it isn't supported I'm a bit surprised/confused..
 As such, the inheritance scheme has worked fine using 0.8 as long as I 
 wan't dipping in the history of the objects.  
 (_history is a necessary evil in my case, and to be frank, I tend to avoid 
 going into it.. it's more of a last ditch security net)

 This is actually the first time I need to retrieve some data from the 
 history layer of a 3rd inheritance level object.

 Anyhow,  I'll certainly give the latest version a spin but remain nervous 
 of the fact that it's still in beta. 
 Will get back to you shortly.

 JP


 On Thursday, November 7, 2013 8:36:53 PM UTC-5, Michael Bayer wrote:

 try out r29a07fc09a6c11b3e05457e2a from git master or rel_0_9, I have 
 multilevel joined inheritance working there now.


 On Nov 7, 2013, at 8:23 PM, Michael Bayer mik...@zzzcomputing.com 
 wrote:

 I can’t even get multi-level inheritance to set up the mappers correctly, 
 it’s not supported right now.   Would need some fixes.




 On Nov 7, 2013, at 11:38 AM, JPLaverdure jp.lav...@gmail.com wrote:

 I seem to be having an issue when calling up the history of a versioned 
 SQLAlchemy class.
 I have the following inheritance structure setup:

 Node(Versioned, Base)
 Specimen(Node)
 Animal(Specimen)


 If I attempt to fetch the animal history using the query generated by :

 AnimalHistory = self.__history_mapper__.class_
 q = object_session(self).query(AnimalHistory).filter(AnimalHistory.id == 
 self.id).order_by(AnimalHistory.version.desc())
 
 logger.debug(q)


 I get the following query:

 SELECT bla bla #trimmed for brevity 
 FROM node_history 
 JOIN specimen_history ON node_history.id = specimen_history.id AND 
 node_history.version = specimen_history.version 
 JOIN animal_history ON specimen_history.id = animal_history.id 
 WHERE animal_history.id = 28 
 ORDER BY animal_history.version DESC


 Basically, I seem to be missing the appropriate AND statement on the 
 animal_history JOIN.
 Because of this, I get an unwanted cartesian product between animal and 
 (specimen, node)

 Could anyone point out the modification needed inside history_meta.py in 
 order to fix this ?

 Thanks !!

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





-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] Multi-Level inheritance and history_meta versioning issue

2013-11-07 Thread JPLaverdure
I seem to be having an issue when calling up the history of a versioned 
SQLAlchemy class.
I have the following inheritance structure setup:

Node(Versioned, Base)
Specimen(Node)
Animal(Specimen)


If I attempt to fetch the animal history using the query generated by :

AnimalHistory = self.__history_mapper__.class_
q = object_session(self).query(AnimalHistory).filter(AnimalHistory.id == 
self.id).order_by(AnimalHistory.version.desc())

logger.debug(q)


I get the following query:

SELECT bla bla #trimmed for brevity 
FROM node_history 
JOIN specimen_history ON node_history.id = specimen_history.id AND 
node_history.version = specimen_history.version 
JOIN animal_history ON specimen_history.id = animal_history.id 
WHERE animal_history.id = 28 
ORDER BY animal_history.version DESC


Basically, I seem to be missing the appropriate AND statement on the 
animal_history JOIN.
Because of this, I get an unwanted cartesian product between animal and 
(specimen, node)

Could anyone point out the modification needed inside history_meta.py in 
order to fix this ?

Thanks !!

-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] ConcreteBase (0.7.3) only supporting 1 level of inheritance ?

2011-10-28 Thread JPLaverdure
Hello,

I started playing with Concrete Table Inheritance this morning and tried to 
implement a portion of my schema:

class Mixin(object):
__table_args__ = {'schema':'test'}

id = Column(Integer, primary_key=True)


class Node(ConcreteBase, Base, Mixin):
__tablename__ = 'node'
__mapper_args__ = {'polymorphic_identity':'node', 'concrete':True}


class Sample(Node, Mixin):
__tablename__ = 'sample'
__mapper_args__ = {'polymorphic_identity':'sample', 'concrete':True}


class DNA(Sample, Mixin):
__tablename__ = 'dna'
__mapper_args__ = {'polymorphic_identity':'dna', 'concrete':True}

token = Column(String(128), nullable=False)
qty = Column(Integer, nullable=False)
comments = Column(String(256))

def __init__(self, token, qty, comments=None):
self.token = token
self.qty = qty
self.comments = comments

def __repr__(self):
return Sample(%s, %s, Qty: %s) % (self.id, self.token, 
self.qty)


class RNA(Sample, Mixin):
__tablename__ = 'rna'
__mapper_args__ = {'polymorphic_identity':'rna', 'concrete':True}

token = Column(String(128), nullable=False)
qty = Column(Integer, nullable=False)
comments = Column(String(256))

def __init__(self, token, qty, comments=None):
self.token = token
self.qty = qty
self.comments = comments

def __repr__(self):
return RNA(%s, %s, Qty: %s) % (self.id, self.token, 
self.qty)

But after inserting some DNA and RNA entities...
It seems that:

session.query(Node).all() 

returns an empty list whereas:

session.query(Sample).all()

returns a polymorphic list of RNAs and DNAs...
Am I missing something ?


Also:
If I declare Node as per:
 
class Node(AbstractConcreteBase, Base):
   pass

Instead of above, I get the following error:
 assert mapper is mapper.base_mapper
AssertionError

In a perfect world, I would have both Node and Sample as abstract classes 
but I can't seem to get that going..

Any pointers ?
Thanks !



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/xojj7cGtMqcJ.
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.



Re: [sqlalchemy] ConcreteBase (0.7.3) only supporting 1 level of inheritance ?

2011-10-28 Thread JPLaverdure
Hello Michael,

Sorry to be the thorn in your side.. 
I attached a test case as requested.. Ticket 2312.

Also, it seems this is incompatible with history_meta based versioning.
(Which probably has to do with the use of the 
__declare_last__()
function.

Thank you

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/JhizOFgIq_QJ.
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.



Re: [sqlalchemy] Versioning and Foreign Keys

2011-09-20 Thread JPLaverdure
Hi Michael,

Thanks for your reply... Your input is always very resourcefull, thanks !
I put together a small example which doesn't seem to function as expected:

class Sample(Base):
__metaclass__ = VersionedMeta
__tablename__ = 'sample'
__table_args__ = {'schema':'test'}

id = Column(Integer, primary_key=True)
token = Column(String(64))
box_id = Column(Integer, ForeignKey('test.box.id', onupdate='cascade', 
ondelete='cascade'), nullable=False)

def __init__(self, token, box):
self.token = token
self.box = box


class Container(Base):
__metaclass__ = VersionedMeta
__tablename__ = 'container'
__table_args__ = {'schema':'test'}

id = Column(Integer, primary_key=True)
discriminator = Column('type', String(64))
token = Column(String(128), nullable=False)
description = Column(String)

__mapper_args__ = {'polymorphic_on': discriminator, 
'polymorphic_identity':'container'}

def __init__(self, token, description=''):
self.token = token
self.description = description


class Box(Container):
__tablename__ = 'box'
__table_args__ = {'schema':'test'}
__mapper_args__ = {'polymorphic_identity': 'box'}

id = Column(Integer, ForeignKey('test.container.id', onupdate=cascade, 
ondelete=cascade), primary_key=True)
barcode = Column(String(64))

samples = relationship('Sample', backref='box')

def __init__(self, token, description='', barcode=''):
super(Box, self).__init__(token, description)
self.barcode = barcode


Base.metadata.drop_all()
Base.metadata.create_all()
Session = scoped_session(sessionmaker(extension=VersionedListener()))

sess = Session()

b = Box('Big box', 'sample1') 
sess.add(b)
s = Sample('New sample', b)
sess.add(s)
sess.commit()

sess.delete(b)
sess.commit()

This fails because of the nullable=False clause on the Sample foreign key 
as SQLA seems to try to update the sample to set box_id to null... 
console printout: (from the delete portion)

2011-09-20 11:41:51,021 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2011-09-20 11:41:51,022 INFO sqlalchemy.engine.base.Engine SELECT 
test.container.type AS test_container_type, test.box.id AS test_box_id, 
test.container.id AS test_container_id, test.container.token AS 
test_container_token, test.container.description AS 
test_container_description, test.container.version AS 
test_container_version, test.box.barcode AS test_box_barcode 
FROM test.container JOIN test.box ON test.container.id = test.box.id 
WHERE test.container.id = %(param_1)s
2011-09-20 11:41:51,023 INFO sqlalchemy.engine.base.Engine {'param_1': 1}
2011-09-20 11:41:51,025 INFO sqlalchemy.engine.base.Engine SELECT 
test.sample.id AS test_sample_id, test.sample.token AS test_sample_token, 
test.sample.box_id AS test_sample_box_id, test.sample.version AS 
test_sample_version 
FROM test.sample 
WHERE %(param_1)s = test.sample.box_id
2011-09-20 11:41:51,025 INFO sqlalchemy.engine.base.Engine {'param_1': 1}
2011-09-20 11:41:51,028 INFO sqlalchemy.engine.base.Engine INSERT INTO 
test.container_history (id, type, token, description, version) VALUES 
(%(id)s, %(type)s, %(token)s, %(description)s, %(version)s)
2011-09-20 11:41:51,028 INFO sqlalchemy.engine.base.Engine {'token': u'Big 
box', 'version': 1, 'type': u'box', 'id': 1, 'description': u'sample1'}
2011-09-20 11:41:51,029 INFO sqlalchemy.engine.base.Engine INSERT INTO 
test.box_history (id, barcode, version) VALUES (%(id)s, %(barcode)s, 
%(version)s)
2011-09-20 11:41:51,029 INFO sqlalchemy.engine.base.Engine {'barcode': u'', 
'id': 1, 'version': 1}
2011-09-20 11:41:51,031 INFO sqlalchemy.engine.base.Engine UPDATE 
test.sample SET box_id=%(box_id)s WHERE test.sample.id = %(test_sample_id)s
2011-09-20 11:41:51,031 INFO sqlalchemy.engine.base.Engine {'box_id': None, 
'test_sample_id': 1}
2011-09-20 11:41:51,032 INFO sqlalchemy.engine.base.Engine ROLLBACK


So it does indeed seem to visit the sample, but I must be doing something 
wrong in my declaration because SQLA should be attempting to delete the 
sample not update it !

Thanks

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/XAPy4uSlJAMJ.
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.



Re: [sqlalchemy] Versioning and Foreign Keys

2011-09-20 Thread JPLaverdure
Oh god...

I thought the statements used when declaring the ForeignKey (ondelete, 
onupdate) would imply that the relationship function in the same manner.
I didn't think the 2 would be decoupled so much.. Although now that you 
point it out, it does seem consistent. 

I guess when I thought the children where deleted but not saved in _history, 
I did not have the nullable=False statement on the foreign key and when they 
did not show up in the _history table, didn't think of looking back in the 
children's table to realise they had not been deleted.

Sorry for the trouble... Seems like I owe you a beer or two now.

JP

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/JOR1NVrg2bYJ.
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.



[sqlalchemy] Versioning and Foreign Keys

2011-09-19 Thread JPLaverdure
Hello,

I'm using the versioned objects suggested in the SQLAlchemy examples:
http://www.sqlalchemy.org/docs/orm/examples.html#versioned-objects

One of the aspects of entity management seems a bit weird though:
If entities are linked using foreign keys, (let's say in one-to-many 
relationship), deleting the parent will indeed delete the children 
(because of the on delete cascade clause)
but the last state of the children will NOT be saved in the _history table 
of the children So I basically lose the last state of the children.
ie: the parent _history is saved but none of the children are.

I of course solved this by running a delete on all children prior to 
deleting the parent but as my model grows in complexity, I would sure love 
for all of this to be done automagically.
in other words for versioned_meta to follow foreign keys and mark and linked 
entities them as modified as well.

I might be doing something wrong or this might be specific to postgresql... 
But I don't think that's the case... 

What would I need to modify in versioned_meta to allow for this ?
Is it even possible ?

Thanks !

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/S-Qf8WjS08IJ.
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.



[sqlalchemy] Re: Versioning and Foreign Keys

2011-09-19 Thread JPLaverdure
Oops, above references to versioned_meta should read history_meta.

Sorry

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/0ZtFX94qz_wJ.
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.



Re: [sqlalchemy] Re: Versioning and multi-level inheritance

2011-08-31 Thread JPLaverdure
Hi Michael,

Thank you for your reply.
Unfortunately, the mistake was all mine... 
At some point (and for an obscure reason...), I had stopped using the 
VersionedListener so changes were no longer registering in the DB :-/

So sorry !

JP

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/WhQyp4AmxWsJ.
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.



[sqlalchemy] Re: Querying specific class using String name of class

2011-08-23 Thread JPLaverdure
Hi Mike,

Thanks for the reply. 
I'm just not sure that using `eval` represents a cleaner way than my 
original code...

The Class query options are specified by the end user through a select 
(html form) so using eval poses a security risk I would like to avoid.

I was hoping slqalchemy would give me a clean way to access mapped objects 
using a String as Identifier. Like a getter of some kind.

JP

  
 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/JPo9YefjDXgJ.
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.



[sqlalchemy] Querying specific class using String name of class

2011-08-22 Thread JPLaverdure
Hello,

Is there a proper way to retrieve a class using its name other than going 
through the _decl_class_registry dictionary of declarative_base ?
I'm using the Joined Table Inheritance and would like to enable users to 
query specific subtypes.

ie: if I have the following structure:
Base  = declarative_base()

class Sample(Base):
  bla

class Tissue(Sample):
  bla

class DNA(Sample):
  bla

I would like to build a query using 'DNA' as class type...
session.query('DNA').all()

But this doesn't work so the solution I found is the following:
session.query(Base._decl_class_registry['DNA'])

Is this the only way to go or is there a cleaner way to obtain a class based 
on its String name ?

Thanks !


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/wL8psJb1Jp4J.
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.



[sqlalchemy] Versioning and multi-level inheritance

2011-06-16 Thread JPLaverdure
Hello,

I'm trying to use the versioning recipe describe on the website along
with a multi-level inheritance model (Joined-Table inheritance)

Here are my declarative statements:

[code]
class Sample(Base):
__metaclass__ = VersionedMeta
__tablename__ = 'sample'
__table_args__ = {'schema': 'test'}

id = Column(Integer, primary_key=True)
discriminator = Column('type', String(50))
token = Column(String(128), nullable=False)
source_sample_id = Column(Integer, ForeignKey('test.sample.id'))

children = relationship(Sample, backref=backref('source_sample',
remote_side=id), single_parent=True)

__mapper_args__ = {'polymorphic_on': discriminator,
'polymorphic_identity':'sample'}

def __init__(self, token, source_sample_id=None):
self.token = token
self.source_sample_id = source_sample_id

class Tissue(Sample):
__metaclass__ = VersionedMeta
__tablename__ = 'tissue'
__mapper_args__ = {'polymorphic_identity': 'tissue'}
__table_args__ = {'schema': 'test'}

id = Column(Integer, ForeignKey('test.sample.id'),
primary_key=True)
concentration = Column(String(32))

def __init__(self, token, concentration, source_sample_id=None):
super(Sample, self).__init__(token, source_sample_id)
self.concentration = concentration

class LeukemicTissue(Tissue):
__metaclass__ = VersionedMeta
__tablename__ = 'leukemic_tissue'
__mapper_args__ = {'polymorphic_identity': 'leukemic_tissue'}
__table_args__ = {'schema': 'test'}

id = Column(Integer, ForeignKey('test.tissue.id'),
primary_key=True)
leukemia = Column(String)

def __init__(self, token, concentration, leukemia,
source_sample_id=None):
super(Tissue, self).__init__(token, concentration,
source_sample_id)
self.leukemia = leukemia
[/code]


Whenever I try to create_all() I get the following error:
sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships
between 'tissue_history' and 'leucegene_tissue_history'.

Single level-inheritance works beautifully (ie if I stop at Tissue
and don't declare the LeukemicTissue) but I really need a multi-
level inheritance scheme to work..

Can anyone give me any pointers ?

Thanks !!

-- 
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.