[sqlalchemy] Re: session.execute(sql_statement) does not flush the session in a autoflush=True session ?

2010-11-29 Thread Emmanuel Cazenave
Yes it surprised me. But I get your point.

Thanks you for your response.

On Nov 26, 9:41 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 I wouldn't say its a bug since its intentional.   But I'll grant the 
 intention is up for debate.   I've always considered usage of execute() to 
 mean, you're going below the level of the ORM and would like to control the 
 SQL interaction directly, not to mention with as minimal overhead as 
 possible, which is why it works that way currently.   It might be just as 
 surprising to many users if execute() issued a whole series of insert/update 
 statements as much as it was apparently surprising to you that it did not.

 On Nov 26, 2010, at 1:49 PM, Emmanuel Cazenave wrote:







  Hi,

  In a session which has some dirty objects, doing
  session.execute(sql_statement) doesn't not flush the dirty objects to
  the database before executing the sql_statement query.

  The session was initialized with  autoflush=True.

  Is it the expected behaviour ? Is it a bug ?

  Thanks

  --
  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 
  athttp://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] version_id_col behavior in case of table inheritance

2010-11-29 Thread Naresh
Hi,

We have a parent class/table (Notification/notifications) and a child
class/table(BusinessNotification/business_notifications).
Both of them have a version_id_col defined.
We are facing ConcurrentModificationException errors for the  model at
the end of the mail.
The problem is because the update state generated uses 'None' a the
value for notifications.version column.

We tried removing the version_id_col mapper arg in the child class -
BusinessNotification and then the error went away and the update
statement used the correct version column value to update.

So, firstly we are wondering how do we fix the situation that we can
have a version_id_col in the child class/table as well?

Upon further investigations,  we noticed that in the other parts of
the application we used the following approach.

parent_table = Table( ... )
class Parent(DeclarativeBase):
__table__ = parent_table
__mapper_args__ = {'polymorphic_on': parent_table.c.type,
'version_id_col': parent_table.c.version}

child1_table = Table( ... )
class Child1(DeclarativeBase)
__table__ = child1_table
__mapper_args__ = {'polymorphic_identity':'c1',
'version_id_col':child1_table.c.version_num}

With the above style of coding our models, we don't get
ConcurrentModificationException, but any update statement to the
parent_table does not use version column.


Please throw some light on these behaviors.

Regards,
Naresh

P.S. The model and sample client code follows.
--

class Notification(DeclarativeBase):
This entity represents the notifications saved for sending
later 
__tablename__ = 'notifications'
__table_args__ =  {mysql_engine:InnoDB,
   mysql_row_format:DYNAMIC,
   mysql_charset:utf8}

id = Column(bigint, primary_key=True, autoincrement=False)
entid = Column(bigint, ForeignKey('enterprises.entid',
name='fk_notifn_entid'), nullable=False)
notification_type = Column(types.String(30), nullable=False)
source = Column(types.String(30), nullable=False)
data  = Column(text_type, nullable=False)
status = Column(types.String(12), nullable=False, default='new')
created_on = Column(types.DATETIME, nullable=False,
default=func.current_timestamp())
last_updated = Column(types.DATETIME, nullable=True,
onupdate=func.current_timestamp())
version = Column(types.SMALLINT, nullable=False, default=0)
__mapper_args__ = {'polymorphic_on': notification_type,
'polymorphic_identity':'incident', 'version_id_col': version}


class BusinessNotification(Notification):
This entity represents the business notifications 
__tablename__ = 'business_notifications'
__table_args__ =  {mysql_engine:InnoDB,
   mysql_row_format:DYNAMIC,
   mysql_charset:utf8}

notification_id = Column(bigint, ForeignKey('notifications.id',
name='fk_bn_notificationid'), primary_key=True, autoincrement=False)
event_id = Column(bigint, ForeignKey('doc_events.id',
name='fk_bn_eventid'), nullable=True)
created_on = Column(types.DATETIME, nullable=False,
default=func.current_timestamp())
last_updated = Column(types.DATETIME, nullable=True,
onupdate=func.current_timestamp())
version_num = Column(types.SMALLINT, nullable=False, default=0)
__mapper_args__ = {'polymorphic_identity':'event',
'version_id_col': version_num}
#__mapper_args__ = {'polymorphic_identity':'event'}


