[sqlalchemy] Polymorphic concrete inheritance question

2008-12-03 Thread Gaetan de Menten
Hello all,

I've been playing a bit with polymorphic concrete inheritance, and
noticed that when you have several levels of polymorphic loading (ie
my child class is also a parent class which I want to load
polymorphically), the query for the top-level class includes the child
polymorphic join while I don't see any reason to (its table is already
contained in the parent join). See attached example.

class A(object):
...

class B(A):
pass

class C(B):
pass

The query ends up something like:

SELECT [all_columns] FROM ([pjoin_abc]), ([pjoin_bc])

Am I using it wrong, or is this a bug?

-- 
Gaëtan de Menten
http://openhex.org

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---

from sqlalchemy import *
from sqlalchemy.orm import *

metadata = MetaData()
metadata.bind = 'sqlite:///'

a_table = Table('a', metadata,
Column('id', Integer, primary_key=True),
Column('data1', String(20))
)
b_table = Table('b', metadata,
Column('id', Integer, primary_key=True),
Column('data1', String(20)),
Column('data2', String(20))
)
c_table = Table('c', metadata,
Column('id', Integer, primary_key=True),
Column('data1', String(20)),
Column('data2', String(20)),
Column('data3', String(20))
)

metadata.create_all()

class A(object):
def __init__(self, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)

class B(A):
pass

class C(B):
pass

pjoin_all = polymorphic_union({
'a': a_table,
'b': b_table,
'c': c_table
}, 'type', 'pjoin')

pjoin_bc = polymorphic_union({
'b': b_table,
'c': c_table
}, 'type', 'pjoin_bc')


a_m = mapper(A, a_table,
 with_polymorphic=('*', pjoin_all),
 polymorphic_on=pjoin_all.c.type,
 polymorphic_identity='a')
b_m = mapper(B, b_table,
 inherits=a_m, concrete=True,
 with_polymorphic=('*', pjoin_bc),
 polymorphic_on=pjoin_bc.c.type,
 polymorphic_identity='b')
c_m = mapper(C, c_table,
 inherits=b_m, concrete=True,
 polymorphic_identity='c')

Session = sessionmaker()
session = Session()

a1 = A(data1='a1')
b1 = B(data1='b1', data2='b1')
c1 = C(data1='c1', data2='c1', data3='c1')

session.add(a1)
session.add(b1)
session.add(c1)
session.commit()

metadata.bind.echo = True

session.query(A).all()
print * * 20, B, * * 20
session.query(B).all()



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread az

hm i had not run my tests for quite a while.. this seems recent thing.
lets see if i can dig anything of help... nothing much, one side 
works, another not at all.

one of my set of inheritance tests (direct over sa, A-B) is ok.

the other one (over dbcook) fails completely, even for A-B 
inheritance. But they seem same as mapping... there's something 
really subtle.
i either get a sort of decart product, or empty result.

and also i stepped on this:
  File sqlalchemy/orm/mapper.py, line 168, in __init__
self.with_polymorphic[1] = self.with_polymorphic[1].alias()
TypeError: 'tuple' object does not support item assignment

ciao
svil

On Wednesday 03 December 2008 11:06:24 Gaetan de Menten wrote:
 Hello all,

 I've been playing a bit with polymorphic concrete inheritance, and
 noticed that when you have several levels of polymorphic loading
 (ie my child class is also a parent class which I want to load
 polymorphically), the query for the top-level class includes the
 child polymorphic join while I don't see any reason to (its table
 is already contained in the parent join). See attached example.

 class A(object):
 ...

 class B(A):
 pass

 class C(B):
 pass

 The query ends up something like:

 SELECT [all_columns] FROM ([pjoin_abc]), ([pjoin_bc])

 Am I using it wrong, or is this a bug?



--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: inferring object class/table directly

2008-12-03 Thread rdmurray

On Tue, 2 Dec 2008 at 23:21, Faheem Mitha wrote:
 Yes, I was looking for this, and printed out obj.__dict__ but didn't
 see it there. A dictionary of attributes is very useful in theory, but
 doesn't always seem to have all attributes. Is this documented
 anywhere?

Try dir(obj).  You'll see it there.  The __dict__ is only for instance
attributes.

 Not too difficult.  You can also use type(obj) instead of
 obj.__class__.

 I thought of trying this, but didn't. It didn't seem likely to work,
 anyway. Is either of these preferred over the other in terms of API
 stability, and if so, why?

obj.__class__ is a python thing, as is type(obj), and neither of
those is changing in python 3.0, so I'd think both would be stable API
wise :)  However, the documentation of __class__ makes it clear you
get the class back, while the documentation of the 'type' built in
function does not...so I'd lean toward using __class__, myself.  It
also means you'll get an earlier error if you accidentally pass
something that is not actually a class instance into your function.

--RDM

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Michael Bayer

um yeah, actually this behavior is affecting all multi-level usage of  
polymorphic_union.   So, while polymorphic_union is quite obviously  
(since nobody has noticed this pretty glaring issue) on the decline in  
the 0.5 series, this is quite severe and ill try to have a look at it  
today.

On Dec 3, 2008, at 4:06 AM, Gaetan de Menten wrote:

 Hello all,

 I've been playing a bit with polymorphic concrete inheritance, and
 noticed that when you have several levels of polymorphic loading (ie
 my child class is also a parent class which I want to load
 polymorphically), the query for the top-level class includes the child
 polymorphic join while I don't see any reason to (its table is already
 contained in the parent join). See attached example.

 class A(object):
...

 class B(A):
pass

 class C(B):
pass

 The query ends up something like:

 SELECT [all_columns] FROM ([pjoin_abc]), ([pjoin_bc])

 Am I using it wrong, or is this a bug?

 -- 
 Gaëtan de Menten
 http://openhex.org

 
 from sqlalchemy import *
 from sqlalchemy.orm import *

 metadata = MetaData()
 metadata.bind = 'sqlite:///'

 a_table = Table('a', metadata,
Column('id', Integer, primary_key=True),
Column('data1', String(20))
 )
 b_table = Table('b', metadata,
Column('id', Integer, primary_key=True),
Column('data1', String(20)),
Column('data2', String(20))
 )
 c_table = Table('c', metadata,
Column('id', Integer, primary_key=True),
Column('data1', String(20)),
Column('data2', String(20)),
Column('data3', String(20))
 )

 metadata.create_all()

 class A(object):
