Re: [sqlalchemy] dynamic_loader

2010-01-25 Thread werner

On 24/01/2010 16:57, werner wrote:
...

Next thing is to make _get_translation reusable for different tables.

I got it down to this:

def _do_translation(bInstance, tTable, fCrit, cLang, dLang):
try:
x = 
sao.object_session(bInstance).query(tTable).with_parent(bInstance).filter(fCrit==cLang)

return x.one()
except sao.exc.NoResultFound:
try:
x =  
sao.object_session(bInstance).query(tTable).with_parent(bInstance).filter(fCrit==dLang)

return x.one()
except sao.exc.NoResultFound:
return 'no translation found'

class Country_B(Base):
__table__ = sa.Table(u'countries_b', metadata,
sa.Column(u'id', sa.Integer(), sa.Sequence('countries_b_id'), 
primary_key=True, nullable=False),

..
)

def _get_translation(self):
return _do_translation(self, Country_T, Country_T.lang_code5, 
getCurrentUserLang, getDefaultUserLang)


country_t = sao.relation('Country_T', backref='country_b')

country = property(_get_translation)

But would like to remove the def _get_translation and call directly 
_do_translation, something like this:


country = property(_do_translation('Country_B', 'Country_T', 
'lang_code5', getCurrentUserLang, getDefaultUserLang))


But can't figure out how I would then get at the instance of Country_B 
within _do_translation.


As always tips or pointers to documentation are very appreciated.

Werner

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



RE: [sqlalchemy] dynamic_loader

2010-01-25 Thread King Simon-NFHD78
 -Original Message-
 From: sqlalchemy@googlegroups.com 
 [mailto:sqlalch...@googlegroups.com] On Behalf Of werner
 Sent: 25 January 2010 13:37
 To: sqlalchemy@googlegroups.com
 Subject: Re: [sqlalchemy] dynamic_loader
 
 On 24/01/2010 16:57, werner wrote:
 ...
  Next thing is to make _get_translation reusable for 
 different tables.
 I got it down to this:
 
 def _do_translation(bInstance, tTable, fCrit, cLang, dLang):
  try:
  x = 
 sao.object_session(bInstance).query(tTable).with_parent(bInsta
 nce).filter(fCrit==cLang)
  return x.one()
  except sao.exc.NoResultFound:
  try:
  x =  
 sao.object_session(bInstance).query(tTable).with_parent(bInsta
 nce).filter(fCrit==dLang)
  return x.one()
  except sao.exc.NoResultFound:
  return 'no translation found'
 
 class Country_B(Base):
  __table__ = sa.Table(u'countries_b', metadata,
  sa.Column(u'id', sa.Integer(), sa.Sequence('countries_b_id'), 
 primary_key=True, nullable=False),
 ..
  )
 
  def _get_translation(self):
  return _do_translation(self, Country_T, 
 Country_T.lang_code5, 
 getCurrentUserLang, getDefaultUserLang)
 
  country_t = sao.relation('Country_T', backref='country_b')
 
  country = property(_get_translation)
 
 But would like to remove the def _get_translation and call directly 
 _do_translation, something like this:
 
  country = property(_do_translation('Country_B', 'Country_T', 
 'lang_code5', getCurrentUserLang, getDefaultUserLang))
 
 But can't figure out how I would then get at the instance of 
 Country_B 
 within _do_translation.
 
 As always tips or pointers to documentation are very appreciated.
 
 Werner
 

Hi Werner,

You need to implement your own 'property'-like class that implements the
descriptor protocol. This page might give you some clues:

http://users.rcn.com/python/download/Descriptor.htm#descriptor-example


If you had a TranslationProperty class that looked like this:


class TranslationProperty(object):
def __get__(self, obj, objtype):
# Call _do_translation(obj, ...) here


Then your Country class can look like:

class Country_B(Base):
country_t = TranslationProperty()


When you access the country_t attribute, the __get__ method will be
called with your Country_B instance as the obj parameter, and the
Country_B class as the objtype parameter, which you can hopefully pass
on to the _do_translation function.

I hope that helps,

Simon

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Problem using concrete inheritance with migrate

2010-01-25 Thread Todd Blanchard
I have this definition in my upgrade script using migrate

meta = MetaData(migrate_engine)
DeclarativeBase = declarative_base(metadata=meta)
maker = sessionmaker(autoflush=True, autocommit=False,
 extension=ZopeTransactionExtension())
DBSession = scoped_session(maker)
DBSession.configure(bind=migrate_engine)

