[sqlalchemy] Re: SQLAlchemy 0.5.5 MySQL Issue

2009-11-29 Thread gizli
Thank you. That was exactly the problem. MyISAM engine was selected as
default, changed to InnoDB and now the autoflush behavior is as
expected.

On Nov 28, 4:36 am, Alexandre Conrad alexandre.con...@gmail.com
wrote:
 You may be using MyISAM storage engine which doesn't support transactions
 and may make all flushes persistent. The other storage engine widely used is
 InnoDB which does support transactions. Find out in the MySQL docs how to
 figure out which storage engine you're using.

 Sent from my fantastic HTC Hero

 On Nov 28, 2009 7:27 AM, gizli mehm...@gmail.com wrote:

 I am not sure about the storage engine but here goes:

 mysql status
 --
 mysql  Ver 14.12 Distrib 5.0.75, for debian-linux-gnu (i486) using
 readline 5.2

 the mysql-python version is MySQL_python-1.2.3c1

 On Nov 26, 11:47 pm, Alexandre Conrad alexandre.con...@gmail.com
 wrote:

  2009/11/27 gizli mehm...@gmail.com:
With mysql however, the insert done by the query() actually does a  

 commit.. i turned on ec...

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

--

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: SQLAlchemy 0.5.5 MySQL Issue

2009-11-27 Thread gizli
I am not sure about the storage engine but here goes:

mysql status
--
mysql  Ver 14.12 Distrib 5.0.75, for debian-linux-gnu (i486) using
readline 5.2

the mysql-python version is MySQL_python-1.2.3c1

On Nov 26, 11:47 pm, Alexandre Conrad alexandre.con...@gmail.com
wrote:
 2009/11/27 gizli mehm...@gmail.com:

  With mysql however, the insert done by the query() actually does a
  commit.. i turned on echo, and i dont see an explicit commit but this
  is what seems to happen.. After the program is done, I can see Obj(5)
  in the mysql database.

  Is this a known problem? Or am I doing something wrong here?

 Which MySQL storage engine are you using?

 Alex

--

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] Concurrent Update Errors

2009-09-17 Thread gizli

Hi guys,

I have a couple of questions about a recent concurrency test I did on
SA. Someone in our team ran into a very intermittent issue where a
certain operation he tried doing failed by ConcurrentUpdateError. I
wrote a simple thread that can do query/update/insert/commit/rollback
operations on demand and created two of those to create specific race
conditions manually.. I found out some interesting stuff:

If I use sqlite, two threads cannot operate on the same ORM object.
E.g.:

t1.update(obj)
t2.update(obj)
t1.commit()
t2.commit()

t2.update(obj) would fail with an error saying Database is locked.

If I use mysql to do the same thing it goes through with no problems.
The only time I could reproduce the concurrent update error is like
this:

t1.update(obj)
t2.delete(obj)
t2.commit()
t1.commit()

The last line will throw the error saying num updated rows is 0 where
it was expecting 1. My first question is: Can this concurrent update
error arise in any other situation?

I also tried the following:

t1.delete(obj)
t2.delete(obj)
t2.commit()
t1.commit()

This also fails with the same error saying the num deleted rows is 0
when it was expecting 1. My second question is: Should t1's
transaction go through? I would think so. I understand why an update
to a deleted row fails the entire transaction but I do not understand
the motivation for failing an entire transaction because a row I
wanted to delete is already deleted.

This behavior is, as far as I can see, embedded in SA logic. So no
matter which database I use, I will see this right? (unless something
happens more fundamentally at the db level, like in sqlite, getting
the database locked error)

The final question is a design question. In a typical web application
that can have 100's of simultaneous users submitting a handful of
tasks, how do we avoid this kind of concurrency issues? Each request
would be handled with a separate thread meaning if any of these
threads try modifying the same db object, we have a potential problem.
Do we need exclusive locks for this kind of situation? Does SA allow
us to do 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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Concurrent Update Errors

2009-09-17 Thread gizli

Thanks for the excellent information Michael. Will need to think about
this and post again if I have further questions.

As for the delete/rm discussion, I guess it depends on your use case.
I usually run rm with -f flag which fails silently if no file is
found. But I get your point and you also provided a way to turn the
feature off. Thanks a lot.