def __init__(self, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)

 class B(A):
pass

 class C(B):
pass

 pjoin_all = polymorphic_union({
'a': a_table,
'b': b_table,
'c': c_table
 }, 'type', 'pjoin')

 pjoin_bc = polymorphic_union({
'b': b_table,
'c': c_table
 }, 'type', 'pjoin_bc')


 a_m = mapper(A, a_table,
 with_polymorphic=('*', pjoin_all),
 polymorphic_on=pjoin_all.c.type,
 polymorphic_identity='a')
 b_m = mapper(B, b_table,
 inherits=a_m, concrete=True,
 with_polymorphic=('*', pjoin_bc),
 polymorphic_on=pjoin_bc.c.type,
 polymorphic_identity='b')
 c_m = mapper(C, c_table,
 inherits=b_m, concrete=True,
 polymorphic_identity='c')

 Session = sessionmaker()
 session = Session()

 a1 = A(data1='a1')
 b1 = B(data1='b1', data2='b1')
 c1 = C(data1='c1', data2='c1', data3='c1')

 session.add(a1)
 session.add(b1)
 session.add(c1)
 session.commit()

 metadata.bind.echo = True

 session.query(A).all()
 print * * 20, B, * * 20
 session.query(B).all()



--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Gaetan de Menten

On Wed, Dec 3, 2008 at 15:03, Michael Bayer [EMAIL PROTECTED] wrote:

 um yeah, actually this behavior is affecting all multi-level usage of
 polymorphic_union.   So, while polymorphic_union is quite obviously
 (since nobody has noticed this pretty glaring issue) on the decline in
 the 0.5 series, this is quite severe and ill try to have a look at it
 today.

Do you want a bug report for this?

-- 
Gaëtan de Menten
http://openhex.org

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Michael Bayer
this ones big, i can handle it.   the attached patch makes your case  
work, but the problem represented here still makes itself apparent in  
other ways and I havent strength tested this patch.   you might want  
to see if this patch works in all of your test cases.


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---

Index: lib/sqlalchemy/orm/query.py
===
--- lib/sqlalchemy/orm/query.py (revision 5405)
+++ lib/sqlalchemy/orm/query.py (working copy)
@@ -1647,7 +1647,8 @@
 
 self.entities = [entity]
 self.entity_zero = entity
-
+self._has_polymorphic_selectable = False
+
 def setup_entity(self, entity, mapper, adapter, from_obj, 
is_aliased_class, with_polymorphic):
 self.mapper = mapper
 self.extension = self.mapper.extension
@@ -1668,6 +1669,7 @@
 
 mappers, from_obj = self.mapper._with_polymorphic_args(cls_or_mappers, 
selectable)
 self._with_polymorphic = mappers
+self._has_polymorphic_selectable = bool(from_obj)
 
 # TODO: do the wrapped thing here too so that with_polymorphic() can be
 # applied to aliases
@@ -1748,7 +1750,7 @@
 if adapter:
 context.order_by = 
adapter.adapt_list(util.to_list(context.order_by))
 
-for value in 
self.mapper._iterate_polymorphic_properties(self._with_polymorphic):
+for value in 
self.mapper._iterate_polymorphic_properties(self._with_polymorphic, 
self._has_polymorphic_selectable):
 if query._only_load_props and value.key not in 
query._only_load_props:
 continue
 value.setup(
Index: lib/sqlalchemy/orm/mapper.py
===
--- lib/sqlalchemy/orm/mapper.py(revision 5406)
+++ lib/sqlalchemy/orm/mapper.py(working copy)
@@ -862,18 +862,20 @@
 
 @property
 def _default_polymorphic_properties(self):
-return util.unique_list(
+return iter(util.unique_list(
 chain(*[list(mapper.iterate_properties) for mapper in [self] + 
self._with_polymorphic_mappers])
-)
-
-def _iterate_polymorphic_properties(self, mappers=None):
-if mappers is None:
-return iter(self._default_polymorphic_properties)
+))
+
+def _iterate_polymorphic_properties(self, mappers=None, 
has_selectable=False):
+if has_selectable or (self.with_polymorphic and 
self.with_polymorphic[1]):
+return self.iterate_properties
+elif mappers is None:
+return self._default_polymorphic_properties
 else:
 return iter(util.unique_list(
 chain(*[list(mapper.iterate_properties) for mapper in [self] + 
mappers])
 ))
-
+
 @property
 def properties(self):
 raise NotImplementedError(Public collection of MapperProperty objects 
is 


On Dec 3, 2008, at 9:22 AM, Gaetan de Menten wrote:


 On Wed, Dec 3, 2008 at 15:03, Michael Bayer  
 [EMAIL PROTECTED] wrote:

 um yeah, actually this behavior is affecting all multi-level usage of
 polymorphic_union.   So, while polymorphic_union is quite obviously
 (since nobody has noticed this pretty glaring issue) on the decline  
 in
 the 0.5 series, this is quite severe and ill try to have a look at it
 today.

 Do you want a bug report for this?

 -- 
 Gaëtan de Menten
 http://openhex.org

 --~--~-~--~~~---~--~~
 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 [EMAIL PROTECTED]
 For more options, visit this group at 
 http://groups.google.com/group/sqlalchemy?hl=en
 -~--~~~~--~~--~--~---




[sqlalchemy] relation join problem

2008-12-03 Thread Dom

Hi

i tried the following example, but i cant get the join to work:

CREATE TABLE product (

   idINTEGER,
   price   NUMERIC(15,2) NOT NULL,

   PRIMARY KEY(id)
);

CREATE TABLE i18n_product (
   id   INTEGER,
   lang   VARCHAR(2),
   descriptionVARCHAR(150) NOT NULL,

   PRIMARY KEY(id, lang),
   FOREIGN KEY(id) REFERENCES product(id)
);

python:

class Product(Base):
__table__ = Table('product', Base.metadata, autoload=True)

class I18NProduct(Base):
__table__ = Table('i18n_product', Base.metadata, autoload=True)
product = relation(Product, backref=backref('i18n'))

x=session.query(Product).filter(Product.id==1183).join('i18n').filter
(I18NProduct.lang=='en').one()

the sql looks of the JOIN looks good, but if i access x.i18n, another
queries is build which returns all of my language entry for one
product, what i try to get is one product description in the given
language.

please tell me how to do that correctly, thank you :)

cheers
Dom

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Gaetan de Menten

On Wed, Dec 3, 2008 at 16:04, Michael Bayer [EMAIL PROTECTED] wrote:

 this ones big, i can handle it.   the attached patch makes your case
 work, but the problem represented here still makes itself apparent in
 other ways and I havent strength tested this patch.   you might want
 to see if this patch works in all of your test cases.

FWIW, my (only) more complete test involving polymorphic concrete
inheritance passes too (and produces correct SQL).
Your patch seem fine and doesn't seem to break unrelated tests.

Thanks for the quick reaction time, as usual.
-- 
Gaëtan de Menten
http://openhex.org

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: New instance ExtraStat with identity key (...) conflicts with persistent instance ExtraStat

2008-12-03 Thread Doug Farrell

I've met so few other Farrells, maybe we ARE related!! Get it, related,
in a SqlAlchemy group. Oh man I'm such a geek!!

 -Original Message-
 From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED]
 On Behalf Of Bob
 Sent: Tuesday, December 02, 2008 9:00 AM
 To: sqlalchemy@googlegroups.com
 Subject: [sqlalchemy] Re: New instance ExtraStat with identity key
 (...) conflicts with persistent instance ExtraStat
 
 
 I keep thinking one of my relatives has emailed me when you post here
 and I get all excited. Any chance you can change your name ? :-)
 
 2008/12/2 Doug Farrell [EMAIL PROTECTED]:
  Michael,
 
 
 
  Thanks for the pointer, that makes great sense, and once again
