Re: Delete class in model and downgrade, bulk_insert

2014-03-17 Thread Tom Haulitschke


 So, create a Table, use that, make sure you’re sending the right kinds of 
 objects to bulk_insert(). 


Thank you very much for that very quick reply, this did the trick. The 
try/except blocks in my post above were just to show what I've tried so far.

I'll include my working code so that it may help someone else:

conn = op.get_bind()

metadata = sa.MetaData()

dog_table = sa.Table('dog', metadata,
   sa.Column('id', sa.INTEGER(), primary_key=True,
 autoincrement=True),
   sa.Column('mammal_id', sa.INTEGER(), 
nullable=True),
   sa.ForeignKeyConstraint(['mammal_id'], 
[Mammal.id],
   
name='dog_mammal_id_fkey'),
   sa.PrimaryKeyConstraint('id', name='dog_pkey'))

dog_table.create(conn)

new_dogs = reconstruct_dogs()

op.bulk_insert(dog_table, new_dogs)


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy-alembic group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy-alembic+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Weird update behaviour

2014-03-17 Thread Dirk Makowski
Hello Michael,

On Sunday, March 16, 2014 10:19:16 PM UTC+1, Michael Bayer wrote:



 are you sure it’s actually saying “SET NULL” in the SQL?   if the value 
 isn’t present in the params, that just means it’s leaving it unaffected. 
  this is normal behavior when the value hasn’t changed. 

 I can’t say much else because these are only excerpts of code without 
 context. 

 if you wanted to show, “stores a NULL”, send a full script that does that 
 and asserts it’s the case. 


Yes, I'm positive, SA explicitly SETs editor_id = NULL. Please find 
attached a stand-alone script.

-- 
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.
#!/usr/bin/env python
import logging

import sqlalchemy as sa
import sqlalchemy.orm
import transaction
import zope.sqlalchemy
from sqlalchemy.ext.declarative import (
declared_attr,
declarative_base
)

logging.basicConfig(level=logging.INFO)
lgg = logging.getLogger(__name__)

salgg = logging.getLogger('sqlalchemy.engine')
salgg.setLevel(logging.INFO)