On Sep 17, 3:59 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 gizli wrote:

  t1.delete(obj)
  t2.delete(obj)
  t2.commit()
  t1.commit()

 I also forgot to mention that you can always use query.delete() or
 table.delete() to get a standard relational delete, though it does not
 offer in-python cascading.  This delete translates directly to DELETE with
 the given criterion and doesn't care if the rows matching its condition
 exist or not.
--~--~-~--~~~---~--~~
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] Setting language for a db session

2009-09-14 Thread gizli

Hi all,

I am just starting to think about this topic so please dont shoot me
if I missed the obvious :).

There are many varieties of database errors. So, sometimes in our
code, we need to let these errors be returned to the user. E.g. we
would like a french guy using this application to have a french
translation of these error messages. Ideally, a single application
should be able to return errors in multiple languages depending on
which language the database session was setup with.

From my understanding, some databases like MySQL does not support
setting language for a particular DB session. Some others, such as
Oracle, allows this. Is this ever considered in SA? or is our only
option to write SQL code to explicitly pass the language parameter to
a session? Do you guys have a better answer?

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



[sqlalchemy] Re: Automatic Polymorphic Identity Assignment

2009-09-10 Thread gizli

Found two ways of doing this:

1. use metaclass:

from sqlalchemy.ext.declarative import DeclarativeMeta

class PolymorphicSetter(DeclarativeMeta):
def __new__(cls, name, bases, dictionary):
if '__mapper_args__' in dictionary.keys():
dictionary['__mapper_args__']['polymorphic_identity'] =
name
else:
dictionary['__mapper_args__'] = dict
(polymorphic_identity=name)
return DeclarativeMeta.__new__(cls, name, bases, dictionary)

and in my base class Task:

class Task(DeclarativeBase):
__metaclass__ = PolymorphicSetter

ii. Use class decorators.. write a function similar to the
polymorphicsetter class above and return the modified cls object..
then for every subclass of Task, use the decorator..

The advantage of the first approach is that, there is no need to do
anything once the Task class is extended..



On Sep 9, 7:51 pm, gizli mehm...@gmail.com wrote:
 Thanks for the suggestion Wolodja but I dont think that would work.
 The self object is not defined at the time of class loading in python:

  class Test:

 ...     qq = self.__class__.__name__
 ...     def fu(self):
 ...             print fu
 ...
 Traceback (most recent call last):
   File stdin, line 1, in module
   File stdin, line 2, in Test
 NameError: name 'self' is not defined

 I will post the solution here if I find any.
--~--~-~--~~~---~--~~
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] Automatic Polymorphic Identity Assignment

2009-09-09 Thread gizli

Hi all,

This list has been very helpful so far, thanks a lot. I was just
wondering if there is a transparent way to assign polymorphic
identities to ORM classes using single table inheritance. Let's say we
have a base Task class:

class Task(DeclarativeBase):
   __tablename__ = 'Tasks'

   id = Column(Integer)
   name = Column(String)
   type = Column(String) etc...

   __mapper_args__ = {'polymorphic_on' : type}

now I want to declare multiple Task types like this:

class MyTask(Task):
__mapper_args__ = {'polymorphic_identity': 'MyTask'}

class YourTask(Task):
__mapper_args__ = {'polymorphic_identity': 'YourTask'}

This is the recommended way in the documentation for declarative
style. I was wondering if I could get rid of the explicit
polymorphic_identity setup in the subclasses by some clever
programming trick. I want to assign the polymorphic identity to be the
class __name__ automatically if that class extends Task class. I am
not very well versed in advanced python programming like decorators or
function/class wrappers, so I wanted to seek your opinion.

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



[sqlalchemy] Re: Automatic Polymorphic Identity Assignment

2009-09-09 Thread gizli

Thanks for the suggestion Wolodja but I dont think that would work.
The self object is not defined at the time of class loading in python:

 class Test:
... qq = self.__class__.__name__
... def fu(self):
... print fu
...
Traceback (most recent call last):
  File stdin, line 1, in module
  File stdin, line 2, in Test
NameError: name 'self' is not defined

I will post the solution here if I find any.
--~--~-~--~~~---~--~~
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] Curious Problem