points
 how my
  generally small database design skills. I'll update my code to try
 this out.
 
 
 
  Again,
 
  Thanks!
 
  Doug
 
 
 
  From: sqlalchemy@googlegroups.com
 [mailto:[EMAIL PROTECTED] On
  Behalf Of Michael Bayer
  Sent: Saturday, November 29, 2008 9:28 PM
  To: sqlalchemy@googlegroups.com
  Subject: [sqlalchemy] Re: New instance ExtraStat with identity key
 (...)
  conflicts with persistent instance ExtraStat
 
 
 
  Simon's suggestion about the duplicate name still holds.  Your
 relation
  from Stat-ExtraStat currently needs to be one-to-one since you
 cannot have
  more than one ExtraStat referencing a single Stat, due to the PK
 constraint
  on ExtraStat.name.  The error is raising at the point of query()
 since
  autoflush is kicking in - use session.flush() to isolate the error.
 
 
 
  On Nov 29, 2008, at 12:18 PM, Doug Farrell wrote:
 
  Hi all,
 
 
 
  I'm having a problem with a new instance of a relation conflicting
 with
 
  an existing instance. I'm using SA 0.5rc with Sqlite3. Here are my
 
  simplified classes:
 
 
 
  class Stat(sqladb.Base):
 
   __tablename__ = stats
 
   name = Column(String(32), primary_key=True)
 
   total= Column(Integer)
 
   created  = Column(DateTime,
default=datetime.datetime.now())
 
   updated  = Column(DateTime)
 
   states   = Column(PickleType, default={})
 
   extraStats   = relation(ExtraStat, backref=stat)
 
 
 
  class ExtraStat(sqladb.Base):
 
   __tablename__ = extrastats
 
   name = Column(String(32), ForeignKey(stats.name),
  primary_key=True)
 
   total= Column(Integer)
 
   created  = Column(DateTime,
default=datetime.datetime.now())
 
   updated  = Column(DateTime)
 
   states   = Column(PickleType, default={})
 
 
 
  The above Stat class has a one-to-many relationship with the
 ExtraStat
 
  class (which I think I've implemented correctly). Later in the
 
  program I create an in memory data model that has as part of it's
 
  components two
 
  dictionaries that contain Stat instances. Those Stat instances have
 
  relationships to ExtraStat instances. My problem comes in the
 
  following when I'm trying to update the data in those
 instances/tables.
 
  Here is a section of code that throws the exception:
 
 
 
 
 
 
 
  pressName = press%s % pressNum
 
  # add new ExtraStat instances as relations
 
  self._addProductStatsPress(productType, pressName)
 
  self._addPressStatsProduct(pressName, productType)
 
  try:
 
 extraStat = session.query(Stat). \
 
 filter(Stat.name==productType). \
 
 join(extraStats). \
 
 filter(ExtraStat.name==pressName).one()
 
  except:
 
 extraStat = ExtraStat(pressName, ExtraStat.PRESS_TYPE)
 
 self.productStats[productType].extraStats.append(extraStat)
 
 extraStat.states.setdefault(sstate, 0)
 
 extraStat.states[sstate] += 1
 
 extraStat.updated = now
 
 extraStat = session.merge(extraStat)
 
  try:
 
 extraStat = session.query(Stat). \
 
 filter(Stat.name==pressName). \
 
 join(extraStats). \
 
 filter(ExtraStat.name==productType).one()   
 throws
  exception right here
 
  except:
 
 extraStat = ExtraStat(productType, ExtraStat.PRODUCT_TYPE)
 
 self.pressStats[pressName].extraStats.append(extraStat)
 
 extraStat.states.setdefault(sstate, 0)
 
 extraStat.states[sstate] += 1
 
 extraStat.updated = now
 
 
 
  The marked area is wear it throws the exception. I'm not sure what
to
 
  do here to get past this, any help or ideas would be greatly
 
  appreciated.
 
 
 
  The exact exception is as follows:
 
  Sqlalchemy.orm.exc.FlushError: New instance [EMAIL PROTECTED] With
 identity
 
  key (class '__main__.ExtraStat',(u'C',)) conflicts with persistent
 
  instance [EMAIL PROTECTED]
 
 
 
  Thanks!
 
  Doug
 
 
 
 
 
  
 
 
  
 r more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en
 -~--~~~~--~~--~--~---


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to 

[sqlalchemy] removing instrumentation from a mapped object

2008-12-03 Thread Simon

Hi there,

is there any canonical way of removing all SQAlchemy instrumentation
from a mapped object?

I'm trying to feed a complex mapped class instance through PyAMF
(which serializes objects to be read in Adobe Flash). This works fine
for scalar attributes but not for collections, e.g. a one-to-many
relation collection. PyAMF getattr()s the list, which is actually not
a list() but a sqlalchemy.orm.collections.InstrumentedList, and
subsequently tries to encode all of its _* and __* attributes.

Thanks, Simon

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Michael Bayer

it needed some more work.  the final version of this fix is in r5412.


On Dec 3, 2008, at 10:49 AM, Gaetan de Menten wrote:


 On Wed, Dec 3, 2008 at 16:04, Michael Bayer  
 [EMAIL PROTECTED] wrote:

 this ones big, i can handle it.   the attached patch makes your case
 work, but the problem represented here still makes itself apparent in
 other ways and I havent strength tested this patch.   you might want
 to see if this patch works in all of your test cases.

 FWIW, my (only) more complete test involving polymorphic concrete
 inheritance passes too (and produces correct SQL).
 Your patch seem fine and doesn't seem to break unrelated tests.

 Thanks for the quick reaction time, as usual.
 -- 
 Gaëtan de Menten
 http://openhex.org

 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: removing instrumentation from a mapped object

2008-12-03 Thread Simon

On 3 Dez., 18:32, Michael Bayer [EMAIL PROTECTED] wrote:
 I would also posit that PyAMF's behavior might be inappropriate in  
 this case.  InstrumentedList is a subclass of list so I don't  
 immediately see why it would treat it differently.

Upon further inspection, this was exactly the case. Basically telling
PyAMF to encode lists as list, not as generic object, solved my
problem. For the record, here's how it works (using PyAMF 0.3.1):

amf3.Encoder.type_map.insert(0, ((list,), writeList))

Michael, you saved my day. Thank you :-)
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] SQLAlchemy Sphinx Documentation Preview