DbEngine = sa.create_engine(postgresql+psycopg2://test:test@localhost/test)
DbSession = sa.orm.scoped_session(
sa.orm.sessionmaker(
extension=zope.sqlalchemy.ZopeTransactionExtension()
)
)
DbSession.configure(bind=DbEngine)
DbBase = declarative_base(bind=DbEngine)


def _validate_editor(context):
pass
# if not context.current_parameters['editor_id']:
# raise ValueError('Editor must be set on update.')


class DefaultMixin(object):
Mixin to add Parenchym's standard fields to a model class.

These are: id, ctime, owner, mtime, editor.


id = sa.Column(sa.Integer(), primary_key=True, nullable=False)
Primary key of table.

ctime = sa.Column(sa.DateTime(), server_default=sa.func.current_timestamp(),
nullable=False)
Timestamp, creation time.

# noinspection PyMethodParameters
@declared_attr
def owner_id(cls):
ID of user who created this record.
return sa.Column(
sa.Integer(),
sa.ForeignKey(
pym.user.id,
onupdate=CASCADE,
ondelete=RESTRICT
),
nullable=False
)

mtime = sa.Column(sa.DateTime(), onupdate=sa.func.current_timestamp(), nullable=True)
Timestamp, last edit time.

# noinspection PyMethodParameters
@declared_attr
def editor_id(cls):
ID of user who was last editor.
return sa.Column(
sa.Integer(),
sa.ForeignKey(
pym.user.id,
onupdate=CASCADE,
ondelete=RESTRICT
),
nullable=True,
onupdate=_validate_editor
)


class User(DbBase, DefaultMixin):
__tablename__ = user
__table_args__ = (
{'schema': 'pym'}
)

principal = sa.Column(sa.Unicode(255), nullable=False)


class Tenant(DbBase, DefaultMixin):

A tenant.

__tablename__ = tenant
__table_args__ = (
sa.UniqueConstraint('name', name='tenant_ux'),
{'schema': 'pym'}
)

name = sa.Column(sa.Unicode(255), nullable=False)
# Load description only if needed
descr = sa.orm.deferred(sa.Column(sa.UnicodeText, nullable=True))
Optional description.

def __repr__(self):
return {name}(id={id}, name='{n}'.format(
id=self.id, n=self.name, name=self.__class__.__name__)


def setup(sess):
with transaction.manager:
sess.execute(create schema pym)
zope.sqlalchemy.mark_changed(sess)

with transaction.manager:
DbBase.metadata.create_all(DbEngine)
u1 = User()
u1.owner_id = 1
u1.principal = 'salomon'
u2 = User()
u2.owner_id = 1
u2.principal = 'sibylle'
sess.add(u1)
sess.add(u2)


def dance(sess):
lgg.info('=' * 78)
with transaction.manager:
try:
tn = sess.query(Tenant).filter(Tenant.name == 'foo').one()
cnt = tn.descr.count('o')
except sa.orm.exc.NoResultFound:
tn = Tenant()
tn.owner_id = 2
tn.name = 'foo'
tn.descr = 'o'
sess.add(tn)
cnt = 0
lgg.info('Loop {} (added): {} {} {}'.format(cnt, tn.editor_id,
tn.descr, tn.descr.count('o')))
else:
lgg.info('Loop {} (stored before change): {} {} {}'.format(cnt, tn.editor_id,
tn.descr, tn.descr.count('o')))
tn.descr += 'o'
tn.editor_id = 2
lgg.info('-' * 78)


def main():
sess = DbSession()
setup(sess)

dance(sess)
dance(sess)
dance(sess)

Re: [sqlalchemy] Weird update behaviour

2014-03-17 Thread Dirk Makowski
A slightly improved version, where I activated the 
onupdate=_validate_editor() check again to log an error if it finds 
editor_id not set.

-- 
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.
#!/usr/bin/env python
import logging

import sqlalchemy as sa
import sqlalchemy.orm
import transaction
import zope.sqlalchemy
from sqlalchemy.ext.declarative import (
declared_attr,
declarative_base
)

logging.basicConfig(level=logging.INFO)
lgg = logging.getLogger(__name__)

#salgg = logging.getLogger('sqlalchemy.engine')
#salgg.setLevel(logging.INFO)

DbEngine = sa.create_engine(postgresql+psycopg2://test:test@localhost/test)
DbSession = sa.orm.scoped_session(
sa.orm.sessionmaker(
extension=zope.sqlalchemy.ZopeTransactionExtension()
)
)
DbSession.configure(bind=DbEngine)
DbBase = declarative_base(bind=DbEngine)


def _validate_editor(context):
if not context.current_parameters['editor_id']:
#raise ValueError('Editor must be set on update.')
lgg.error(' Editor must be set on update.')
# 'editor_id' is present in current_parameters, only having a value of None.
# If a field is omitted by SA, say because the value did not change, I
# would expect to not find that key in current_parameters. If that would be
# case for editor_id, I'd expect above code to raise a KeyError.
# Is that correct?


class DefaultMixin(object):
Mixin to add Parenchym's standard fields to a model class.

These are: id, ctime, owner, mtime, editor.


id = sa.Column(sa.Integer(), primary_key=True, nullable=False)
Primary key of table.

ctime = sa.Column(sa.DateTime(), server_default=sa.func.current_timestamp(),
nullable=False)
Timestamp, creation time.

# noinspection PyMethodParameters
@declared_attr
def owner_id(cls):
ID of user who created this record.
return sa.Column(
sa.Integer(),
sa.ForeignKey(
pym.user.id,
onupdate=CASCADE,
ondelete=RESTRICT
),
nullable=False
)

mtime = sa.Column(sa.DateTime(), onupdate=sa.func.current_timestamp(), nullable=True)
Timestamp, last edit time.

# noinspection PyMethodParameters
@declared_attr
def editor_id(cls):
ID of user who was last editor.
return sa.Column(
sa.Integer(),
sa.ForeignKey(
pym.user.id,
onupdate=CASCADE,
ondelete=RESTRICT
),
nullable=True,
onupdate=_validate_editor
)


class User(DbBase, DefaultMixin):
__tablename__ = user
__table_args__ = (
{'schema': 'pym'}
)

principal = sa.Column(sa.Unicode(255), nullable=False)


class Tenant(DbBase, DefaultMixin):

A tenant.

__tablename__ = tenant
__table_args__ = (
sa.UniqueConstraint('name', name='tenant_ux'),
{'schema': 'pym'}
)

name = sa.Column(sa.Unicode(255), nullable=False)
# Load description only if needed
descr = sa.orm.deferred(sa.Column(sa.UnicodeText, nullable=True))
Optional description.

def __repr__(self):
return {name}(id={id}, name='{n}'.format(
id=self.id, n=self.name, name=self.__class__.__name__)


def setup(sess):
with transaction.manager:
sess.execute(create schema pym)
zope.sqlalchemy.mark_changed(sess)

with transaction.manager:
DbBase.metadata.create_all(DbEngine)
u1 = User()
u1.owner_id = 1
u1.principal = 'salomon'
u2 = User()
u2.owner_id = 1
u2.principal = 'sibylle'
sess.add(u1)
sess.add(u2)


def dance(sess):
lgg.info('=' * 78)
with transaction.manager:
try:
tn = sess.query(Tenant).filter(Tenant.name == 'foo').one()
except sa.orm.exc.NoResultFound:
tn = Tenant()
tn.owner_id = 2
tn.name = 'foo'
tn.descr = 'o'
sess.add(tn)
cnt = 0
lgg.info('Loop {} (added): {} {} {}'.format(cnt, tn.editor_id,
tn.descr, tn.descr.count('o')))
else:
cnt = tn.descr.count('o')
lgg.info('Loop {} (stored before change): {} {} {}'.format(cnt, tn.editor_id,
tn.descr, tn.descr.count('o')))
# XXX Have activated the onupdate=_validate_editor() check above to
# XXX log an error.
#
# If cnt == 1 we just added that record, so editor_id must be None.
# Later on, editor_id must be 

[sqlalchemy] single table hierarchy: disable polymorphism and load all as base class

2014-03-17 Thread Pau Tallada
Hi everyone :)

I have an application with some kind of dynamic model.
Several plugins define subclasses of a common base class and override their
behaviour, but they do not change any column.

In some scenarios, not all the puglins are loaded, so not all the
subclasses are present/defined in the Metadata, but I still need to query
those instances and access their columns.

Is there any option/feature/trick to temporarily disable polymorphism in a
single query (or globally for a session or engine) and load all classes as
instances of the base class?

The other option is to hack some kind of on-demand polymorphism myself into
the __new__ method of the Base class.

Thanks!

Pau.

-- 
--
Pau Tallada Crespí
Dep. d'Astrofísica i Cosmologia
Port d'Informació Científica (PIC)
Tel: +34 93 586 8233
--

-- 
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] single table hierarchy: disable polymorphism and load all as base class

2014-03-17 Thread Michael Bayer

On Mar 17, 2014, at 6:48 AM, Pau Tallada tall...@pic.es wrote:

 Hi everyone :)
 
 I have an application with some kind of dynamic model.
 Several plugins define subclasses of a common base class and override their 
 behaviour, but they do not change any column.
 
 In some scenarios, not all the puglins are loaded, so not all the subclasses 
 are present/defined in the Metadata, but I still need to query those 
 instances and access their columns.
 
 Is there any option/feature/trick to temporarily disable polymorphism in a 
 single query (or globally for a session or engine) and load all classes as 
 instances of the base class?


you can use a non primary mapper:

m = mapper(MyBase, my_base_table, non_primary=True)

s.query(m).all()



 
 The other option is to hack some kind of on-demand polymorphism myself into 
 the __new__ method of the Base class.
 
 Thanks!
 
 Pau.
 
 -- 
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --
 
 
 -- 
 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.

-- 
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] Weird update behaviour

2014-03-17 Thread Michael Bayer
This is what I suggested originally, you set tn.editor_id to 2, then you run 
the same loop over and over again.  the value of tn.editor_id does not change, 
and is not part of the parameters in the UPDATE statement. if you remove the 
column on update and look at the echoed SQL, the statements all look like this:

UPDATE tenant SET mtime=CURRENT_TIMESTAMP, descr=? WHERE tenant.id = ?

as expected, editor_id is not present - it hasn't changed, so is not present in 
the SET clause.

When you use onupdate=something, SQLAlchemy is being told to use this 
function to prepare a value for the editor_id column in the *absense* of any 
change.  That your function is being called in the first place is an indicator 
that there otherwise would be no change made to this column.  The value of 
None in the dictionary is there in preparation for the default function to be 
invoked and place something there; because the column has an ON UPDATE default, 
it means the column must unconditionally be in the SET clause of the UPDATE 
statement.  So now the SET appears and it uses None because your function has 
no return value, hence is None in Python.