if __name__ == '__main__':
try :
qry = meta.Session().query(BusinessNotification).filter(and_(
 
BusinessNotification.status=='new',
 
BusinessNotification.created_on  now()))
qry = qry.order_by(BusinessNotification.created_on)
all_notifications = qry.all()
for notification in all_notifications :
# some business logic to trigger status update
notification.status='in_progress'
meta.Session().commit()
except Exception as ex :
log.error(Error Identifying Notification Recipients)
log.exception(ex)
meta.Session().rollback()
finally :
meta.Session.remove()

-- 
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] Re: version_id_col behavior in case of table inheritance

2010-11-29 Thread Naresh Khalasi
Hi,

After some more internal discussions we tried and realized that the version
col is not really required at the child table level.
The second commit in the sample code fails because the version value on the
parent row has already moved ahead.

Please confirm if the understanding/conclusion is correct.

Regards,
Naresh

On Mon, Nov 29, 2010 at 2:21 PM, Naresh nkhal...@vayana.in wrote:

 Hi,

 We have a parent class/table (Notification/notifications) and a child
 class/table(BusinessNotification/business_notifications).
 Both of them have a version_id_col defined.
 We are facing ConcurrentModificationException errors for the  model at
 the end of the mail.
 The problem is because the update state generated uses 'None' a the
 value for notifications.version column.

 We tried removing the version_id_col mapper arg in the child class -
 BusinessNotification and then the error went away and the update
 statement used the correct version column value to update.

 So, firstly we are wondering how do we fix the situation that we can
 have a version_id_col in the child class/table as well?

 Upon further investigations,  we noticed that in the other parts of
 the application we used the following approach.

 parent_table = Table( ... )
 class Parent(DeclarativeBase):
__table__ = parent_table
__mapper_args__ = {'polymorphic_on': parent_table.c.type,
 'version_id_col': parent_table.c.version}

 child1_table = Table( ... )
 class Child1(DeclarativeBase)
__table__ = child1_table
__mapper_args__ = {'polymorphic_identity':'c1',
 'version_id_col':child1_table.c.version_num}

 With the above style of coding our models, we don't get
 ConcurrentModificationException, but any update statement to the
 parent_table does not use version column.


 Please throw some light on these behaviors.

 Regards,
 Naresh

 P.S. The model and sample client code follows.
 --

 class Notification(DeclarativeBase):
This entity represents the notifications saved for sending
 later 
__tablename__ = 'notifications'
__table_args__ =  {mysql_engine:InnoDB,
   mysql_row_format:DYNAMIC,
   mysql_charset:utf8}

id = Column(bigint, primary_key=True, autoincrement=False)
entid = Column(bigint, ForeignKey('enterprises.entid',
 name='fk_notifn_entid'), nullable=False)
notification_type = Column(types.String(30), nullable=False)
source = Column(types.String(30), nullable=False)
data  = Column(text_type, nullable=False)
status = Column(types.String(12), nullable=False, default='new')
created_on = Column(types.DATETIME, nullable=False,
 default=func.current_timestamp())
last_updated = Column(types.DATETIME, nullable=True,
 onupdate=func.current_timestamp())
version = Column(types.SMALLINT, nullable=False, default=0)
__mapper_args__ = {'polymorphic_on': notification_type,
 'polymorphic_identity':'incident', 'version_id_col': version}


 class BusinessNotification(Notification):
This entity represents the business notifications 
__tablename__ = 'business_notifications'
__table_args__ =  {mysql_engine:InnoDB,
   mysql_row_format:DYNAMIC,
   mysql_charset:utf8}

notification_id = Column(bigint, ForeignKey('notifications.id',
 name='fk_bn_notificationid'), primary_key=True, autoincrement=False)
event_id = Column(bigint, ForeignKey('doc_events.id',
 name='fk_bn_eventid'), nullable=True)
created_on = Column(types.DATETIME, nullable=False,
 default=func.current_timestamp())
last_updated = Column(types.DATETIME, nullable=True,
 onupdate=func.current_timestamp())