2009-09-01 Thread gizli

Hi all,

I just discovered something weird when doing concurrency testing with
my program. Before writing a simplified test case for it and really
figuring out whether its a bug with sqlalchemy (I am using 0.5.5), I
wanted to write the scenario here. Basically I was getting the
infamous Set size changed during iteration error during commit.
Multiple threads are not accessing the same session (as was in some of
the posts I have read online). Here's what I am doing:

There is a task dispatcher that queries the database, gets a list of
tasks to be done, dispatches them to separate threads. Each thread
creates its own session using the session_maker and updates the status
of a task. There are three kinds of objects in question: Task,
TaskSchedule and TaskResult. There is a one-to-many relation between
Task and TaskSchedule. There is also a one-to-many relation between
Task and TaskResult. Pseudo code:

task_dispatcher:
   for task_schedule in sess.query(TaskSchedule).filter
(next_execution_time = current_time):
   do_task(task_schedule.task) -- using relation
   task_schedule.next_execution_time = some_value
   sess.commit()

(in a new thread)
do_task(task):
 sess := get_session()
 sess.add(TaskResult(task.id, task_started))
 sess.commit()
 task.perform()
 sess.merge(TaskResult(task.id, task_finished))
 sess.commit()
 sess.close()

Basically, I get the mysterious error for the commit in
task_dispatcher intermittently (probably 10 times out of 1000
executions). This brings me to my first question: Is it bad practice
to commit a session from within the sess.query() loop? I wanted each
task execution time update to be independent of other tasks. If this
is bad practice, then should I use sub-transactions for this purpose?

After realizing this possible pitfall, I changed the code to commit
only after the loop has finished. This lead to another interesting
result: None of my TaskResult objects got committed. Instead I saw a
lot of ROLLBACK's in the log with no errors associated with them.

I tried yet another variation. This is the one that puzzled me the
most. I tried eager loading the task relation in the TaskScheduleItem
and it worked like a charm:

task_dispatcher:
   for task_schedule in sess.query(TaskScheduleItem).options(eagerload
('task')).filter(next_execution_time = current_time):
   do_task(task_schedule.task) -- using relation
   task_schedule.next_execution_time = some_value
   sess.commit()

This time, no errors, the TaskResults appeared in database with each
commit in the do_task function.

Does anyone have an insight into this?

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



[sqlalchemy] Autoflush setting

2009-08-28 Thread gizli

Hi all,

I have a pretty basic question about autoflush that I could not find
an answer to. By default, in sessionmaker, this is set to true.
However, I have this basic scenario where my transaction involves
inserting objects into session and querying for some others:

add(o1)
query(SomeObject)
add(o2)
commit()

While this transaction is going on, I dont want any of the other
threads to see o1.  Only after commit, both objects should be
visible.

Does that mean i need to set autoflush to false? Is there any
disadvantage of doing so since this is the default setting?

Thanks.

On a related note, the reason why I do not want o1 to appear in the
database without o2 is because they are dependent from the UI point of
view (the rendering page needs an o2 if an o1 is present). Does that
mean they should have been modeled using relations and inserted using
relations as well? That would mean doing the query before o1 and
building o1,o2 together and that would avoid this issue. Is this why I
am running into these problems that seem trivial w.r.t. autoflush?
--~--~-~--~~~---~--~~
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] Re: Autoflush setting

2009-08-28 Thread gizli

Okay. I believe this is my mistake. I just wrote a simple test program
and saw that the other threads should not see o1 or o2 until commit
since I am using scoped_session. I guess there is another reason for
the behavior I am seeing.

On Aug 28, 10:05 pm, gizli mehm...@gmail.com wrote:
 Hi all,

 I have a pretty basic question about autoflush that I could not find
 an answer to. By default, in sessionmaker, this is set to true.
 However, I have this basic scenario where my transaction involves
 inserting objects into session and querying for some others:

 add(o1)
 query(SomeObject)
 add(o2)
 commit()

 While this transaction is going on, I dont want any of the other
 threads to see o1.  Only after commit, both objects should be
 visible.

 Does that mean i need to set autoflush to false? Is there any
 disadvantage of doing so since this is the default setting?

 Thanks.

 On a related note, the reason why I do not want o1 to appear in the
 database without o2 is because they are dependent from the UI point of
 view (the rendering page needs an o2 if an o1 is present). Does that
 mean they should have been modeled using relations and inserted using
 relations as well? That would mean doing the query before o1 and
 building o1,o2 together and that would avoid this issue. Is this why I
 am running into these problems that seem trivial w.r.t. autoflush?