So in this regard an onupdate default can't really be effectively used to 
effect no change on a column as it seems is the need here; the UPDATE statement 
has already been rendered with a SET clause including the column in question.   
 At best it could return the value that's expected to be there, but the ORM's 
notion of the object is not really accessible at this level.

the last moment you would have to validate what's to be sent as an UPDATE 
before the structure is fixed would be the before_update mapper event.The 
other option would be within the before_flush() event.





On Mar 17, 2014, at 5:08 AM, Dirk Makowski dirk.makow...@gmail.com wrote:

 A slightly improved version, where I activated the 
 onupdate=_validate_editor() check again to log an error if it finds editor_id 
 not set.
 
 -- 
 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.
 check_editor_id.py

-- 
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] Weird update behaviour

2014-03-17 Thread Dirk Makowski
So I did some debugging, the first time for me looking deeper into SA's 
code. Hopefully I did not get too lost.

In the 3rd loop, when the loaded editor_id == 2 and was again assigned 2, I 
forced a flush and stepped into SA. Down the top levels I could see SA 
bearing a loaded_value == 2 and a value == 2. After a while, near when the 
SQL was about to be constructed, editor_id vanished and only fields with 
actual different values remained. -- But, the compiled SQL statement 
somehow still insisted on having editor_id=%(editor_id)s. And then suddenly 
editor_id appears again in the parameters, with a NULL value.

Sorry for not being more precise. The actual places where the parameters 
were transformed I obviously missed.

Here are some screenshots http://parenchym.com/fridge/check_editor_id/for 
illustration.

-- 
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] Weird update behaviour

2014-03-17 Thread Dirk Makowski
Wow, great explanation, thanks a lot. This also sheds light on what I had 
seen during the debug.


On Monday, March 17, 2014 12:44:24 PM UTC+1, Michael Bayer wrote:

 This is what I suggested originally, you set tn.editor_id to “2”, then you 
 run the same loop over and over again.  the value of tn.editor_id does not 
 change, and is not part of the parameters in the UPDATE statement. if you 
 remove the column on update and look at the echoed SQL, the statements all 
 look like this:

 UPDATE tenant SET mtime=CURRENT_TIMESTAMP, descr=? WHERE tenant.id = ?

 as expected, editor_id is not present - it hasn’t changed, so is not 
 present in the SET clause.

 When you use onupdate=something, SQLAlchemy is being told to use this 
 function to prepare a value for the editor_id column in the *absense* of 
 any change.  That your function is being called in the first place is an 
 indicator that there otherwise would be no change made to this column.  The 
 value of “None” in the dictionary is there in preparation for the default 
 function to be invoked and place something there; because the column has an 
 ON UPDATE default, it means the column must unconditionally be in the SET 
 clause of the UPDATE statement.  So now the SET appears and it uses None 
 because your function has no return value, hence is None in Python.

 So in this regard an onupdate default can’t really be effectively used to 
 effect no change on a column as it seems is the need here; the UPDATE 
 statement has already been rendered with a SET clause including the column 
 in question.At best it could return the value that’s expected to be 
 there, but the ORM’s notion of the object is not really accessible at this 
 level.

 the last moment you would have to validate what’s to be sent as an UPDATE 
 before the structure is fixed would be the before_update mapper event.   
  The other option would be within the before_flush() event.





 On Mar 17, 2014, at 5:08 AM, Dirk Makowski dirk.m...@gmail.comjavascript: 
 wrote:

 A slightly improved version, where I activated the 
 onupdate=_validate_editor() check again to log an error if it finds 
 editor_id not set.

 -- 
 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/d/optout.
 check_editor_id.py




-- 
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] single table hierarchy: disable polymorphism and load all as base class

2014-03-17 Thread Pau Tallada
Great!

I think it works for my needs :D

Thank you very much!

Pau.


2014-03-17 12:28 GMT+01:00 Michael Bayer mike...@zzzcomputing.com:


 On Mar 17, 2014, at 6:48 AM, Pau Tallada tall...@pic.es wrote:

 Hi everyone :)

 I have an application with some kind of dynamic model.
 Several plugins define subclasses of a common base class and override
 their behaviour, but they do not change any column.

 In some scenarios, not all the puglins are loaded, so not all the
 subclasses are present/defined in the Metadata, but I still need to query
 those instances and access their columns.

 Is there any option/feature/trick to temporarily disable polymorphism in a
 single query (or globally for a session or engine) and load all classes as
 instances of the base class?



 you can use a non primary mapper:

 m = mapper(MyBase, my_base_table, non_primary=True)

 s.query(m).all()




 The other option is to hack some kind of on-demand polymorphism myself
 into the __new__ method of the Base class.

 Thanks!

 Pau.

 --
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --


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


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




-- 
--
Pau Tallada Crespí
Dep. d'Astrofísica i Cosmologia
Port d'Informació Científica (PIC)
Tel: +34 93 586 8233
--

-- 
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] single table hierarchy: disable polymorphism and load all as base class

2014-03-17 Thread Pau Tallada
Hi,

Can it be done in declarative?
I've tried several ways, but I cannot find a working one :/
Basically, I think I need to redefine some self-referential relationships,
as they link against the polymorphic class.


Meta = declarative_meta()

class NonPolymorphicClass(MyBaseClass):
__mapper_args__ = {
'non_primary' : True
}

== ArgumentError: Inheritance of non-primary mapper for class '
NonPolymorphicClass' is only allowed from a non-primary mapper




class NonPolymorphicClass(MyBaseClass):
__table__ = MyBaseClass.__table__
__mapper_args__ = {
'non_primary' : True
}

== ArgumentError: Inheritance of non-primary mapper for class '
NonPolymorphicClass' is only allowed from a non-primary mapper




class NonPolymorphicClass(Meta):
__mapper_args__ = {
'non_primary' : True
}

== InvalidRequestError: Class class '__main__.NonPolymorphicClass' does
not have a __table__ or __tablename__ specified and does not inherit from
an existing table-mapped class.




class NonPolymorphicClass(Meta):
__mapper_args__ = {
'non_primary' : True
}

== InvalidRequestError: Class class '__main__.NonPolymorphicClass' has
no primary mapper configured. Configure a primary mapper first before
setting up a non primary Mapper.