2008-12-03 Thread Michael Bayer

We've created a new branch and are in the process of migrating all of  
our documentation over to Sphinx.   The process has gone well and we  
have a working demo of the full system online.  By converting to  
Sphinx, we get the huge advantage of being on a standardized platform  
that everyone can understand and contribute towards.  All kinds of  
wacky old code, some of it four or more years old, has been removed  
(and we thank it for its service).   The docs are now split into Main  
Documentation and API Reference.  Because Sphinx allows very  
flexible layout of docstring-generated documentation, Main  
Documentation is shrinking and the docstrings used by API  
Reference, which is an all new section that replaces the old  
straight down modules display, are growing dramatically, which means  
more documentation is centralized across the site/pydocs and there's  
less redundancy.

What we are now looking for with regards to the demo is:

- comments/suggestions regarding layout, styling.  Some layout  
changes were forced by Sphinx,  and others (most) are improvements  
that Sphinx allowed us to achieve.  I'm not a CSS guru or a designer  
so suggested patches to the CSS and templates would be welcome.   If  
Todd Grimason is out there, feel free to chime in :) .

- proofreaders.  The content on the demo is maybe 60% of the way  
there and we're combing through finding issues related to the Sphinx  
conversion, as well as things that have just been wrong all along.
We would love to get patches against the doc build correcting as many  
issues as possible.

- authors.   No excuses now , we're on the most standard platform  
there is for docs.  If you have better verbiage for sections or  
docstrings which aren't clear, are nonexistent (like many of the  
dialects) or are out of date (theres lots), we want to see  
suggestions.  More elaborate suggestions regarding new sections and  
organization are welcome too as the structure is completely open ended.

- people who understand LaTex to work on the PDF side of things.   
This one's totally over my head as far as how to get a pdf file out of  
this thing (pdflatex is fairly inscrutable on a mac).

Sphinx 0.6 is required, which at the time of this writing is not yet  
released so you'll have to check out Sphinx from its mercurial  
repository if you want to do builds.

View the content online at: http://www.sqlalchemy.org/docs/sphinxtest/
Checkout the SVN branch and do a build:  
http://svn.sqlalchemy.org/sqlalchemy/branches/sphinx

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: relation join problem

2008-12-03 Thread Simon

That would be

desc = session.query(I18Product).filter_by(id=1183, lang=en).one()

The Problem with your query is that you query() for Product, not for
I18NProduct, so regardless of and filter and join functions you
specify, you will always receice Product objects. Think of query
(Product) as a final filter which creates Product objects from the
returned rows, and ignores everything which is not a column of
Product.

For x.i18n (a property of Product) to work as you described, have a
look at 
http://www.sqlalchemy.org/docs/04/mappers.html#advdatamapping_relation_collections
. You'd basically want to setup your relation() as a dict using the
lang column as key.

Simon

On 3 Dez., 16:33, Dom [EMAIL PROTECTED] wrote:
 Hi

 i tried the following example, but i cant get the join to work:

 CREATE TABLE product (

    id                INTEGER,
    price           NUMERIC(15,2) NOT NULL,

    PRIMARY KEY(id)
 );

 CREATE TABLE i18n_product (
    id                       INTEGER,
    lang                   VARCHAR(2),
    description        VARCHAR(150) NOT NULL,

    PRIMARY KEY(id, lang),
    FOREIGN KEY(id) REFERENCES product(id)
 );

 python:

 class Product(Base):
     __table__ = Table('product', Base.metadata, autoload=True)

 class I18NProduct(Base):
     __table__ = Table('i18n_product', Base.metadata, autoload=True)
     product = relation(Product, backref=backref('i18n'))

 x=session.query(Product).filter(Product.id==1183).join('i18n').filter
 (I18NProduct.lang=='en').one()

 the sql looks of the JOIN looks good, but if i access x.i18n, another
 queries is build which returns all of my language entry for one
 product, what i try to get is one product description in the given
 language.

 please tell me how to do that correctly, thank you :)

 cheers
 Dom
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Abstract base class

2008-12-03 Thread Guillaume

Hello,

is there a way with the ORM layer to have abstract base class like in
django ?
http://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-
classes

Another somehow related question is there any plan for declarative
base to support inheritance ala django ?

Regards,
  Guillaume

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: inferring object class/table directly

2008-12-03 Thread Faheem Mitha

On Wed, 3 Dec 2008 08:58:42 -0500 (EST), [EMAIL PROTECTED]
[EMAIL PROTECTED] wrote:

 On Tue, 2 Dec 2008 at 23:21, Faheem Mitha wrote:
 Yes, I was looking for this, and printed out obj.__dict__ but didn't
 see it there. A dictionary of attributes is very useful in theory, but
 doesn't always seem to have all attributes. Is this documented
 anywhere?

 Try dir(obj).  You'll see it there.  The __dict__ is only for instance
 attributes.