--~--~-~--~~~---~--~~
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] Performance Analysis

2009-08-15 Thread gizli

Hi all,

This is not really a sqlalchemy question but I was wondering if anyone
developing with sqlalchemy knows the answer.

Turning on echo=True spits out all the queries that the application
generates. Currently I am directing this output to a file and then
looking through to derive statistics like what kind of tables are most
frequently accessed. I use this to see where my program can be
optimized.

Are you aware of any tool built on top of sqlalchemy to do this kind
of analysis and give out a performance report?

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



[sqlalchemy] Re: Many-to-many relations

2009-08-12 Thread gizli

Never mind. Using primaryjoin and secondaryjoin helped quite a bit :)
--~--~-~--~~~---~--~~
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] Many-to-many relations

2009-08-10 Thread gizli

Hi all,

Please help me model this scenario with many-to-many relations:

I am trying to model a directed graph. My objects are nodes: n1...nk,
and I have a bunch of directed edges: n1 -- n3, n5 -- n6, n6 -- n2
and so on. From reading the documentation, I know that the nodes will
probably be one table, and edges will probably be defined as a
secondary table in a relation. The examples in the documentation
however assume that the relationship is between two tables (left and
right) whereas all I have is nodes. My intuition was to define an edge
table like this:

edges = Table(.. Column(source, Integer, ForeignKey('Nodes.id')),
Column(target, Integer, ForeignKey('Nodes.id')))

but I could not figure out how to turn this into a relation. How can I
design a Nodes table which would give me the following two relations:

n.incoming == The list of nodes such that there exists an edge where
n = target
n.outgoing == The list of nodes such that there exists an edge where
n = source

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



[sqlalchemy] Re: Reentrant data population script using sql alchemy

2009-08-10 Thread gizli

Thanks a lot Michael.

The merge functionality is what I was looking for. This also exposed a
flaw in our model I think. We keep using the auto-increment primary
keys which would make merge() impossible to use in the scenario I was
describing. Right?



 The easiest way to do auto insert or update given an object that  
 you've loaded from a file is to use merge():

         myobj = session.merge(myobj)

 which will do the SELECT for you.  If the object is already loaded, no  
 SELECT is emitted.

 So it follows then that you can SELECT all the rows of the table ahead  
 of time, keep them referenced in a collection:

         all_objects = session.query(MyStuff).all()

 then you can merge() each element you pull from the file as needed,  
 and no additional SQL should be emitted to fetch any of it.

--~--~-~--~~~---~--~~
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] Reentrant data population script using sql alchemy

2009-08-09 Thread gizli

Hi all,

Forgive me if this is a very basic question but I could not find the
answer anywhere.

I am trying to write a data population script to setup a few tables
and insert some data in them. I need to make this script reentrant..
The problem is that currently the script looks like this:

get a session
use metadata.create_all() to create all the tables
call add(obj) on all objects that need to be inserted
flush()
commit()

create_all api is reentrant..  However when I add() existing objects,
the script fails when flush() happens with integrity error. I thought
of wrapping the add() function and doing a flush after each add, catch
the integrity exception and pass. However that requires me to create a
new session object after each flush (since the transaction is rolled
back if a failure happens)..  Is there another way of doing this in
sqlalchemy w/o creating a session object for every single add() call?

One elegant way would be to be able to query the seed db for the obj..
if it exists, pass.. my script does not know about the structure of
the objects being inserted, therefore i cannot write a generic query
based on its attributes.. it would be nice if one could do something
like:

try:
   session.query(obj)
except NotFound:
   session.add(obj)

does such a thing exist in sql alchemy? if not, what do you suggest I
do? Please bear the following in mind:

1. I cannot remove everything in the tables at start time since there
is more than one script and there is only one seed db.
2. The solution has to be generic and not require me to know what kind
of attributes/primary_keys obj has
3. I would like to do this using one session instance if possible

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