2014-03-17 13:09 GMT+01:00 Pau Tallada tall...@pic.es:

 Great!

 I think it works for my needs :D

 Thank you very much!

 Pau.


 2014-03-17 12:28 GMT+01:00 Michael Bayer mike...@zzzcomputing.com:


 On Mar 17, 2014, at 6:48 AM, Pau Tallada tall...@pic.es wrote:

 Hi everyone :)

 I have an application with some kind of dynamic model.
 Several plugins define subclasses of a common base class and override
 their behaviour, but they do not change any column.

 In some scenarios, not all the puglins are loaded, so not all the
 subclasses are present/defined in the Metadata, but I still need to query
 those instances and access their columns.

 Is there any option/feature/trick to temporarily disable polymorphism in
 a single query (or globally for a session or engine) and load all classes
 as instances of the base class?



 you can use a non primary mapper:

 m = mapper(MyBase, my_base_table, non_primary=True)

 s.query(m).all()




 The other option is to hack some kind of on-demand polymorphism myself
 into the __new__ method of the Base class.

 Thanks!

 Pau.

 --
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --


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


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




 --
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --




-- 
--
Pau Tallada Crespí
Dep. d'Astrofísica i Cosmologia
Port d'Informació Científica (PIC)
Tel: +34 93 586 8233
--

-- 
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] Weird update behaviour

2014-03-17 Thread Dirk Makowski
On Monday, March 17, 2014 12:44:24 PM UTC+1, Michael Bayer wrote:

 the last moment you would have to validate what’s to be sent as an UPDATE 
 before the structure is fixed would be the before_update mapper event.   
  The other option would be within the before_flush() event.


Thank you for the pointer to these events. I went for the mapper event 
before_update, and basically I could realise the intended check. But it 
turned out, this event is only fired for 'real' instances, not for mixins. 
So I could not write one event handler for DefaultMixin, but had to write 
as many as I have model classes. Is that correct or is there a way to get 
this event for mixins?
(Attached code shows this variant.)

What would have to be done to implement the check with the before_flush 
event?
Iterate over the set of instances in session.dirty, filter out those who 
actually will produce an UPDATE SQL (session.is_modified()) and perform the 
check on those?


-- 
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.
#!/usr/bin/env python
import logging

import sqlalchemy as sa
import sqlalchemy.orm
import sqlalchemy.exc
import transaction
import zope.sqlalchemy
from sqlalchemy.ext.declarative import (
declared_attr,
declarative_base
)

logging.basicConfig(level=logging.INFO)
lgg = logging.getLogger(__name__)

#salgg = logging.getLogger('sqlalchemy.engine')
#salgg.setLevel(logging.INFO)