class MarkerGraphic(DeclarativeBase):
__tablename__ = 'marker_graphics'
id = Column(Integer, primary_key=True)
base_url = Column(Unicode,default=http://chart.apis.google.com/
chart)

class EventType(MarkerGraphic):
__tablename__ = 'event_types'
__mapper_args__ = {'concrete':True}

id = Column(Integer, primary_key=True)
name = Column(Unicode(60), nullable=False, unique=True)

def __unicode__(self):
return self.name

and when doing an upgrade, only the EventType columns are created in
the db (postgresql).

Is concrete not compatible with declarative?

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] dynamic_loader

2010-01-25 Thread werner

Simon,

On 25/01/2010 15:18, King Simon-NFHD78 wrote:
...

I hope that helps,

Yes, that did help a lot.

This is my custom property class.

class TranslationProperty(object):
Returns a query enabled property

def __init__(self, tTable=None, fCol=None, cLang=None, dLang=None):
self.tTable = tTable
self.fCol = fCol
self.cLang = cLang
self.dLang = dLang

def __get__(self, obj, objtype):
# get the class containing the translations
tTable = globals()[self.tTable]
# get the column containing the translation code, e.g. EN_en
fCrit = getattr(tTable, self.fCol)
try:
return 
sao.object_session(obj).query(tTable).with_parent(obj).filter(fCrit==self.cLang).one()

except sao.exc.NoResultFound:
try:
return  
sao.object_session(obj).query(tTable).with_parent(obj).filter(fCrit==self.dLang).one()

except sao.exc.NoResultFound:
return 'no translation found'

Then this is my country table with columns which don't need translation:
class Country_B(Base):
__table__ = sa.Table(u'countries_b', metadata,
sa.Column(u'id', sa.Integer(), sa.Sequence('countries_b_id'), 
primary_key=True, nullable=False),

sa.Column(u'iso2', sa.String(length=2, convert_unicode=False)),
sa.Column(u'iso3', sa.String(length=3, convert_unicode=False)),
...
)

country_t = sao.relation('Country_T', backref='country_b')

country = TranslationProperty('Country_T', 'lang_code5', 
getCurrentUserLang, getDefaultUserLang)


The table with translation columns:
class Country_T(Base):
__table__ = sa.Table(u'countries_t', metadata,
sa.Column(u'id', sa.Integer(), sa.Sequence('countries_t_id'), 
primary_key=True, nullable=False),
sa.Column(u'lang_code5', sa.String(length=5, 
convert_unicode=False), sa.ForeignKey(u'languages.code5')),

sa.Column(u'name', sa.String(length=50, convert_unicode=False)),

sa.Column(u'countries_b_id', sa.Integer(), 
sa.ForeignKey(u'countries_b.id')),

)

Then using it like this:
db.setCurrentUserLang('FR_fr')

ct = session.query(db.Country_B)

for x in ct:
print x
print x.country
print x.country.name

db.setCurrentUserLang('DE_de')

for x in ct:
print x
print x.country
print x.country.name

Resulting in this:
Country_B(id=2, iso2=u'FR', iso3=u'FRA')
Country_T(countries_b_id=2, id=3, lang_code5=u'EN_en', name=u'France')
France
Country_B(id=2, iso2=u'FR', iso3=u'FRA')
Country_T(countries_b_id=2, id=4, lang_code5=u'DE_de', name=u'Frankreich')
Frankreich

The test db does not contain an FR_fr translation, and the default 
language is set to EN_en.


Now I just need to clean up the code, document it a bit and add better 
error handling.


Simon and Michael, thanks again for helping me with all this.

Hope above might be useful for others.

Werner

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Problem using concrete inheritance with migrate

2010-01-25 Thread Michael Bayer
Todd Blanchard wrote:
 I have this definition in my upgrade script using migrate

 meta = MetaData(migrate_engine)
 DeclarativeBase = declarative_base(metadata=meta)
 maker = sessionmaker(autoflush=True, autocommit=False,
  extension=ZopeTransactionExtension())
 DBSession = scoped_session(maker)
 DBSession.configure(bind=migrate_engine)

 class MarkerGraphic(DeclarativeBase):
 __tablename__ = 'marker_graphics'
 id = Column(Integer, primary_key=True)
 base_url = Column(Unicode,default=http://chart.apis.google.com/
 chart)

 class EventType(MarkerGraphic):
 __tablename__ = 'event_types'
 __mapper_args__ = {'concrete':True}

 id = Column(Integer, primary_key=True)
 name = Column(Unicode(60), nullable=False, unique=True)

 def __unicode__(self):
 return self.name

 and when doing an upgrade, only the EventType columns are created in
 the db (postgresql).

 Is concrete not compatible with declarative?