Excellent. This is the first I've heard of this function, but
apparently it is a Python builtin. Well past time to go read the docs
for this, I guess.

 Not too difficult.  You can also use type(obj) instead of
 obj.__class__.

 I thought of trying this, but didn't. It didn't seem likely to work,
 anyway. Is either of these preferred over the other in terms of API
 stability, and if so, why?

 obj.__class__ is a python thing, as is type(obj), and neither of
 those is changing in python 3.0, so I'd think both would be stable API
 wise :)  However, the documentation of __class__ makes it clear you
 get the class back, while the documentation of the 'type' built in
 function does not...so I'd lean toward using __class__, myself.  It
 also means you'll get an earlier error if you accidentally pass
 something that is not actually a class instance into your function.

Thanks. That's very helpful.
 Regards, Faheem.



--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Abstract base class

2008-12-03 Thread Michael Bayer


On Dec 3, 2008, at 1:26 PM, Guillaume wrote:


 Hello,

 is there a way with the ORM layer to have abstract base class like in
 django ?
 http://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-
 classes

sure, just pass along cls=MyBaseClass along to declarative_base().
You can also make your own metaclass if you wanted, and pass it in as  
metaclass=MyMetaClass, or you can use the individual components within  
declarative_base explicitly if you wanted to roll it yourself.   This  
is all in the docstrings for declarative.

 Another somehow related question is there any plan for declarative
 base to support inheritance ala django ?

declarative supports all three of SQLA's table inheritance forms  
fully.It pretty much happens automatically when you make a  
subclass, and you just need to pass along polymorphic_on/ 
polymorphic_identity into __mapper_args__.   If Django supported some  
kind of inheritance scenario that we don't I'd be very interested to  
see that :) .




--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread az

this is still there:
  File sqlalchemy/orm/mapper.py, line 168, in __init__
    self.with_polymorphic[1] = self.with_polymorphic[1].alias()
TypeError: 'tuple' object does not support item assignment

also, related question: once there is A-B-C, concrete, how u'd get 
some A by id? query(A).filter_by(id=1) returns 3 objects, one of 
A,B,C. i guess some filter( mapper.polymorphic_on == 'Aidentity') 
should be there, but how to guess if A is inherited concrete hence 
needs that?
or is that automaticaly done by query.get() and i missed it?

On Wednesday 03 December 2008 19:29:31 Michael Bayer wrote:
 it needed some more work.  the final version of this fix is in
 r5412.

 On Dec 3, 2008, at 10:49 AM, Gaetan de Menten wrote:
  On Wed, Dec 3, 2008 at 16:04, Michael Bayer
 
  [EMAIL PROTECTED] wrote:
  this ones big, i can handle it.   the attached patch makes your
  case work, but the problem represented here still makes itself
  apparent in other ways and I havent strength tested this patch. 
   you might want to see if this patch works in all of your test
  cases.
 
  FWIW, my (only) more complete test involving polymorphic
  concrete inheritance passes too (and produces correct SQL).
  Your patch seem fine and doesn't seem to break unrelated tests.
 
  Thanks for the quick reaction time, as usual.
  --
  Gaëtan de Menten
  http://openhex.org

 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread az

and maybe related:
 def query_by_id( klas, idname, oid, .):
 q = session.query( klas).filter_by( **{idname: oid})
 # filter by atype for concrete
 m = class_mapper( klas)
 concrete = bool( m.with_polymorphic[1] )
 if concrete: q= q.filter( m.polymorphic_on == klas.__name__)
 return q.all()

generates a query like 

SELECT pu_a.*
FROM (SELECT A.* FROM A 
 UNION ALL
 SELECT C.* FROM C) 
AS pu_a,
(SELECT A.* FROM A 
 UNION ALL 
 SELECT C.* FROM C) 
AS pu_a 
WHERE pu_a.db_id = ? AND pu_a.atype = ?

with repeated union twice in the FROM, and error thereof. 
Somehow the mapper.polymorphic_on is not recognized as already being 
there and pulls the union once more?
if there's no q.filter( m.polymorphic_on == klas.__name__), no errors 
(but returns multiple objects).

this on latest trunk.

svil

On Wednesday 03 December 2008 19:29:31 Michael Bayer wrote:
 it needed some more work.  the final version of this fix is in
 r5412.

 On Dec 3, 2008, at 10:49 AM, Gaetan de Menten wrote:
  On Wed, Dec 3, 2008 at 16:04, Michael Bayer
 
  [EMAIL PROTECTED] wrote:
  this ones big, i can handle it.   the attached patch makes your
  case work, but the problem represented here still makes itself
  apparent in other ways and I havent strength tested this patch. 
   you might want to see if this patch works in all of your test
  cases.
 
  FWIW, my (only) more complete test involving polymorphic
  concrete inheritance passes too (and produces correct SQL).
  Your patch seem fine and doesn't seem to break unrelated tests.
 
  Thanks for the quick reaction time, as usual.
  --
  Gaëtan de Menten
  http://openhex.org

 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Michael Bayer

thats strange, i dont suppose you could send me how you're setting up  
that polymorphic union

On Dec 3, 2008, at 3:05 PM, [EMAIL PROTECTED] wrote:


 and maybe related:
 def query_by_id( klas, idname, oid, .):
 q = session.query( klas).filter_by( **{idname: oid})
 # filter by atype for concrete
 m = class_mapper( klas)
 concrete = bool( m.with_polymorphic[1] )
 if concrete: q= q.filter( m.polymorphic_on == klas.__name__)
 return q.all()

 generates a query like

 SELECT pu_a.*
 FROM (SELECT A.* FROM A
 UNION ALL
 SELECT C.* FROM C)
 AS pu_a,
 (SELECT A.* FROM A
 UNION ALL
 SELECT C.* FROM C)
 AS pu_a
 WHERE pu_a.db_id = ? AND pu_a.atype = ?

 with repeated union twice in the FROM, and error thereof.
 Somehow the mapper.polymorphic_on is not recognized as already being
 there and pulls the union once more?
 if there's no q.filter( m.polymorphic_on == klas.__name__), no errors
 (but returns multiple objects).

 this on latest trunk.

 svil

 On Wednesday 03 December 2008 19:29:31 Michael Bayer wrote:
 it needed some more work.  the final version of this fix is in
 r5412.

 On Dec 3, 2008, at 10:49 AM, Gaetan de Menten wrote:
 On Wed, Dec 3, 2008 at 16:04, Michael Bayer

 [EMAIL PROTECTED] wrote:
 this ones big, i can handle it.   the attached patch makes your
 case work, but the problem represented here still makes itself
 apparent in other ways and I havent strength tested this patch.
 you might want to see if this patch works in all of your test
 cases.

 FWIW, my (only) more complete test involving polymorphic
 concrete inheritance passes too (and produces correct SQL).
 Your patch seem fine and doesn't seem to break unrelated tests.

 Thanks for the quick reaction time, as usual.
 --
 Gaëtan de Menten
 http://openhex.org




 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread az