DbEngine = sa.create_engine(postgresql+psycopg2://test:test@localhost/test)
DbSession = sa.orm.scoped_session(
sa.orm.sessionmaker(
extension=zope.sqlalchemy.ZopeTransactionExtension()
)
)
DbSession.configure(bind=DbEngine)
DbBase = declarative_base(bind=DbEngine)


# Rhoobarb
#
# def _validate_editor(context):
# if not context.current_parameters['editor_id']:
# #raise ValueError('Editor must be set on update.')
# lgg.error(' Editor must be set on update.')
# # 'editor_id' is present in current_parameters, only having a value of None.
# # If a field is omitted by SA, say because the value did not change, I
# # would expect to not find that key in current_parameters. If that would be
# # case for editor_id, I'd expect above code to raise a KeyError.
# # Is that correct?


class DefaultMixin(object):
Mixin to add Parenchym's standard fields to a model class.

These are: id, ctime, owner, mtime, editor.


id = sa.Column(sa.Integer(), primary_key=True, nullable=False)
Primary key of table.

ctime = sa.Column(sa.DateTime(), server_default=sa.func.current_timestamp(),
nullable=False)
Timestamp, creation time.

# noinspection PyMethodParameters
@declared_attr
def owner_id(cls):
ID of user who created this record.
return sa.Column(
sa.Integer(),
sa.ForeignKey(
pym.user.id,
onupdate=CASCADE,
ondelete=RESTRICT
),
nullable=False
)

mtime = sa.Column(sa.DateTime(), onupdate=sa.func.current_timestamp(), nullable=True)
Timestamp, last edit time.

# noinspection PyMethodParameters
@declared_attr
def editor_id(cls):
ID of user who was last editor.
return sa.Column(
sa.Integer(),
sa.ForeignKey(
pym.user.id,
onupdate=CASCADE,
ondelete=RESTRICT
),
nullable=True,
# Learned 20140317: Don't do this if you do not want to actively
# set a value
#onupdate=_validate_editor
)


class User(DbBase, DefaultMixin):
__tablename__ = user
__table_args__ = (
{'schema': 'pym'}
)

principal = sa.Column(sa.Unicode(255), nullable=False)


class Tenant(DbBase, DefaultMixin):

A tenant.

__tablename__ = tenant
__table_args__ = (
sa.UniqueConstraint('name', name='tenant_ux'),
{'schema': 'pym'}
)

name = sa.Column(sa.Unicode(255), nullable=False)
# Load description only if needed
descr = sa.orm.deferred(sa.Column(sa.UnicodeText, nullable=True))
Optional description.

def __repr__(self):
return {name}(id={id}, name='{n}'.format(
id=self.id, n=self.name, name=self.__class__.__name__)


@sa.event.listens_for(Tenant, 'before_update')
def receive_before_update(mapper, connection, target):
lgg.info('Received a before_update for the mixin')
lgg.info('Class name: {}'.format(target.__class__.__name__))
will_result_in_update_sql = sa.orm.object_session(target).is_modified(
target, include_collections

Re: [sqlalchemy] Feedback appreciated (again :)

2014-03-17 Thread Richard Gerd Kuesters

hello!

good job on these extensions and utilities. i have been using some of 
them, i'll give a try on the newest releases and i'll let you know. 
also, i forgot to contribute code with you on github. i'll send you an 
email directly.



best regards,
richard.


On 03/15/2014 06:11 AM, Konsta Vesterinen wrote:

Hi,

Lately I've been spending a lot of time improving some SQLAlchemy 
extensions. I'd appreciate any feedback for the new features I've made.


Some of the stuff I've been working on:

* Generic relationship support has been added for SQLAlchemy-Utils: 
http://sqlalchemy-utils.readthedocs.org/en/latest/generic_relationship.html. 
This is yet another implementation of polymorphic associations pattern 
(http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-sqlalchemy/). 
It would be very nice to see this kind of implementation in the core 
of SQLAlchemy some day. What is still needed for the 
generic_relationship is support for dependency processors and support 
for different loading strategies.


* I added full support for PostgreSQL range data types for SA-Utils: 
http://sqlalchemy-utils.readthedocs.org/en/latest/range_data_types.html. 
To be able to handle these datatypes in pythonic way I also created a 
separate package for handling interval objects on the python 
side: https://github.com/kvesteri/intervals


* Some new database 
helpers: http://sqlalchemy-utils.readthedocs.org/en/latest/database_helpers.html


* http://sqlalchemy-searchable.readthedocs.org/en/latest/ - Humanized 
search string parsing for PostgreSQL full text search vectors


* Lots of new features and tweaks for 
SQLAlchemy-Continuum: http://sqlalchemy-continuum.readthedocs.org/en/latest/, 
one especially useful feature is the ActivityPlugin 
(http://sqlalchemy-continuum.readthedocs.org/en/latest/plugins.html#module-sqlalchemy_continuum.plugins.activity) 
which uses the generic relationships of SA-Utils.


Also thanks Mike for all the hard work you've put into SA 0.9! I love 
all the new features in the 0.9 series.


- Konsta
--
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 
mailto:sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com 
mailto:sqlalchemy@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+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] single table hierarchy: disable polymorphism and load all as base class

2014-03-17 Thread Michael Bayer
maybe make a subclass of the polymorphic base, and just put __concrete__ = True 
in the mapper_args.skip the non primary part.




On Mar 17, 2014, at 8:45 AM, Pau Tallada tall...@pic.es wrote:

 Hi,
 
 Can it be done in declarative?
 I've tried several ways, but I cannot find a working one :/
 Basically, I think I need to redefine some self-referential relationships, as 
 they link against the polymorphic class.
 
 
 Meta = declarative_meta()
 
 class NonPolymorphicClass(MyBaseClass):
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == ArgumentError: Inheritance of non-primary mapper for class 
 'NonPolymorphicClass' is only allowed from a non-primary mapper
 
 
 
 
 class NonPolymorphicClass(MyBaseClass):
 __table__ = MyBaseClass.__table__
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == ArgumentError: Inheritance of non-primary mapper for class 
 'NonPolymorphicClass' is only allowed from a non-primary mapper
 
 
 
 
 class NonPolymorphicClass(Meta):
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == InvalidRequestError: Class class '__main__.NonPolymorphicClass' does 
 not have a __table__ or __tablename__ specified and does not inherit from an 
 existing table-mapped class.
 
 
 
 
 class NonPolymorphicClass(Meta):
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == InvalidRequestError: Class class '__main__.NonPolymorphicClass' has no 
 primary mapper configured.  Configure a primary mapper first before setting 
 up a non primary Mapper.
 
 
 2014-03-17 13:09 GMT+01:00 Pau Tallada tall...@pic.es:
 Great!
 
 I think it works for my needs :D
 
 Thank you very much!
 
 Pau.
 
 
 2014-03-17 12:28 GMT+01:00 Michael Bayer mike...@zzzcomputing.com:
 
 
 On Mar 17, 2014, at 6:48 AM, Pau Tallada tall...@pic.es wrote:
 
 Hi everyone :)
 
 I have an application with some kind of dynamic model.
 Several plugins define subclasses of a common base class and override their 
 behaviour, but they do not change any column.
 
 In some scenarios, not all the puglins are loaded, so not all the subclasses 
 are present/defined in the Metadata, but I still need to query those 
 instances and access their columns.
 
 Is there any option/feature/trick to temporarily disable polymorphism in a 
 single query (or globally for a session or engine) and load all classes as 
 instances of the base class?
 
 
 you can use a non primary mapper:
 
 m = mapper(MyBase, my_base_table, non_primary=True)
 
 s.query(m).all()
 
 
 
 
 The other option is to hack some kind of on-demand polymorphism myself into 
 the __new__ method of the Base class.
 
 Thanks!
 
 Pau.
 
 -- 
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --
 
 
 -- 
 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.
 
 
 -- 
 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.
 
 
 
 -- 
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --
 
 
 
 
 -- 
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --
 
 
 -- 
 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.

-- 
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] Weird update behaviour

2014-03-17 Thread Michael Bayer

On Mar 17, 2014, at 8:53 AM, Dirk Makowski dirk.makow...@gmail.com wrote:

 On Monday, March 17, 2014 12:44:24 PM UTC+1, Michael Bayer wrote:
 the last moment you would have to validate what's to be sent as an UPDATE 
 before the structure is fixed would be the before_update mapper event.The 
 other option would be within the before_flush() event.
 
 Thank you for the pointer to these events. I went for the mapper event 
 before_update, and basically I could realise the intended check. But it 
 turned out, this event is only fired for 'real' instances, not for mixins. So 
 I could not write one event handler for DefaultMixin, but had to write as 
 many as I have model classes. Is that correct or is there a way to get this 
 event for mixins?
 (Attached code shows this variant.)

you can write a handler for a mixin.  It needs 0.8 at least and you set up the 
event with the flag propagate=True, meaning it propagates to subclasses.


 
 What would have to be done to implement the check with the before_flush event?
 Iterate over the set of instances in session.dirty, filter out those who 
 actually will produce an UPDATE SQL (session.is_modified()) and perform the 
 check on those?

yes, in my own apps I'm often doing a lot of before_flush() things, so I 
usually have just one before_flush() listener that iterates through 
session.dirty and runs a series of checks on them (e.g. versioning, validation 
routines, etc).   I guess you could use is_modified() to check for a net change 
but you might want to find more of a business-level reason for the attribute to 
be present or not.

or you could just use attribute on change events to make sure that attribute 
gets the change it needs in all cases

-- 
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] single table hierarchy: disable polymorphism and load all as base class

2014-03-17 Thread Pau Tallada
Hi, I tried this, but then it selects WHERE table.type IN (NULL) :(

class NonPolymorphicClass(MyBaseClass):
__mapper_args__ = {
'concrete' : True
}

I'll try some more things, like overriding the __new__ method on the base
class, to create subclasses if they are available, and instances of the
base class if not.

Thank you very much anyway :)

Pau.


