[sqlalchemy] ClassManager.new_instance does not longer initialize polymorphic column

2012-01-31 Thread Torsten Landschoff
Hello again,

for a while I want to upgrade our application to use SQLAlchemy 0.7.x.
However I am running into changed behaviour wrt.
ClassManager.new_instance. The behaviour I rely on was discussed here:

http://article.gmane.org/gmane.comp.python.sqlalchemy.user/28746

Basically, I want to create an empty instance of a mapped class and
unserialize my data into it. I am not using Pickle because of security
and compatibility fears.

The attached sample program worked fine with SQLAlchemy 0.6.8:

$ python new_instance.py 
__main__.Engineer object at 0x10774d0

However, with SQLAlchemy 0.7.5 I get

$ python new_instance.py 
Traceback (most recent call last):
  File new_instance.py, line 27, in module
session.commit()
  [...]
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.7.5dev-py2.6-linux-x86_64.egg/sqlalchemy/engine/default.py,
 line 330, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (IntegrityError) people.type may not be NULL 
u'INSERT INTO people (type) VALUES (?)' (None,)

I'd really like to use 0.7.5 but I don't know how to replace
new_instance. I attached the sample program and a suggested patch for
the documentation: In the declarative example, the type column is
nullable.

I found out the hard way that it should rather not be. Having a
non-nullable type column at least unconvers the problem when writing to
the database, not when reading the corrupted database :-)

Greetings, Torsten

-- 
DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
Torsten Landschoff

Office Dresden
Tel: +49-(0)351-4519587
Fax: +49-(0)351-4519561

mailto:torsten.landsch...@dynamore.de
http://www.dynamore.de

Registration court: Stuttgart, HRB 733694
Managing director: Prof. Dr. Karl Schweizerhof, Dipl.-Math. Ulrich Franz

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

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.orm.attributes import manager_of_class
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()

class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
discriminator = Column('type', String(50), nullable=False)
__mapper_args__ = {'polymorphic_on': discriminator}

class Engineer(Person):
__tablename__ = 'engineers'
__mapper_args__ = {'polymorphic_identity': 'engineer'}
id = Column(Integer, ForeignKey('people.id'), primary_key=True)
primary_language = Column(String(50))