can i... maybe something like

table_A = Table( 'A', meta,
Column( 'name', String(length=200, ), ),
Column( 'db_id',   primary_key= True,   type_= Integer, ),
)
table_B = Table( 'B', meta,
Column( 'dataB', String(length=200 ),
Column( 'db_id',   primary_key= True,   type_= Integer, ),
)
table_C = Table( 'C', meta,
Column( 'name', String(length=200 ),
Column( 'dataC', String(length=200 ),
Column( 'db_id',   primary_key= True,   type_= Integer, ),
)

meta.create_all()

class A( Base):
props = ['db_id', 'name']
class B( Base):
props = ['db_id', 'dataB']
class C( A):
props = ['db_id', 'name', 'dataC']

pu_a = polymorphic_union( {
'A': table_A,
'C': table_C,
}, 'atype', 'pu_a', ) #concrete table
mapper_A = mapper( A, table_A,
polymorphic_identity= 'A',
polymorphic_on= pu_a.c.atype,
with_polymorphic= ('*', pu_a.alias( 'pu_a' )),
)

mapper_B = mapper( B, table_B,
with_polymorphic= None,
)

mapper_C = mapper( C, table_C,
concrete= True,
inherits= mapper_A,
polymorphic_identity= 'C',
with_polymorphic= None,
)

#populate
a = A()
b = B()
c = C()
a.name = 'anna'
b.dataB = 'gun'
c.name = 'cc'
c.dataC = 'mc'

session = create_session()
session.save(a)
session.save(b)
session.save(c)
session.flush()

def query_by_id( session, klas, idname, oid, ):
#single
if config.session_clear: session.clear()
q = session.query( klas).filter_by( **{idname: oid})
#TODO: filter by atype for concrete?
m = class_mapper( klas)
concrete = bool( m.with_polymorphic[1] )
print 
print m.polymorphic_on
print m.with_polymorphic[1].c.atype
if concrete: q= q.filter( m.polymorphic_on == 
klas.__name__)
#if concrete: q= q.filter( m.with_polymorphic[1].c.atype 
== klas.__name__)
return q.all()
print query_by_id( session, A, 'db_id', 1, str(a) )

filtering by m.with_polymorphic[1].c.atype is ok (commented).

i guess i see the error: 
polymorphic_on is on pu_a, 
with_polymorphic is on pu_a.alias()...
but u have some autoaliasing in there anyway, no?


btw, have u planned to get relations to polymorphic concretes to work 
somewhen ? eventualy query.get(id) to work? i.e. identity to include 
the type


On Wednesday 03 December 2008 22:21:12 Michael Bayer wrote:
 thats strange, i dont suppose you could send me how you're setting
 up that polymorphic union

 On Dec 3, 2008, at 3:05 PM, [EMAIL PROTECTED] wrote:
  and maybe related:
  def query_by_id( klas, idname, oid, .):
  q = session.query( klas).filter_by( **{idname: oid})
  # filter by atype for concrete
  m = class_mapper( klas)
  concrete = bool( m.with_polymorphic[1] )
  if concrete: q= q.filter( m.polymorphic_on == klas.__name__)
  return q.all()
 
  generates a query like
 
  SELECT pu_a.*
  FROM (SELECT A.* FROM A
  UNION ALL
  SELECT C.* FROM C)
  AS pu_a,
  (SELECT A.* FROM A
  UNION ALL
  SELECT C.* FROM C)
  AS pu_a
  WHERE pu_a.db_id = ? AND pu_a.atype = ?
 
  with repeated union twice in the FROM, and error thereof.
  Somehow the mapper.polymorphic_on is not recognized as already
  being there and pulls the union once more?
  if there's no q.filter( m.polymorphic_on == klas.__name__), no
  errors (but returns multiple objects).
 
  this on latest trunk.
 
  svil
 
  On Wednesday 03 December 2008 19:29:31 Michael Bayer wrote:
  it needed some more work.  the final version of this fix is in
  r5412.
 
  On Dec 3, 2008, at 10:49 AM, Gaetan de Menten wrote:
  On Wed, Dec 3, 2008 at 16:04, Michael Bayer
 
  [EMAIL PROTECTED] wrote:
  this ones big, i can handle it.   the attached patch makes
  your case work, but the problem represented here still makes
  itself apparent in other ways and I havent strength tested
  this patch. you might want to see if this patch works in all
  of your test cases.
 
  FWIW, my (only) more complete test involving polymorphic
  concrete inheritance passes too (and produces correct SQL).
  Your patch seem fine and doesn't seem to break unrelated tests.
 
  Thanks for the quick reaction time, as usual.
  --
  Gaëtan de Menten
  http://openhex.org

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to 

[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread az

  this is still there:
File sqlalchemy/orm/mapper.py, line 168, in __init__
  self.with_polymorphic[1] = self.with_polymorphic[1].alias()
  TypeError: 'tuple' object does not support item assignment

 try mapping to something that is already an alias() (this would
 lend insight into your other problem)
ah, okay, i'm aliasing my stuff, but removed the alias to check 
something else and stepped on this one. passing in a list works too.

  also, related question: once there is A-B-C, concrete, how u'd
  get some A by id? query(A).filter_by(id=1) returns 3 objects, one
  of A,B,C. i guess some filter( mapper.polymorphic_on ==
  'Aidentity') should be there, but how to guess if A is inherited
  concrete hence needs that?
  or is that automaticaly done by query.get() and i missed it?

 if B and C inherit from A, then three objects is the right answer
 in that case.   put this in the bucket of reasons why concrete
 table inheritance in conjunction with polymorphic loading by
 default should be avoided.

 I was about to advise using query.with_polymorphic() only, no
 mapper polymorphic at all, for this case but I realized this is
 currently incompatible with the need for a polymorphic
 discriminator column.  so maybe we can add that as a third argument
 to with_polymorphic().

okay, then i get this as answer to my other question - so concrete 
polymorhism relations/get()/identity on top of it are blue_sky. 
that's okay - just put a line about it in the docs. 
dbcook is throwing warnings about it since long time.

svil

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] I can replace an object with another in python, by changing the object dict to the other object dict. How does it settle with sqlalchemy? Does it works when another mapped object poin

2008-12-03 Thread [EMAIL PROTECTED]

I wrote it on usage reciepts, but no one answered yet.

The reason I'm doing so, is to solve the following problem: I have an
object that is compounded from the fields - obj_id, num1, num2, num3.
obj_id is my primary key. I want to create a save method for the
object's class, that will do the following:
If the object is in the session, save it.
Else, if there is another object in the db with the same num1 and
num2, use the object in the db instead of the current one, and warn
the user if num3 is different.
So it's quite like merge, but not necessarily on the primary key. Now,
I want that use the object in the db wouldn't be by returning the
object after the merge (original object if didn't exist, and db_object
if existed), but really replacing it (self.dict =
existing_object.dict), so one can use that object afterwards, without
being confused.


I know that I can make a constraint in the DB that num1 and num2 would
be unique so that object won't be created (the user will get an
exception), but it won't really be a fix for my problem, because it's
important for my users not to get that kind of exceptions (Especially
because I have another mapped clazz, that is the contatiner of many
obj, so way they will save that class they don't won't to deal with
the case that one of the obj already existed).

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: replace an object.dict with another

2008-12-03 Thread az

so u'd get two objects sharing same dict, and changin one will break 
the other, in a hideous way.
better copy stuff one by one, or invent some other way.

On Wednesday 03 December 2008 22:47:34 [EMAIL PROTECTED] wrote:
 I wrote it on usage reciepts, but no one answered yet.

 The reason I'm doing so, is to solve the following problem: I have
 an object that is compounded from the fields - obj_id, num1, num2,
 num3. obj_id is my primary key. I want to create a save method for
 the object's class, that will do the following:
 If the object is in the session, save it.
 Else, if there is another object in the db with the same num1 and
 num2, use the object in the db instead of the current one, and warn
 the user if num3 is different.
 So it's quite like merge, but not necessarily on the primary key.
 Now, I want that use the object in the db wouldn't be by
 returning the object after the merge (original object if didn't
 exist, and db_object if existed), but really replacing it
 (self.dict =
 existing_object.dict), so one can use that object afterwards,
 without being confused.


 I know that I can make a constraint in the DB that num1 and num2
 would be unique so that object won't be created (the user will get
 an exception), but it won't really be a fix for my problem, because
 it's important for my users not to get that kind of exceptions
 (Especially because I have another mapped clazz, that is the
 contatiner of many obj, so way they will save that class they
 don't won't to deal with the case that one of the obj already
 existed).

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: I can replace an object with another in python, by changing the object dict to the other object dict. How does it settle with sqlalchemy? Does it works when another mapped object