version_num = Column(types.SMALLINT, nullable=False, default=0)
__mapper_args__ = {'polymorphic_identity':'event',
 'version_id_col': version_num}
 #__mapper_args__ = {'polymorphic_identity':'event'}


 if __name__ == '__main__':
try :
qry = meta.Session().query(BusinessNotification).filter(and_(

 BusinessNotification.status=='new',

 BusinessNotification.created_on  now()))
qry = qry.order_by(BusinessNotification.created_on)
all_notifications = qry.all()
for notification in all_notifications :
# some business logic to trigger status update
notification.status='in_progress'
meta.Session().commit()
except Exception as ex :
log.error(Error Identifying Notification Recipients)
log.exception(ex)
meta.Session().rollback()
finally :
meta.Session.remove()




-- 
Naresh Khalasi | Vayana Services (http://www.vayana.in) | +91-9892294598

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

from sqlalchemy import create_engine, 

Re: [sqlalchemy] Re: session.execute(sql_statement) does not flush the session in a autoflush=True session ?

2010-11-29 Thread Michael Bayer
I might turn it on in 0.7 and add an extra flag autoflush_on_execute just so 
people can turn it off if they don't like it.  0.7 is on track for beta 
releases in december or january.

You can make yourself a quick Session subclass that wraps execute(), if you 
wanted this behavior right now.



On Nov 29, 2010, at 3:56 AM, Emmanuel Cazenave wrote:

 Yes it surprised me. But I get your point.
 
 Thanks you for your response.
 
 On Nov 26, 9:41 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 I wouldn't say its a bug since its intentional.   But I'll grant the 
 intention is up for debate.   I've always considered usage of execute() to 
 mean, you're going below the level of the ORM and would like to control the 
 SQL interaction directly, not to mention with as minimal overhead as 
 possible, which is why it works that way currently.   It might be just as 
 surprising to many users if execute() issued a whole series of insert/update 
 statements as much as it was apparently surprising to you that it did not.
 
 On Nov 26, 2010, at 1:49 PM, Emmanuel Cazenave wrote:
 
 
 
 
 
 
 
 Hi,
 
 In a session which has some dirty objects, doing
 session.execute(sql_statement) doesn't not flush the dirty objects to
 the database before executing the sql_statement query.
 
 The session was initialized with  autoflush=True.
 
 Is it the expected behaviour ? Is it a bug ?
 
 Thanks
 
 --
 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 
 athttp://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.



Re: [sqlalchemy] Re: version_id_col behavior in case of table inheritance

2010-11-29 Thread Michael Bayer

On Nov 29, 2010, at 8:28 AM, Naresh Khalasi wrote:

 Hi,
 
 After some more internal discussions we tried and realized that the version 
 col is not really required at the child table level.
 The second commit in the sample code fails because the version value on the 
 parent row has already moved ahead.
 
 Please confirm if the understanding/conclusion is correct.

the version col would be just on the base table, that's correct, since no child 
row should ever exist without a parent row, which establishes the version.  As 
far as what happens when version_id_col is placed on two tables internally, I'd 
have to try that out to see why you got silent failure on that.  We try to add 
warnings or exceptions for the wide variety of configurational mistakes that 
are possible.   Ideally the version_id_col on both parent and child would 
actually work as expected, i.e. both columns get populated equally.

Looking at the sample code, the structure of change/commit created at the end 
appears to be the classic case the version id col was designed to detect - 
concurrent modification.   The most recent 0.6 release renamed the exception 
StaleDataError to prevent confusion with threading/process issues, which 
aren't necessary to produce this condition.





 
 Regards,
 Naresh
 
 On Mon, Nov 29, 2010 at 2:21 PM, Naresh nkhal...@vayana.in wrote:
 Hi,
 
 We have a parent class/table (Notification/notifications) and a child
 class/table(BusinessNotification/business_notifications).
 Both of them have a version_id_col defined.
 We are facing ConcurrentModificationException errors for the  model at
 the end of the mail.
 The problem is because the update state generated uses 'None' a the
 value for notifications.version column.
 
 We tried removing the version_id_col mapper arg in the child class -
 BusinessNotification and then the error went away and the update
 statement used the correct version column value to update.
 
 So, firstly we are wondering how do we fix the situation that we can
 have a version_id_col in the child class/table as well?
 
 Upon further investigations,  we noticed that in the other parts of
 the application we used the following approach.
 
 parent_table = Table( ... )
 class Parent(DeclarativeBase):
__table__ = parent_table
__mapper_args__ = {'polymorphic_on': parent_table.c.type,
 'version_id_col': parent_table.c.version}
 
 child1_table = Table( ... )
 class Child1(DeclarativeBase)
__table__ = child1_table
__mapper_args__ = {'polymorphic_identity':'c1',
 'version_id_col':child1_table.c.version_num}
 
 With the above style of coding our models, we don't get
 ConcurrentModificationException, but any update statement to the
 parent_table does not use version column.
 
 
 Please throw some light on these behaviors.
 
 Regards,
 Naresh
 
 P.S. The model and sample client code follows.
 --
 
 class Notification(DeclarativeBase):
This entity represents the notifications saved for sending
 later 
__tablename__ = 'notifications'
__table_args__ =  {mysql_engine:InnoDB,
   mysql_row_format:DYNAMIC,
   mysql_charset:utf8}
 
id = Column(bigint, primary_key=True, autoincrement=False)
entid = Column(bigint, ForeignKey('enterprises.entid',
 name='fk_notifn_entid'), nullable=False)
notification_type = Column(types.String(30), nullable=False)
source = Column(types.String(30), nullable=False)
data  = Column(text_type, nullable=False)
status = Column(types.String(12), nullable=False, default='new')
created_on = Column(types.DATETIME, nullable=False,
 default=func.current_timestamp())
last_updated = Column(types.DATETIME, nullable=True,
 onupdate=func.current_timestamp())
version = Column(types.SMALLINT, nullable=False, default=0)
__mapper_args__ = {'polymorphic_on': notification_type,
 'polymorphic_identity':'incident', 'version_id_col': version}
 
 
 class BusinessNotification(Notification):
This entity represents the business notifications 
__tablename__ = 'business_notifications'
__table_args__ =  {mysql_engine:InnoDB,
   mysql_row_format:DYNAMIC,
   mysql_charset:utf8}
 
notification_id = Column(bigint, ForeignKey('notifications.id',
 name='fk_bn_notificationid'), primary_key=True, autoincrement=False)
event_id = Column(bigint, ForeignKey('doc_events.id',
 name='fk_bn_eventid'), nullable=True)
created_on = Column(types.DATETIME, nullable=False,
 default=func.current_timestamp())
last_updated = Column(types.DATETIME, nullable=True,
 onupdate=func.current_timestamp())
version_num = Column(types.SMALLINT, nullable=False, default=0)
__mapper_args__ = {'polymorphic_identity':'event',
 'version_id_col': version_num}
 #__mapper_args__ = {'polymorphic_identity':'event'}
 
 
 if __name__ == '__main__':
try :
qry = meta.Session().query(BusinessNotification).filter(and_(
 
 

Re: [sqlalchemy] Char encoding..

2010-11-29 Thread Michael Bayer
we've got unicode round trips down very well for years now with plenty of 
tests, so would need a specific series of steps to reproduce what you're doing 
here.  Note that the recommended connect string for MySQL + Mysqldb looks like 
mysql://scott:ti...@localhost/test?charset=utf8use_unicode=0 .

On Nov 29, 2010, at 2:37 AM, Warwick Prince wrote:

 Hi All
 
 I thought I had Character Encoding licked, but I've hit something I can't 
 work through.  Any help appreciated.
 
 I have a legacy non SQL database that I read legacy data from (using cool 
 Python code that emulates the old ISDB binary comms) and it reads a str which 
 has Foreign language chars in it.  (French for example).  
 
 So, firstly, I have   myStr = ''Aligot\xc3\xa9  which when printed is 
 Aligoté.   So far so good.
 
 I then convert that to unicode by  myUnicode = unicode(myStr, 'utf-8', 
 errors='ignore') and get u'Aligot\xe9'.   This printed is also Aligoté, 
 therefore all is good.
 
 I have a MySQL database, InnoDB table, charset utf-8.
 
 I set up my values in a dict called setValues with all the columns and their 
 respective unicode'd values ready to go
 
 I then do a table.insert(values=setValues).execute() and get this error.
 
 Traceback (most recent call last):
  File C:\Documents and Settings\wprince\Desktop\PY CODE 
 DEVELOPMENT\CESyncSQL\TEST_Sync.py, line 148, in SYNC_IT
SyncFunction(ceDB, session, meta)
  File C:\Documents and Settings\wprince\Desktop\PY CODE 
 DEVELOPMENT\CESyncSQL\TEST_Sync.py, line 840, in SYNC_VarietiesOUT
DAPDB_SetColumns(meta, 'varieties', 
 {'DescriptiveText':self.CEUnicode(tVarieties.ceVarietyText.value), 
 'FlavourText':self.CEUnicode(tVarieties.ceFlavourText.value), 
 'ImageURL':imageURL}, Variety=variety)
  File C:\Python26\lib\DAPDBHelpers.py, line 323, in DAPDB_SetColumns
table.insert(values=setColumns).execute()
  File C:\Python26\lib\site-packages\sqlalchemy\sql\expression.py, line 
 1217, in execute
return e._execute_clauseelement(self, multiparams, params)
  File C:\Python26\lib\site-packages\sqlalchemy\engine\base.py, line 1722, 
 in _execute_clauseelement
return connection._execute_clauseelement(elem, multiparams, params)
 UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 
 4: ordinal not in range(128)
 
 I know what the error means, I just don't know why I'm getting it.  The 
 offending u'\xe9' character is in the DescriptiveText column.  
 DAPDB_SetColumns is a simple wrapper around an update/insert that builds up 
 the table.insert(values=setColumns).execute() you see.
 
 This is what setColumns looks like;
 {'ImageURL': '', 'DescriptiveText': u'Carm\xe9n\xe8re is a red wine grape 
 variety originally from Bordeaux, France. Having lost favor in France, the 
 largest area planted with this variety is in now Chile. It only survived, due 
 to growers believing it was Merlot. The vines were imported into Chil', 
 'FlavourText': u'Carmenere is a full bodied red wine with approachable 
 tannins and a combination of sweet berry fruit, savory pepper, smoke, tar, 
 with a slight leafy character.\n', 'Variety': u'Carmenere'}
 
 'Variety' is the primary key BTW.
 
 What gives?  It feels like SQLA is encoding/decoding somewhere it shouldn't..
 
 Cheers
 Warwick
 
 -- 
 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.



Re: [sqlalchemy] Char encoding..

2010-11-29 Thread Warwick Prince
Hi Michael

Thanks for your thoughts and comments to date.

I can replicate the problem with ease, so perhaps this will help;

# -*- coding: utf-8 -*-
e = 
create_engine('mysql+mysqlconnector://user:passw...@127.0.0.1/testdb?use_unicode=0',
 encoding='utf8', echo=False)
m = MetaData(e)
t = Table('test_table', m, autoload=True)
#test_table is;
Table('test_table', 
MetaData(Engine(mysql+mysqlconnector://user:passw...@127.0.0.1/testdb?use_unicode=0)),
 Column(u'ID', INTEGER(display_width=11), table=test_table, primary_key=True, 
nullable=False), Column(u'SourceType', VARCHAR(length=10), table=test_table), 
Column(u'SourceID', VARCHAR(length=128), table=test_table), Column(u'Date', 
DATE(), table=test_table), Column(u'Time', TIME(timezone=False), 
table=test_table), Column(u'UserID', VARCHAR(length=10), table=test_table), 
Column(u'Note', BLOB(length=None), table=test_table), Column(u'Division', 
VARCHAR(length=3), table=test_table), schema=None)

# Set some row  data in a dict
columns = dict(ID=1, SourceType='TEST', SourceID='WAP', Note=u'Aligot\xe9')  # 
The Note column is set to a unicode value for a French word with accents. 
Column type is BLOB

# insert it
t.insert(values=columns).execute()

get this;
Traceback (most recent call last):
  File interactive input, line 1, in module
  File C:\Python26\lib\site-packages\sqlalchemy\sql\expression.py, line 1217, 
in execute
return e._execute_clauseelement(self, multiparams, params)
  File C:\Python26\lib\site-packages\sqlalchemy\engine\base.py, line 1722, in 
_execute_clauseelement
return connection._execute_clauseelement(elem, multiparams, params)
  File C:\Python26\lib\site-packages\sqlalchemy\engine\base.py, line 1235, in 
_execute_clauseelement
parameters=params
  File C:\Python26\lib\site-packages\sqlalchemy\engine\base.py, line 1343, in 
__create_execution_context
connection=self, **kwargs)
  File C:\Python26\lib\site-packages\sqlalchemy\engine\default.py, line 384, 
in __init__
self.parameters = self.__convert_compiled_params(self.compiled_parameters)
  File C:\Python26\lib\site-packages\sqlalchemy\engine\default.py, line 513, 
in __convert_compiled_params
param[key] = processors[key](compiled_params[key])
  File C:\Python26\lib\site-packages\sqlalchemy\types.py, line 1209, in 
process
return DBAPIBinary(value)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 6: 
ordinal not in range(128)

It appears to be in the processing of the Binary type that something is going 
wrong. 

Further testing showed something interesting.  I changed around the data above 
and set the unicode value to the VARCHAR column SourceID.  That worked..  
Therefore, the issue is related to storing a unicode value into a BLOB.  Surely 
I can store anything in a BLOB, or am I missing something?

Cheers
Warwick

Warwick Prince 
Managing Director 
mobile: +61 411 026 992 
skype: warwickprince  
 
phone: +61 7 3102 3730 
fax:  +61 7 3319 6734 
web: www.mushroomsys.com 

On 30/11/2010, at 1:29 AM, Michael Bayer wrote:

 we've got unicode round trips down very well for years now with plenty of 
 tests, so would need a specific series of steps to reproduce what you're 
 doing here.  Note that the recommended connect string for MySQL + Mysqldb 
 looks like mysql://scott:ti...@localhost/test?charset=utf8use_unicode=0 .
 
 On Nov 29, 2010, at 2:37 AM, Warwick Prince wrote:
 
 Hi All
 
 I thought I had Character Encoding licked, but I've hit something I can't 
 work through.  Any help appreciated.
 
 I have a legacy non SQL database that I read legacy data from (using cool 
 Python code that emulates the old ISDB binary comms) and it reads a str 
 which has Foreign language chars in it.  (French for example).  
 
 So, firstly, I have   myStr = ''Aligot\xc3\xa9  which when printed is 
 Aligoté.   So far so good.
 
 I then convert that to unicode by  myUnicode = unicode(myStr, 'utf-8', 
 errors='ignore') and get u'Aligot\xe9'.   This printed is also Aligoté, 
 therefore all is good.
 
 I have a MySQL database, InnoDB table, charset utf-8.
 
 I set up my values in a dict called setValues with all the columns and their 
 respective unicode'd values ready to go
 
 I then do a table.insert(values=setValues).execute() and get this error.
 
 Traceback (most recent call last):
 File C:\Documents and Settings\wprince\Desktop\PY CODE 
 DEVELOPMENT\CESyncSQL\TEST_Sync.py, line 148, in SYNC_IT
   SyncFunction(ceDB, session, meta)
 File C:\Documents and Settings\wprince\Desktop\PY CODE 
 DEVELOPMENT\CESyncSQL\TEST_Sync.py, line 840, in SYNC_VarietiesOUT
   DAPDB_SetColumns(meta, 'varieties', 
 {'DescriptiveText':self.CEUnicode(tVarieties.ceVarietyText.value), 
 'FlavourText':self.CEUnicode(tVarieties.ceFlavourText.value), 
 'ImageURL':imageURL}, Variety=variety)
 File C:\Python26\lib\DAPDBHelpers.py, line 323, in DAPDB_SetColumns
   table.insert(values=setColumns).execute()
 File C:\Python26\lib\site-packages\sqlalchemy\sql\expression.py, line 

[sqlalchemy] Re: version_id_col behavior in case of table inheritance

2010-11-29 Thread Naresh
Thanks Michael for the confirmation/explanation.


On Nov 29, 8:25 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Nov 29, 2010, at 8:28 AM, Naresh Khalasi wrote:

  Hi,

  After some more internal discussions we tried and realized that the version 
  col is not really required at the child table level.
  The second commit in the sample code fails because the version value on the 
  parent row has already moved ahead.

  Please confirm if the understanding/conclusion is correct.

 the version col would be just on the base table, that's correct, since no 
 child row should ever exist without a parent row, which establishes the 
 version.  As far as what happens when version_id_col is placed on two tables 
 internally, I'd have to try that out to see why you got silent failure on 
 that.  We try to add warnings or exceptions for the wide variety of 
 configurational mistakes that are possible.   Ideally the version_id_col on 
 both parent and child would actually work as expected, i.e. both columns get 
 populated equally.

 Looking at the sample code, the structure of change/commit created at the end 
 appears to be the classic case the version id col was designed to detect - 
 concurrent modification.   The most recent 0.6 release renamed the exception 
 StaleDataError to prevent confusion with threading/process issues, which 
 aren't necessary to produce this condition.









  Regards,
  Naresh

  On Mon, Nov 29, 2010 at 2:21 PM, Naresh nkhal...@vayana.in wrote:
  Hi,

  We have a parent class/table (Notification/notifications) and a child
  class/table(BusinessNotification/business_notifications).
  Both of them have a version_id_col defined.
  We are facing ConcurrentModificationException errors for the  model at
  the end of the mail.
  The problem is because the update state generated uses 'None' a the
  value for notifications.version column.

  We tried removing the version_id_col mapper arg in the child class -
  BusinessNotification and then the error went away and the update
  statement used the correct version column value to update.

  So, firstly we are wondering how do we fix the situation that we can
  have a version_id_col in the child class/table as well?

  Upon further investigations,  we noticed that in the other parts of
  the application we used the following approach.

  parent_table = Table( ... )
  class Parent(DeclarativeBase):
     __table__ = parent_table
     __mapper_args__ = {'polymorphic_on': parent_table.c.type,
  'version_id_col': parent_table.c.version}

  child1_table = Table( ... )
  class Child1(DeclarativeBase)
     __table__ = child1_table
     __mapper_args__ = {'polymorphic_identity':'c1',
  'version_id_col':child1_table.c.version_num}

  With the above style of coding our models, we don't get
  ConcurrentModificationException, but any update statement to the
  parent_table does not use version column.

  Please throw some light on these behaviors.

  Regards,
  Naresh

  P.S. The model and sample client code follows.
  --

  class Notification(DeclarativeBase):
     This entity represents the notifications saved for sending
  later 
     __tablename__ = 'notifications'
     __table_args__ =  {mysql_engine:InnoDB,
                        mysql_row_format:DYNAMIC,
                        mysql_charset:utf8}

     id = Column(bigint, primary_key=True, autoincrement=False)
     entid = Column(bigint, ForeignKey('enterprises.entid',
  name='fk_notifn_entid'), nullable=False)
     notification_type = Column(types.String(30), nullable=False)
     source = Column(types.String(30), nullable=False)
     data  = Column(text_type, nullable=False)
     status = Column(types.String(12), nullable=False, default='new')
     created_on = Column(types.DATETIME, nullable=False,
  default=func.current_timestamp())
     last_updated = Column(types.DATETIME, nullable=True,
  onupdate=func.current_timestamp())
     version = Column(types.SMALLINT, nullable=False, default=0)
     __mapper_args__ = {'polymorphic_on': notification_type,
  'polymorphic_identity':'incident', 'version_id_col': version}

  class BusinessNotification(Notification):
     This entity represents the business notifications 
     __tablename__ = 'business_notifications'
     __table_args__ =  {mysql_engine:InnoDB,
                        mysql_row_format:DYNAMIC,
                        mysql_charset:utf8}

     notification_id = Column(bigint, ForeignKey('notifications.id',
  name='fk_bn_notificationid'), primary_key=True, autoincrement=False)
     event_id = Column(bigint, ForeignKey('doc_events.id',
  name='fk_bn_eventid'), nullable=True)
     created_on = Column(types.DATETIME, nullable=False,
  default=func.current_timestamp())
     last_updated = Column(types.DATETIME, nullable=True,
  onupdate=func.current_timestamp())
     version_num = Column(types.SMALLINT, nullable=False, default=0)
     __mapper_args__ = {'polymorphic_identity':'event',
  'version_id_col': version_num}
  #