2014-03-17 15:44 GMT+01:00 Michael Bayer mike...@zzzcomputing.com:

 maybe make a subclass of the polymorphic base, and just put __concrete__ =
 True in the mapper_args.skip the non primary part.




 On Mar 17, 2014, at 8:45 AM, Pau Tallada tall...@pic.es wrote:

  Hi,

 Can it be done in declarative?
 I've tried several ways, but I cannot find a working one :/
 Basically, I think I need to redefine some self-referential relationships,
 as they link against the polymorphic class.


 Meta = declarative_meta()

 class NonPolymorphicClass(MyBaseClass):
 __mapper_args__ = {
 'non_primary' : True
 }

 == ArgumentError: Inheritance of non-primary mapper for class '
 NonPolymorphicClass' is only allowed from a non-primary mapper




 class NonPolymorphicClass(MyBaseClass):
 __table__ = MyBaseClass.__table__
 __mapper_args__ = {
 'non_primary' : True
 }

 == ArgumentError: Inheritance of non-primary mapper for class '
 NonPolymorphicClass' is only allowed from a non-primary mapper




 class NonPolymorphicClass(Meta):
 __mapper_args__ = {
 'non_primary' : True
 }

 == InvalidRequestError: Class class '__main__.NonPolymorphicClass'
 does not have a __table__ or __tablename__ specified and does not inherit
 from an existing table-mapped class.




 class NonPolymorphicClass(Meta):
 __mapper_args__ = {
 'non_primary' : True
 }

 == InvalidRequestError: Class class '__main__.NonPolymorphicClass' has
 no primary mapper configured. Configure a primary mapper first before
 setting up a non primary Mapper.


 2014-03-17 13:09 GMT+01:00 Pau Tallada tall...@pic.es:

 Great!

 I think it works for my needs :D

 Thank you very much!

 Pau.


 2014-03-17 12:28 GMT+01:00 Michael Bayer mike...@zzzcomputing.com:


 On Mar 17, 2014, at 6:48 AM, Pau Tallada tall...@pic.es wrote:

 Hi everyone :)

 I have an application with some kind of dynamic model.
 Several plugins define subclasses of a common base class and override
 their behaviour, but they do not change any column.

 In some scenarios, not all the puglins are loaded, so not all the
 subclasses are present/defined in the Metadata, but I still need to query
 those instances and access their columns.

 Is there any option/feature/trick to temporarily disable polymorphism in
 a single query (or globally for a session or engine) and load all classes
 as instances of the base class?



 you can use a non primary mapper:

 m = mapper(MyBase, my_base_table, non_primary=True)

 s.query(m).all()




 The other option is to hack some kind of on-demand polymorphism myself
 into the __new__ method of the Base class.

 Thanks!

 Pau.

 --
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --


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



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




 --
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --




 --
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --


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


  --
 You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
 To unsubscribe from this group 

Re: [sqlalchemy] Weird update behaviour

2014-03-17 Thread Dirk Makowski
Really nice, you helped a lot.


On Monday, March 17, 2014 3:48:43 PM UTC+1, Michael Bayer wrote:


 On Mar 17, 2014, at 8:53 AM, Dirk Makowski dirk.m...@gmail.comjavascript: 
 wrote:

 On Monday, March 17, 2014 12:44:24 PM UTC+1, Michael Bayer wrote:

 the last moment you would have to validate what’s to be sent as an UPDATE 
 before the structure is fixed would be the before_update mapper event.   
  The other option would be within the before_flush() event.


 Thank you for the pointer to these events. I went for the mapper event 
 before_update, and basically I could realise the intended check. But it 
 turned out, this event is only fired for 'real' instances, not for mixins. 
 So I could not write one event handler for DefaultMixin, but had to write 
 as many as I have model classes. Is that correct or is there a way to get 
 this event for mixins?
 (Attached code shows this variant.)


 you can write a handler for a mixin.  It needs 0.8 at least and you set up 
 the event with the flag propagate=True, meaning it propagates to subclasses.



 What would have to be done to implement the check with the before_flush 
 event?
 Iterate over the set of instances in session.dirty, filter out those who 
 actually will produce an UPDATE SQL (session.is_modified()) and perform 
 the check on those?


 yes, in my own apps I’m often doing a lot of before_flush() things, so I 
 usually have just one before_flush() listener that iterates through 
 session.dirty and runs a series of checks on them (e.g. versioning, 
 validation routines, etc).   I guess you could use is_modified() to check 
 for a net change but you might want to find more of a business-level reason 
 for the attribute to be present or not.

 or you could just use attribute on change events to make sure that 
 attribute gets the change it needs in all cases….



-- 
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] single table hierarchy: disable polymorphism and load all as base class

2014-03-17 Thread Michael Bayer
er, guessing, polymorphic_on=None also for that class? not sure of the mapper's 
tolerance.


On Mar 17, 2014, at 12:10 PM, Pau Tallada tall...@pic.es wrote:

 Hi, I tried this, but then it selects WHERE table.type IN (NULL) :(
 
 class NonPolymorphicClass(MyBaseClass):
 __mapper_args__ = {
 'concrete' : True
 }
 
 I'll try some more things, like overriding the __new__ method on the base 
 class, to create subclasses if they are available, and instances of the base 
 class if not.
 
 Thank you very much anyway :)
 
 Pau.
 
 
 2014-03-17 15:44 GMT+01:00 Michael Bayer mike...@zzzcomputing.com:
 maybe make a subclass of the polymorphic base, and just put __concrete__ = 
 True in the mapper_args.skip the non primary part.
 
 
 
 
 On Mar 17, 2014, at 8:45 AM, Pau Tallada tall...@pic.es wrote:
 
 Hi,
 
 Can it be done in declarative?
 I've tried several ways, but I cannot find a working one :/
 Basically, I think I need to redefine some self-referential relationships, 
 as they link against the polymorphic class.
 
 
 Meta = declarative_meta()
 
 class NonPolymorphicClass(MyBaseClass):
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == ArgumentError: Inheritance of non-primary mapper for class 
 'NonPolymorphicClass' is only allowed from a non-primary mapper
 
 
 
 
 class NonPolymorphicClass(MyBaseClass):
 __table__ = MyBaseClass.__table__
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == ArgumentError: Inheritance of non-primary mapper for class 
 'NonPolymorphicClass' is only allowed from a non-primary mapper
 
 
 
 
 class NonPolymorphicClass(Meta):
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == InvalidRequestError: Class class '__main__.NonPolymorphicClass' does 
 not have a __table__ or __tablename__ specified and does not inherit from an 
 existing table-mapped class.
 
 
 
 
 class NonPolymorphicClass(Meta):
 __mapper_args__ = {
 'non_primary' : True
 }
 
 == InvalidRequestError: Class class '__main__.NonPolymorphicClass' has no 
 primary mapper configured.  Configure a primary mapper first before setting 
 up a non primary Mapper.
 
 
 2014-03-17 13:09 GMT+01:00 Pau Tallada tall...@pic.es:
 Great!
 
 I think it works for my needs :D
 
 Thank you very much!
 
 Pau.
 
 
 2014-03-17 12:28 GMT+01:00 Michael Bayer mike...@zzzcomputing.com:
 
 
 On Mar 17, 2014, at 6:48 AM, Pau Tallada tall...@pic.es wrote:
 
 Hi everyone :)
 
 I have an application with some kind of dynamic model.
 Several plugins define subclasses of a common base class and override their 
 behaviour, but they do not change any column.
 
 In some scenarios, not all the puglins are loaded, so not all the 
 subclasses are present/defined in the Metadata, but I still need to query 
 those instances and access their columns.
 
 Is there any option/feature/trick to temporarily disable polymorphism in a 
 single query (or globally for a session or engine) and load all classes as 
 instances of the base class?
 
 
 you can use a non primary mapper:
 
 m = mapper(MyBase, my_base_table, non_primary=True)
 
 s.query(m).all()
 
 
 
 
 The other option is to hack some kind of on-demand polymorphism myself into 
 the __new__ method of the Base class.
 
 Thanks!
 
 Pau.
 
 -- 
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --
 
 
 -- 
 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.
 
 
 -- 
 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.
 
 
 
 -- 
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --
 
 
 
 
 -- 
 --
 Pau Tallada Crespí
 Dep. d'Astrofísica i Cosmologia
 Port d'Informació Científica (PIC)
 Tel: +34 93 586 8233
 --
 
 
 -- 
 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.
 