2008-12-03 Thread Michael Bayer


SQLAlchemy instruments classes using an event-based system that  
intercepts all setattribute and collection mutation operations, and  
logs these events as things to be reconciled when the Session is  
flushed.   Additionally, the __dict__ of the object itself is  
referenced by the InstanceState object which is SQLAlchemy's per- 
object manager.   Thirdly, the InstanceState object itself is placed  
inside of the __dict__ of every object instance, and this cannot be  
shared among multiple objects.   So for these three reasons and  
probably more, using the old Python trick of replacing __dict__ will  
lead to poor results.

To populate the state of an object with that of another, use a  
setattr() based approach:

for k in dir(object1):
setattr(object2, k, getattr(object1, k))

On Dec 3, 2008, at 3:47 PM, [EMAIL PROTECTED] wrote:

 The reason I'm doing so, is to solve the following problem: I have an
 object that is compounded from the fields - obj_id, num1, num2, num3.
 obj_id is my primary key. I want to create a save method for the
 object's class, that will do the following:
 If the object is in the session, save it.
 Else, if there is another object in the db with the same num1 and
 num2, use the object in the db instead of the current one, and warn
 the user if num3 is different.
 So it's quite like merge, but not necessarily on the primary key. Now,
 I want that use the object in the db wouldn't be by returning the
 object after the merge (original object if didn't exist, and db_object
 if existed), but really replacing it (self.dict =
 existing_object.dict), so one can use that object afterwards, without
 being confused.

the most straightforward way to accomplish this would be a custom  
__new__ method, so that when you say:

x = MyObject(num1=x, num2=y)

the __new__() would do the session work to find the old object and  
return that instead, if present.  There is a usage recipe on the Wiki  
that does something like this, except its 0.4 specific, and uses a  
metaclass in combination with a homegrown cache - I wrote it years ago  
and it can be done much more simply.   Just use __new__().

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Michael Bayer


On Dec 3, 2008, at 3:45 PM, [EMAIL PROTECTED] wrote:


 okay, then i get this as answer to my other question - so concrete
 polymorhism relations/get()/identity on top of it are blue_sky.
 that's okay - just put a line about it in the docs.
 dbcook is throwing warnings about it since long time.


modify your code to use the query.with_polymorphic('*', selectable,  
some_discriminator_column) approach in r5413, and then tell me what  
issues remain.  its not appropriate for with_polymorphic to be set on  
a concrete mapper() in most cases.

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread az

On Wednesday 03 December 2008 23:28:01 Michael Bayer wrote:
 On Dec 3, 2008, at 3:45 PM, [EMAIL PROTECTED] wrote:
  okay, then i get this as answer to my other question - so
  concrete polymorhism relations/get()/identity on top of it are
  blue_sky. that's okay - just put a line about it in the docs.
  dbcook is throwing warnings about it since long time.

 modify your code to use the query.with_polymorphic('*', selectable,
 some_discriminator_column) approach in r5413, and then tell me what
 issues remain. 

u mean a plain mapper without polymorphism, then above 
query().with_poly? that seem to work. 
but it still needs .filter(
  discriminator==identity) for a get()-like op to work.

and in this case each query() will also needs the .with_poly(..) 
stuff, so whole automatics (specifying things once) gets lost.

ah, forget it. i dont need concrete without working relations, just 
played with the tests.
if u decide one day to finish this concrete stuff and need coverage of 
fullblown combinations of A-B-C + all-possible-references, yell.
it's in dbcook/tests/test_ABC_inh_ref_all.py