engine = create_engine(sqlite:///)
Base.metadata.create_all(engine)
session = sessionmaker(engine)()

e = manager_of_class(Engineer).new_instance()
session.add(e)
session.commit()

print session.query(Engineer).first()
diff -r ebe9514a69a4 lib/sqlalchemy/ext/declarative.py
--- a/lib/sqlalchemy/ext/declarative.py	Sat Jan 28 17:43:13 2012 -0500
+++ b/lib/sqlalchemy/ext/declarative.py	Tue Jan 31 12:50:35 2012 +0100
@@ -389,7 +389,7 @@
 class Person(Base):
 __tablename__ = 'people'
 id = Column(Integer, primary_key=True)
-discriminator = Column('type', String(50))
+discriminator = Column('type', String(50), nullable=False)
 __mapper_args__ = {'polymorphic_on': discriminator}
 
 class Engineer(Person):


Re: [sqlalchemy] ClassManager.new_instance does not longer initialize polymorphic column

2012-01-31 Thread Torsten Landschoff
On Tue, 2012-01-31 at 12:52 +0100, Torsten Landschoff wrote:

 However, with SQLAlchemy 0.7.5 I get
 
 $ python new_instance.py 
 Traceback (most recent call last):
   File new_instance.py, line 27, in module
 session.commit()
   [...]
   File 
 /usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.7.5dev-py2.6-linux-x86_64.egg/sqlalchemy/engine/default.py,
  line 330, in do_execute
 cursor.execute(statement, parameters)
 sqlalchemy.exc.IntegrityError: (IntegrityError) people.type may not be NULL 
 u'INSERT INTO people (type) VALUES (?)' (None,)

I found a workaround:

--- a/new_instance.py   2012-01-31 12:50:44.510525675 +0100
+++ b/new_instance.py   2012-01-31 13:05:52.110514861 +0100
@@ -1,6 +1,6 @@
 from sqlalchemy import *
 from sqlalchemy.orm import *
-from sqlalchemy.orm.attributes import manager_of_class
+from sqlalchemy.orm.attributes import manager_of_class, instance_state
 from sqlalchemy.ext.declarative import declarative_base
 
 
@@ -22,7 +22,11 @@
 Base.metadata.create_all(engine)
 session = sessionmaker(engine)()
 
-e = manager_of_class(Engineer).new_instance()
+manager = manager_of_class(Engineer)
+e = manager.new_instance()
+state = instance_state(e)
+manager.mapper._set_polymorphic_identity(state)
+
 session.add(e)
 session.commit()

But this is leaving the area of documented API. I found out that
SQLAlchemy actually initializes the polymorphic_identity column by
registering an on_init event. I'd rather trigger that but I did not yet
find out how to do that.

Thanks, Torsten

-- 
DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
Torsten Landschoff

Office Dresden
Tel: +49-(0)351-4519587
Fax: +49-(0)351-4519561

mailto:torsten.landsch...@dynamore.de
http://www.dynamore.de

Registration court: Stuttgart, HRB 733694
Managing director: Prof. Dr. Karl Schweizerhof, Dipl.-Math. Ulrich Franz


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



[sqlalchemy] NEW and OLD objects in sqlalchemy events

2012-01-31 Thread lestat
I try rewrite trigger for postgresql in python sqlalchemy event
function.

Can I in sqlalchemy event context get NEW and OLD objects?

I need compare attributes of NEW and OLD objects.


Thanks!

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



Re: [sqlalchemy] SQLAlchemy 0.7.5 Released

2012-01-31 Thread Michael Bayer
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

That is a bug with readthedocs.   The content should be the 0.7.5 content (not 
100% sure though).




On Jan 31, 2012, at 2:12 AM, Fayaz Yusuf Khan wrote:

 On Saturday 28 Jan 2012 6:05:51 PM Michael Bayer wrote:
 SQLAlchemy 0.7.5 is now available.
 Where's the documentation (pdf)? Or has nothing changed there since 0.7.4?
 http://media.readthedocs.org/pdf/sqlalchemy/latest/sqlalchemy.pdf still gives 
 the older pdf.
 -- 
 Fayaz Yusuf Khan
 Cloud developer and architect
 Dexetra SS, Bangalore, India
 fayaz.yusuf.khan_AT_gmail_DOT_com
 fayaz_AT_dexetra_DOT_com
 +91-9746-830-823

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQEcBAEBAgAGBQJPKAWVAAoJEDMCOcHE2v7hir4IAIycYUS/xzQupjHT7nygx7Z5
sYfK4MjHMZ+DMoYl6EvEYd/sPS9Zalv//El1izSUS3RypsFWgW9qQi5Cvob8fypH
53vHPCPQZSdiLBhU9VZnMT+KvepQ+3hQWjGZt+HPK71uZfCpkeIb2woPsec9ZldI
X1aB9Ne806WihXe1dF8vwhmJ7B21yqufjv1kjh5/GY9luyawxq407+YXSOHYnIQP
9/w1SF37D5UxrHeekxvfjxe9jWJyT7xDr+LEGuPfb4KSKTaePCo48kFeDAPRa6kq
pJ5+xKfvRPZrUawaTSE3PvWeinQDkrDQnQj2j7sH5umoka+V+hQDchvpaP3e6pY=
=XS7L
-END PGP SIGNATURE-

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



Re: [sqlalchemy] ClassManager.new_instance does not longer initialize polymorphic column

2012-01-31 Thread Michael Bayer

On Jan 31, 2012, at 7:08 AM, Torsten Landschoff wrote:

 On Tue, 2012-01-31 at 12:52 +0100, Torsten Landschoff wrote:
 
 However, with SQLAlchemy 0.7.5 I get
 
 $ python new_instance.py 
 Traceback (most recent call last):
  File new_instance.py, line 27, in module
session.commit()
  [...]
  File 
 /usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.7.5dev-py2.6-linux-x86_64.egg/sqlalchemy/engine/default.py,
  line 330, in do_execute
cursor.execute(statement, parameters)
 sqlalchemy.exc.IntegrityError: (IntegrityError) people.type may not be NULL 
 u'INSERT INTO people (type) VALUES (?)' (None,)


If you're using new_instance() to create the instance, then you are 
deserializing data from somewhere, why isn't the discriminator value, which is 
after all one of the column values in the table, not present in this 
deserialization ?

Right now the event in question is emitted only from the __init__() method of 
your object, which is obviously what you don't call when deserializing.The 
discriminator value is now considered to be just another instance variable that 
you can change freely - a default for it is configured from __init__().

Anyway the event here is the init event which you can emit from classmanager:

manager.dispatch.init(state, args, kw)

where args, kw are what would normally be sent to __init__, but can just be 
blank here.

Invoking the events is not entirely public API, though.  





 
 I found a workaround:
 
 --- a/new_instance.py 2012-01-31 12:50:44.510525675 +0100
 +++ b/new_instance.py 2012-01-31 13:05:52.110514861 +0100
 @@ -1,6 +1,6 @@
 from sqlalchemy import *
 from sqlalchemy.orm import *
 -from sqlalchemy.orm.attributes import manager_of_class
 +from sqlalchemy.orm.attributes import manager_of_class, instance_state
 from sqlalchemy.ext.declarative import declarative_base
 
 
 @@ -22,7 +22,11 @@
 Base.metadata.create_all(engine)
 session = sessionmaker(engine)()
 
 -e = manager_of_class(Engineer).new_instance()
 +manager = manager_of_class(Engineer)
 +e = manager.new_instance()
 +state = instance_state(e)
 +manager.mapper._set_polymorphic_identity(state)
 +
 session.add(e)
 session.commit()
 
 But this is leaving the area of documented API. I found out that
 SQLAlchemy actually initializes the polymorphic_identity column by
 registering an on_init event. I'd rather trigger that but I did not yet
 find out how to do that.
 
 Thanks, Torsten
 
 -- 
 DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
 Torsten Landschoff
 
 Office Dresden
 Tel: +49-(0)351-4519587
 Fax: +49-(0)351-4519561
 
 mailto:torsten.landsch...@dynamore.de
 http://www.dynamore.de
 
 Registration court: Stuttgart, HRB 733694
 Managing director: Prof. Dr. Karl Schweizerhof, Dipl.-Math. Ulrich Franz
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 To unsubscribe from this group, send email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/sqlalchemy?hl=en.
 

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



[sqlalchemy] Overload Query Object

2012-01-31 Thread Christian Démolis
Hi Michael,

i overload class Query in my script.
i have 4 ways to obtain query's results.

1/ session.query(model.x).all()
2/ session.query(model.x).first()
3/ session.query(model.x).one()
4/ for e in session.query(model.x):
print e

in case 1,2,3, i know which method is used
What method is used in case 4 ?

Thanks in advance.
Chris

class Query(Query):
def __init__(self, *arg, **kw):
self._populate_existing = True
super(Query, self).__init__(*arg, **kw)

def all(self):
print all, threading.current_thread()
param.lock_bdd.acquire()
global session
try:
x = super(Query, self).all()
except exc2.OperationalError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except exc2.StatementError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except:
raise
param.lock_bdd.release()
print /all, threading.current_thread()
return x

def one(self):
print one, threading.current_thread()
param.lock_bdd.acquire()
global session
try:
x = super(Query, self).one()
except exc2.OperationalError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except exc2.StatementError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except:
raise
param.lock_bdd.release()
print /one, threading.current_thread()
return x

def first(self):
print first, threading.current_thread()
param.lock_bdd.acquire()
global session
try:
x = super(Query, self).first()
except exc2.OperationalError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except exc2.StatementError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except:
raise
param.lock_bdd.release()
print /first, threading.current_thread()
return x

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



Re: [sqlalchemy] Overload Query Object

2012-01-31 Thread Tate Kim
Hi,

Have you checked the __iter__ method ? 
-Original Message-
From: Christian Démolis christiandemo...@gmail.com
Sender: sqlalchemy@googlegroups.com
Date: Tue, 31 Jan 2012 17:39:54 
To: sqlalchemysqlalchemy@googlegroups.com
Reply-To: sqlalchemy@googlegroups.com
Subject: [sqlalchemy] Overload Query Object

Hi Michael,

i overload class Query in my script.
i have 4 ways to obtain query's results.

1/ session.query(model.x).all()
2/ session.query(model.x).first()
3/ session.query(model.x).one()
4/ for e in session.query(model.x):
print e

in case 1,2,3, i know which method is used
What method is used in case 4 ?

Thanks in advance.
Chris

class Query(Query):
def __init__(self, *arg, **kw):
self._populate_existing = True
super(Query, self).__init__(*arg, **kw)

def all(self):
print all, threading.current_thread()
param.lock_bdd.acquire()
global session
try:
x = super(Query, self).all()
except exc2.OperationalError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except exc2.StatementError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except:
raise
param.lock_bdd.release()
print /all, threading.current_thread()
return x

def one(self):
print one, threading.current_thread()
param.lock_bdd.acquire()
global session
try:
x = super(Query, self).one()
except exc2.OperationalError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except exc2.StatementError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except:
raise
param.lock_bdd.release()
print /one, threading.current_thread()
return x

def first(self):
print first, threading.current_thread()
param.lock_bdd.acquire()
global session
try:
x = super(Query, self).first()
except exc2.OperationalError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except exc2.StatementError:
import common
common.alerte(L'écriture a échoué. Retentez l'action, Erreur
MySQL)
session.rollback()
except:
raise
param.lock_bdd.release()
print /first, threading.current_thread()
return x

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


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



[sqlalchemy] expunge cascade behavior change

2012-01-31 Thread Kent Bower
Somewhere between 0.6.4 and 0.7.5, the expunge cascade behavior 
changed.  Can you help me understand what changed/point me to the 
ticket?  The attached script assertions succeed in 0.6.4 but the last 
one fails in 0.7.5.  It doesn't seem wrong, but I'm wondering what the 
behavior was defined as previously and if that was considered a bug, etc.


Thanks,
Kent

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

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.orm.util import has_identity

engine = create_engine('sqlite:///', echo=True)
metadata = MetaData(engine)
Session = sessionmaker(bind=engine)

rocks_table = Table(rocks, metadata,
Column(id, Integer, primary_key=True),
)

bugs_table = Table(bugs, metadata,
Column(id, Integer, primary_key=True),
Column(rockid, Integer, ForeignKey('rocks.id'),),
)

class Rock(object):
def __repr__(self):
return 'Rock@%d: id=[%s] in session:[%s] has_identity[%s]' % (id(self), self.__dict__.get('id'), self in session, has_identity(self))

class Bug(object):
def __repr__(self):
return 'Bug@%d: id=[%s] rockid[%s] with rock[%s]' % (id(self), self.__dict__.get('id'), self.__dict__.get('rockid'), self.__dict__.get('rock','not set'))


mapper(Rock, rocks_table,
properties={'bugs': relationship(Bug,
cascade='all,delete-orphan', 
backref=backref('rock',cascade='refresh-expire,expunge'))
})

mapper(Bug, bugs_table)


metadata.create_all()

session = Session()


# add a rock and bug
rock=Rock()
rock.id = 0
bug=Bug()
bug.id = 0
rock.bugs.append(bug)
session.add(rock)

session.commit()

# later... new session
session = Session()
rock = session.query(Rock).get(0)
rock.bugs.append(Bug())

assert rock in session

rock.bugs = []

assert rock in session


[sqlalchemy] What's the idiomatic way of writing INSERT... ON DUPLICATE KEY UPDATE

2012-01-31 Thread Didip Kerabat
when using SqlAlchemy Core (not using Session/ORM)?

I have quite a few tables with composite primary keys that can use it
for optimization.

At the moment what I have is quite ghetto, below is a contrive example
of it:

stmt = str(user_table.insert().values(email=email, name=name))
stmt +=  ON DUPLICATE KEY UPDATE name=%s
engine.execute(stmt, email, name, name)

NOTE: I believe this is MySQL specific.

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



[sqlalchemy] Learn Chinese (Mandarin) faster by using flashcards with pictures

2012-01-31 Thread ichineseflashcards 8
http://www.ichineseflashcards.com will help you learn Chinese
(Mandarin) faster by using flashcards with pictures, thanks

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