[sqlalchemy] outerjoin where first selected column is a literal dies with confusing error

2014-03-17 Thread Ryan Kelly
Hi:

When I run the attached example, I get the following error:

sqlalchemy.exc.NoInspectionAvailable: No inspection system is
available for object of type type 'NoneType'

Which is a result of literal(1) appearing first in the select list.
I don't particularly care than I can't order my columns that way, but
the error message cost me about 30 minutes just trying to figure out
why.

Not sure if there is a good way to fix this or what the correct approach is.

-Ryan Kelly

-- 
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.
#!/usr/bin/env python

from sqlalchemy import create_engine, MetaData, Table, Column, Integer
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql.expression import literal


engine = create_engine(sqlite:///:memory:, echo=True)
session = sessionmaker(bind=engine)()

metadata = MetaData()

some_table = Table(some_table, metadata,
Column(foo, Integer),
)

other_table = Table(other_table, metadata,
Column(foo, Integer),
)

results = (
session.query(
literal(1),
some_table.c.foo,
other_table.c.foo)
.outerjoin(other_table, some_table.c.foo == some_table.c.foo)
).all()



Re: [sqlalchemy] outerjoin where first selected column is a literal dies with confusing error

2014-03-17 Thread Michael Bayer
when you do outerjoin() it will try to join from the first item in the list, 
unless you do select_from:

query(literal(), X.foo, Y.bar).select_from(X).join(Y, )

will see what can be done about the error message



On Mar 17, 2014, at 2:58 PM, Ryan Kelly rpkell...@gmail.com wrote:

 Hi:
 
 When I run the attached example, I get the following error:
 
 sqlalchemy.exc.NoInspectionAvailable: No inspection system is
 available for object of type type 'NoneType'
 
 Which is a result of literal(1) appearing first in the select list.
 I don't particularly care than I can't order my columns that way, but
 the error message cost me about 30 minutes just trying to figure out
 why.
 
 Not sure if there is a good way to fix this or what the correct approach is.
 
 -Ryan Kelly
 
 -- 
 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.
 t.py

-- 
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] outerjoin where first selected column is a literal dies with confusing error

2014-03-17 Thread Michael Bayer
the error message has been improved in 9ec01ab35a / 987759aec51e (0.9 / 0.8)


On Mar 17, 2014, at 4:16 PM, Michael Bayer mike...@zzzcomputing.com wrote:

 when you do outerjoin() it will try to join from the first item in the list, 
 unless you do select_from:
 
 query(literal(), X.foo, Y.bar).select_from(X).join(Y, )
 
 will see what can be done about the error message
 
 
 
 On Mar 17, 2014, at 2:58 PM, Ryan Kelly rpkell...@gmail.com wrote:
 
 Hi:
 
 When I run the attached example, I get the following error:
 
 sqlalchemy.exc.NoInspectionAvailable: No inspection system is
 available for object of type type 'NoneType'
 
 Which is a result of literal(1) appearing first in the select list.
 I don't particularly care than I can't order my columns that way, but
 the error message cost me about 30 minutes just trying to figure out
 why.
 
 Not sure if there is a good way to fix this or what the correct approach is.
 
 -Ryan Kelly
 
 -- 
 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.
 t.py
 
 -- 
 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.

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


[sqlalchemy] Is knowing change history necessary to understand ORM, or I can get away without it?

2014-03-17 Thread Bao Niu
I've been reading the documentation on Using the Session -- Merging. The 
concept like *change history*, *history stream* occur several times. I know 
the history attribute is something that belongs to the *Core*. But my 
question is, is this really useful for learning ORM? How much knowledge 
about the Core is optimal for a ORM user who just wants to quickly 
establish an application?

Pardon me if my question may not sound very technical, I'm just trying to 
elicit some guide from experienced users here so newbies like me would have 
a better idea of the route to go, instead of hesitating whether to learn 
the core first or just read orm part would be good. For experienced users 
it may not be a question but for new users learning the entire core is a 
HUGE barrier;) Many many 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/d/optout.


Re: [sqlalchemy] Is knowing change history necessary to understand ORM, or I can get away without it?

2014-03-17 Thread Michael Bayer
if you're talking about attribute history like 
attributes.get_history(MyClass.someattr) or inspect(my_object).attrs.history, 
that's all ORM stuff.   SQLAlchemy Core (which might really be better to learn 
first, if you're really reading the docs cover to cover as opposed to just 
trying to do something quickly; conceptually it is much simpler than the ORM) 
is only about SQL statements coming from Python, not object relational mapping.