the loss of synchron between the polymorphic_on and the  
with_polymorphic[1] if alias'ed, may be a problem one day for 
someone, but it's up to you.

ciao
svil

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic concrete inheritance question

2008-12-03 Thread Michael Bayer


On Dec 3, 2008, at 5:15 PM, [EMAIL PROTECTED] wrote:


 On Wednesday 03 December 2008 23:28:01 Michael Bayer wrote:
 On Dec 3, 2008, at 3:45 PM, [EMAIL PROTECTED] wrote:
 okay, then i get this as answer to my other question - so
 concrete polymorhism relations/get()/identity on top of it are
 blue_sky. that's okay - just put a line about it in the docs.
 dbcook is throwing warnings about it since long time.

 modify your code to use the query.with_polymorphic('*', selectable,
 some_discriminator_column) approach in r5413, and then tell me what
 issues remain.

 u mean a plain mapper without polymorphism, then above
 query().with_poly? that seem to work.
 but it still needs .filter(
  discriminator==identity) for a get()-like op to work.

no, you say session.query(cls).get(x) - you're looking for class  
cls.  get() is not going to figure that out for you.  I think  
concrete inheritance is more useful when its less magical.

 and in this case each query() will also needs the .with_poly(..)
 stuff, so whole automatics (specifying things once) gets lost.

if you want polymorphic loading.  Which you usually shouldn't, if you  
are using concrete inheritance.  it is not optimized for that.

 ah, forget it. i dont need concrete without working relations, just
 played with the tests.

there we go !

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: I can replace an object with another in python, by changing the object dict to the other object dict. How does it settle with sqlalchemy? Does it works when another mapped object

2008-12-03 Thread kobi...@gmail.com

A. Thanks for this great idea. From your suggestion, I realize that if
I am going to use the new method, than I must enforce my __new__ (and
__init__)
to get all the unique fields as arguments. Then, if the object already
exists in the db to return it, and otherwise save the new object.

An important part of it is save the new object, because if I won't
save the object, and one would do something like:

obj1 = MyObject(num1 = x, num2 = y)
obj1.save()
obj2 = MyObject(num1 = x, num2 = x)
obj2.num2 = y
obj2.save()

Then obj2 would not really be merged with obj1, and I will get a
constraint exception - the thing my customers afraid of the most.

So far, so good.

But my customers are really weird, and two weeks ago they asked me to
totally change the design of my project, so they will be able to use
my mapped objects, without saving them to the db. Meaning, they wants
to be able to do the following thing:
1. Create many MyObject instances.
2. Do some operations on them. (The features that my program supply)
3. Save some of them to the db, if they are interesting, but most of
them, just throw away, without even saving them in the first place.
The reason they asked it, is because in some of the cases, they will
want to only use the classes in the API that I provide, for stuff that
aren't important enough to be saved in the db, and without suffering
from the overhead of saving objects to the db.

So the case that I mentioned above with changing the attribute num2
can happen.

Another option, is not to allow them to change num2, unless the object
is saved already in the db. (using property) It would be weird.

B. So I can settle with a merge() method that returns an object. I
think it's the only solution (beside forcing them to work with saving
to the db). Actually, it's not too bad. But it's also not easy, I tell
you, to write such a function. Because what happens if one of the
things that defines me, a part of my uniqueness, is not really a
unique field, but a list of objects that are connected to me in a many-
to-many relationship from another table. And what if I need to call
merge() on each one of them. And what if two of them are evaluated to
be the same object, so I need to fix the list. oof!


On 3 דצמבר, 23:25, Michael Bayer [EMAIL PROTECTED] wrote:
 SQLAlchemy instruments classes using an event-based system that  
 intercepts all setattribute and collection mutation operations, and  
 logs these events as things to be reconciled when the Session is  
 flushed.   Additionally, the __dict__ of the object itself is  
 referenced by the InstanceState object which is SQLAlchemy's per-
 object manager.   Thirdly, the InstanceState object itself is placed  
 inside of the __dict__ of every object instance, and this cannot be  
 shared among multiple objects.   So for these three reasons and  
 probably more, using the old Python trick of replacing __dict__ will  
 lead to poor results.

 To populate the state of an object with that of another, use a  
 setattr() based approach:

 for k in dir(object1):
         setattr(object2, k, getattr(object1, k))

 On Dec 3, 2008, at 3:47 PM, [EMAIL PROTECTED] wrote:

  The reason I'm doing so, is to solve the following problem: I have an
  object that is compounded from the fields - obj_id, num1, num2, num3.
  obj_id is my primary key. I want to create a save method for the
  object's class, that will do the following:
  If the object is in the session, save it.
  Else, if there is another object in the db with the same num1 and
  num2, use the object in the db instead of the current one, and warn
  the user if num3 is different.
  So it's quite like merge, but not necessarily on the primary key. Now,
  I want that use the object in the db wouldn't be by returning the
  object after the merge (original object if didn't exist, and db_object
  if existed), but really replacing it (self.dict =
  existing_object.dict), so one can use that object afterwards, without
  being confused.

 the most straightforward way to accomplish this would be a custom  
 __new__ method, so that when you say:

         x = MyObject(num1=x, num2=y)

 the __new__() would do the session work to find the old object and  
 return that instead, if present.  There is a usage recipe on the Wiki  
 that does something like this, except its 0.4 specific, and uses a  
 metaclass in combination with a homegrown cache - I wrote it years ago  
 and it can be done much more simply.   Just use __new__().
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: I can replace an object with another in python, by changing the object dict to the other object dict. How does it settle with sqlalchemy? Does it works when another mapped object

2008-12-03 Thread Michael Bayer


On Dec 3, 2008, at 6:39 PM, [EMAIL PROTECTED] wrote:


 B. So I can settle with a merge() method that returns an object. I
 think it's the only solution (beside forcing them to work with saving
 to the db). Actually, it's not too bad. But it's also not easy, I tell
 you, to write such a function. Because what happens if one of the
 things that defines me, a part of my uniqueness, is not really a
 unique field, but a list of objects that are connected to me in a  
 many-
 to-many relationship from another table. And what if I need to call
 merge() on each one of them. And what if two of them are evaluated to
 be the same object, so I need to fix the list. oof!



merge() doesn't do much that you couldn't do manually on your own.
if you need to write a jacked up merge()-like function that compares  
collections and things, i dont think Python will let you down in that  
regard.



--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---