Concrete is entirely compatible with declarative.   I don't see where
you're issuing metadata.create_all() above, yet you say its creating one
of the tables, so the above is not a full script.





 --
 You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Error handling in SQLAlchemy

2010-01-25 Thread Boda Cydo
Hello all!

I have a question about handling errors in SQLAlchemy.

Before I used SQLAlchemy I used to rigorously check for all errors
when executing queries, like:

 status = db.query(INSERT INTO users ...)
 if !status:
   handle_insert_error()

But now when I have switched to SQLAlchemy I write code with no error
checking whatsoever, like:

 user = User(Boda Cydo)
 session.add(user)
 session.commit()

And I do absolutely no error checking. I absolutely feel horrible for
writing such code.

I talked in #sqlalchemy and someone told me that SQLAlchemy throws
exceptions on errors. That's better. But where is it documented? The
person couldn't find anything. Neither could I.

Can anyone please help with tips (or point me to documentation) about
what exceptions get raised when?

I absolutely don't want to write code without error handling.


Thanks,
Boda Cydo

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Problem using concrete inheritance with migrate

2010-01-25 Thread Todd Blanchard
Ugh.  Then I just don't get the point - the only reason to use inheritance is 
to avoid defining all the fields twice (and I have a bunch of methods - but 
still).

I might as well stick with the class decorators approach (which is working 
really well for me).