On Mar 17, 2014, at 4:30 PM, Bao Niu niuba...@gmail.com wrote:

 I've been reading the documentation on Using the Session -- Merging. The 
 concept like *change history*, *history stream* occur several times. I know 
 the history attribute is something that belongs to the *Core*. But my 
 question is, is this really useful for learning ORM? How much knowledge about 
 the Core is optimal for a ORM user who just wants to quickly establish an 
 application?
 
 Pardon me if my question may not sound very technical, I'm just trying to 
 elicit some guide from experienced users here so newbies like me would have a 
 better idea of the route to go, instead of hesitating whether to learn the 
 core first or just read orm part would be good. For experienced users it may 
 not be a question but for new users learning the entire core is a HUGE 
 barrier;) Many many 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/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.


[sqlalchemy] troubleshooting mapper error

2014-03-17 Thread Jonathan Vanasco
i'm updating my db code, and this popped up:

InvalidRequestError: One or more mappers failed to initialize - can't 
proceed with initialization of other mappers.  Original exception was: id() 
takes exactly one argument
is there any way to tell where/how this got triggered?  There's nothing 
useful in the callstack.  It appeared on a query to a table that hasn't 
been worked on.

-- 
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] troubleshooting mapper error

2014-03-17 Thread Michael Bayer
its probably the Python builtin id being referenced somewhere


On Mar 17, 2014, at 7:28 PM, Jonathan Vanasco jonat...@findmeon.com wrote:

 i'm updating my db code, and this popped up:
 
   InvalidRequestError: One or more mappers failed to initialize - can't 
 proceed with initialization of other mappers.  Original exception was: id() 
 takes exactly one argument
   
 is there any way to tell where/how this got triggered?  There's nothing 
 useful in the callstack.  It appeared on a query to a table that hasn't been 
 worked on.
 
 -- 
 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.

-- 
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] troubleshooting mapper error

2014-03-17 Thread Jonathan Vanasco
thanks. i finally found it.  

i was querying TableA

TableA  mapped somewhere  to TableB

Table B had a backref on an 'id' field.  that field got removed.

the query on TableA triggered the error , even though I wasn't loading the 
'id' field.  because of how the backref was constructed, it was not 
apparent/expected to require editing; nor was it a candidate for the cause 
of this bug.

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


[sqlalchemy] Unique Many-to-Many

2014-03-17 Thread Morgan McClure
I'm trying to make a many-to-many relationship using sqlalchemy 0.9 and 
postgres

If I put a unique constraint on the join table, and I add a duplicate, I 
get an integrity error.
If I change the collection class to set, it won't double commit, however a 
set prevents me from using things like order_by.

In my scenario, I'm massively multi-threaded and so the check-before commit 
methodology won't work (proven it breaks with 24 processes).
Is it possible to get a nice elegant solution to this without defining a 
custom collection_class?

I believe this is a regression (enhancement?) from version 0.8, but on 0.8 
I was using mysql and now I'm using postgres.


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


[sqlalchemy] order by before group by

2014-03-17 Thread Jonathan Herriott
Hi,

I was creating a billing table that needs to be updated on repeated cycles 
as more information becomes available for a month, so I was following an 
Add Only scheme where I only add new rows, so we can keep track of the 
history of the month.  Now, when I show them a list of bills for the year, 
I only want to show them the most up to date for each month, so initially, 
I was doing something like:

session.query(Bill).filter_by(account_id=id).order_by(Bill.timestamp.desc()).group_by(Bill.date_begin)

Unfortunately, this doesn't compile a query in the read order or something 
comparable.  Second, I tried:

stmt = 
session.query(Bill).filter_by(account_id=id).order_by(Bill.timestamp.desc()).subquery()
session.query(stmt).group_by(Bill.date_begin)

This does get me the correct result, however, the problem is, for backwards 
compatibility, this does not actually return a list of Bill objects, but 
instead, it returns a list of KeyedTuples.  Is there a way to achieve what 
I want with sqlalchemy?

Thanks,
Jon

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


[sqlalchemy] Re: order by before group by

2014-03-17 Thread Jonathan Herriott
Ok, I figured it out.

stmt = 
session.query(Bill).filter_by(account_id=id).order_by(Bill.timestamp.desc()).subquery()
session.query().add_entity(Bill, alias=stmt).group_by(Bill.date_begin)

On Monday, March 17, 2014 7:44:09 PM UTC-7, Jonathan Herriott wrote:

 Hi,

 I was creating a billing table that needs to be updated on repeated cycles 
 as more information becomes available for a month, so I was following an 
 Add Only scheme where I only add new rows, so we can keep track of the 
 history of the month.  Now, when I show them a list of bills for the year, 
 I only want to show them the most up to date for each month, so initially, 
 I was doing something like:


 session.query(Bill).filter_by(account_id=id).order_by(Bill.timestamp.desc()).group_by(Bill.date_begin)

 Unfortunately, this doesn't compile a query in the read order or something 
 comparable.  Second, I tried:

 stmt = 
 session.query(Bill).filter_by(account_id=id).order_by(Bill.timestamp.desc()).subquery()
 session.query(stmt).group_by(Bill.date_begin)

 This does get me the correct result, however, the problem is, for 
 backwards compatibility, this does not actually return a list of Bill 
 objects, but instead, it returns a list of KeyedTuples.  Is there a way to 
 achieve what I want with sqlalchemy?

 Thanks,
 Jon


-- 
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] Unique Many-to-Many

2014-03-17 Thread Michael Bayer

On Mar 17, 2014, at 10:38 PM, Morgan McClure mcclure.mor...@gmail.com wrote:

 I'm trying to make a many-to-many relationship using sqlalchemy 0.9 and 
 postgres
 
 If I put a unique constraint on the join table, and I add a duplicate, I get 
 an integrity error.
 If I change the collection class to set, it won't double commit, however a 
 set prevents me from using things like order_by.
 
 In my scenario, I'm massively multi-threaded and so the check-before commit 
 methodology won't work (proven it breaks with 24 processes).
 Is it possible to get a nice elegant solution to this without defining a 
 custom collection_class?
 
 I believe this is a regression (enhancement?) from version 0.8, but on 0.8 I 
 was using mysql and now I'm using postgres.

im not seeing how this is any kind of change from version 8 to 9, or even from 
version 7, 6, or 5;  a list will certainly allow duplicates that will give you 
integrity errors, and a set certainly won't.   using many processes of course 
you can't coordinate those in memory with a set, only the database knows the 
right answer.

the approach here unfortunately is to use traditional means of adding new rows 
while checking for an existing one.   which means either emitting a SELECT 
first and ensuring adequate coordination between these 24 processes using 
transaction isolation or locks, or using a simple optimistic approach where you 
start a savepoint (begin_nested()), attempt the operation, catch IntegrityError 
and then continue with the row now known to be already present.

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