On Jan 25, 2010, at 1:10 PM, Michael Bayer wrote:

 Todd Blanchard wrote:
 I upgraded from 0.5.6 to 0.5.8 but it is still the same.
 
 The fields from MakerGraphic do not appear in the event_types table.:-/
 
 This is a common misunderstanding when using concrete.   You need to
 define each column specifically for each concrete table since each class
 represents an entirely different table.  See the example at
 http://www.sqlalchemy.org/docs/reference/ext/declarative.html#concrete-table-inheritance
 .
 
 
 On Jan 25, 2010, at 9:43 AM, Michael Bayer wrote:
 
 Todd Blanchard wrote:
 I have
 
 MarkerGraphic.__table__.create()
 EventType.__table__.create()
 
 In the upgrade portion of my script
 
 SQL for CREATE TABLE will be emitted unconditionally at the point at
 which
 create() is called - which implies that part of the script isn't being
 called for whatever reason, or perhaps you have some engine/URL
 confusion
 going on.
 
 I'd also ditch all the session stuff that isn't necessary for migrate.
 
 Also make sure you're on 0.5.8 or 0.6 trunk to eliminate the possibility
 of any bugs in very old versions of 0.5  (and don't even consider 0.4).
 
 
 
 
 Sent from my iPhone
 
 On Jan 25, 2010, at 8:14, Michael Bayer mike...@zzzcomputing.com
 wrote:
 
 Todd Blanchard wrote:
 I have this definition in my upgrade script using migrate
 
 meta = MetaData(migrate_engine)
 DeclarativeBase = declarative_base(metadata=meta)
 maker = sessionmaker(autoflush=True, autocommit=False,
   extension=ZopeTransactionExtension())
 DBSession = scoped_session(maker)
 DBSession.configure(bind=migrate_engine)
 
 class MarkerGraphic(DeclarativeBase):
  __tablename__ = 'marker_graphics'
  id = Column(Integer, primary_key=True)
  base_url = Column(Unicode,default=http://chart.apis.google.com/
 chart)
 
 class EventType(MarkerGraphic):
  __tablename__ = 'event_types'
  __mapper_args__ = {'concrete':True}
 
  id = Column(Integer, primary_key=True)
  name = Column(Unicode(60), nullable=False, unique=True)
 
  def __unicode__(self):
  return self.name
 
 and when doing an upgrade, only the EventType columns are created in
 the db (postgresql).
 
 Is concrete not compatible with declarative?
 
 Concrete is entirely compatible with declarative.   I don't see where
 you're issuing metadata.create_all() above, yet you say its creating
 one
 of the tables, so the above is not a full script.
 
 
 
 
 
 --
 You received this message because you are subscribed to the Google
 Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 
 --
 You received this message because you are subscribed to the Google
 Groups sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en
 .
 
 
 --
 You received this message because you are subscribed to the Google
 Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 
 --
 You received this message because you are subscribed to the Google
 Groups sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 --
 You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/sqlalchemy?hl=en.
 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 

Re: [sqlalchemy] Problem using concrete inheritance with migrate

2010-01-25 Thread Michael Bayer

On Jan 25, 2010, at 9:13 PM, Todd Blanchard wrote:

 Ugh.  Then I just don't get the point - the only reason to use inheritance is 
 to avoid defining all the fields twice (and I have a bunch of methods - but 
 still).
 
 I might as well stick with the class decorators approach (which is working 
 really well for me).


the point is, if you intend to represent a class hierarchy among distinct 
tables.But no, its not meant as a typing saver.  The approach at 
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DeclarativeMixins is 
recommended for that since many people have requested it.


 

 
 On Jan 25, 2010, at 1:10 PM, Michael Bayer wrote:
 
 Todd Blanchard wrote:
 I upgraded from 0.5.6 to 0.5.8 but it is still the same.
 
 The fields from MakerGraphic do not appear in the event_types table.:-/
 
 This is a common misunderstanding when using concrete.   You need to
 define each column specifically for each concrete table since each class
 represents an entirely different table.  See the example at
 http://www.sqlalchemy.org/docs/reference/ext/declarative.html#concrete-table-inheritance
 .
 
 
 On Jan 25, 2010, at 9:43 AM, Michael Bayer wrote:
 
 Todd Blanchard wrote:
 I have
 
 MarkerGraphic.__table__.create()
 EventType.__table__.create()
 
 In the upgrade portion of my script
 
 SQL for CREATE TABLE will be emitted unconditionally at the point at
 which
 create() is called - which implies that part of the script isn't being
 called for whatever reason, or perhaps you have some engine/URL
 confusion
 going on.
 
 I'd also ditch all the session stuff that isn't necessary for migrate.
 
 Also make sure you're on 0.5.8 or 0.6 trunk to eliminate the possibility
 of any bugs in very old versions of 0.5  (and don't even consider 0.4).
 
 
 
 
 Sent from my iPhone
 
 On Jan 25, 2010, at 8:14, Michael Bayer mike...@zzzcomputing.com
 wrote:
 
 Todd Blanchard wrote:
 I have this definition in my upgrade script using migrate
 
 meta = MetaData(migrate_engine)
 DeclarativeBase = declarative_base(metadata=meta)
 maker = sessionmaker(autoflush=True, autocommit=False,
  extension=ZopeTransactionExtension())
 DBSession = scoped_session(maker)
 DBSession.configure(bind=migrate_engine)
 
 class MarkerGraphic(DeclarativeBase):
 __tablename__ = 'marker_graphics'
 id = Column(Integer, primary_key=True)
 base_url = Column(Unicode,default=http://chart.apis.google.com/
 chart)
 
 class EventType(MarkerGraphic):
 __tablename__ = 'event_types'
 __mapper_args__ = {'concrete':True}
 
 id = Column(Integer, primary_key=True)
 name = Column(Unicode(60), nullable=False, unique=True)
 
 def __unicode__(self):
 return self.name
 
 and when doing an upgrade, only the EventType columns are created in
 the db (postgresql).
 
 Is concrete not compatible with declarative?
 
 Concrete is entirely compatible with declarative.   I don't see where
 you're issuing metadata.create_all() above, yet you say its creating
 one
 of the tables, so the above is not a full script.
 
 
 
 
 
 --
 You received this message because you are subscribed to the Google
 Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 
 --
 You received this message because you are subscribed to the Google
 Groups sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en
 .
 
 
 --
 You received this message because you are subscribed to the Google
 Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 
 --
 You received this message because you are subscribed to the Google
 Groups sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 --
 You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to 
 

[sqlalchemy] Re: in_() with composite primary key

2010-01-25 Thread jpeck


On Jan 25, 3:08 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 jpeck wrote:
  Depending on your database, you may have a function-style row
  constructor that does what you want. For example, PostgreSQL treats (a,
  b) and ROW(a, b) as equivalent. If this works for you, then I think you
  can then use SQLAlchemy's func object:

  select([...]).where(func.row(a, b).in_([func.row(a1, b1), func.row(a2,
  b2)]))

  I have used func.row to build row objects, but I haven't used it with
  the in_ operator, so YMMV.

  Conor - that was exactly what I was looking for! Much nicer than
  generating via text().

  Sorry for top posting before! (I lose the internets today).

 I just added `tuple_()` into trunk since its about time we had this.

 http://www.sqlalchemy.org/docs/06/reference/sqlalchemy/expressions.ht...

Michael - you are the man! I'm going to try this out first thing in
the morning. I've been following this list for the past couple of
years, and you always seem to come through for people. This may sound
funny, but what makes or breaks a software component for me is the
quality of people working on the project. People like Tom Lane are why
I choose Postgresql, and you are the reason I choose SQLAlchemy.
Thanks for all of your hard work!

Jeff Peck

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.