[sqlalchemy] Question on the precedence of insert and delete in session flush

2011-07-27 Thread ammar azif
Hi,

I am using SQLAlchemy 0.6.4 with postgres db. I have two tables - users and
addresses tables with addresses table having a foreign key constraint
referencing the users table. Each address record is identified by a unique
constraint key 'email_address'.
In my test case, each user instance have a collection of addresses. For each
user instance, I want to delete every address instance in the addresses
collection that the user instance has and then add new address instances
(they may have the same unique key that the previously deleted address
instance had). The problem I am having now is that at the end of the flush
call, unique constraint error for 'email_address' from addresses table is
thrown even though delete operation is done earlier than insert. Looking at
the echo output, INSERTs are indeed done first than DELETEs. The work around
that I have now is to call flush() right after the deletion of address
instances in each user.

My question is - what is the precedence of insert, delete and update in
session flush? It would also be helpful if someone can explain the overview
of the mechanics of flushing in SQLAlchemy.
Attached is the python script that I wrote to understand why this problem
mentioned above happens.

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.

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import Column, UniqueConstraint, ForeignKeyConstraint
from sqlalchemy.types import String, Integer
from sqlalchemy.orm import sessionmaker, relationship, backref
from sqlalchemy import create_engine

engine = create_engine('postgres://postgres:data01@localhost:5432/flush_test')

Base = declarative_base()

class User(Base):
__tablename__ = 'users'
__table_args__ = (
UniqueConstraint('name',
name='users_name_key'),
{})
id = Column(Integer, primary_key=True)
name = Column(String(20), nullable=False)

def __init__(self, name):
self.name = name

def __repr__(self):
return User('%s') % self.name

class Address(Base):
__tablename__ = 'addresses'
__table_args__ = (
UniqueConstraint('email_address',
name='addresses_email_address_key'),
ForeignKeyConstraint(['username'],
 ['users.name'],
 onupdate='cascade'),
{}
)
id = Column(Integer, primary_key=True)
email_address = Column(String(20), nullable=False)
username = Column(String(20), nullable=False)
user = relationship(User, backref=backref('addresses', cascade='all, delete-orphan'))

def __init__(self, email_address):
self.email_address = email_address
def __repr__(self):
return Address('%s') % self.email_address

metadata = Base.metadata
metadata.create_all(engine)
Session = sessionmaker(bind=engine, autoflush=False)

session = Session()
session.rollback()

# begin init code that puts the persisted instance into the database
if session.query(User).filter_by(name='user1').count()==0:
user1 = User('user1')
user1.addresses.append(Address('us...@email.com'))
session.add(user1)
session.commit()

else:
user1=session.query(User).filter_by(name='user1').one()
if len(user1.addresses)==0:
user1.addresses.append(Address('us...@email.com'))
session.commit()
# end init code

engine.echo = True

for address in user1.addresses:
session.delete(address)

user1.addresses.append(Address('us...@email.com'))

# After the flush line below unique constraint error for address table is thrown,
# echo output shows that insertion of child item was done first before delete, although we call delete first.
# This does not happen if we flush after delete.
session.flush() 


[sqlalchemy] Question about sqlalchemy inserts and deletes order in a transaction

2011-07-19 Thread ammar azif
Hi,

The code that I am working on deletes rows from table A that are based on a
certain query and then recreates these rows based on entries supplied by a
csv file. Table A is referenced by table B. My question is, how does sql
alchemy manage inserts and deletes in a transaction and it what order are
they done? It seems that deletes are done after inserts because I am getting
unique constraint errors, although the rows are deleted before inserts are
done. If my assumption is correct, how do I change this behaviour in
SQLAlchemy. I do not want to add unique deferrable constraint into table A
because its unique constraint key is being referred by table B, this is a
limitation of postgres.

Appreciate your feedback

-- 
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] Question about how session works in SQLAlchemy

2010-12-28 Thread ammar azif
Hi,

Attached is a simple script that inserts a record using
Table.insert().execute() method and session.execute(Table.insert()).

When I tried running session.execute(Table.select()), both records inserted
by Table.insert().execute() and session.execute(Table.insert()) are
retrieved, but when I tried running
Table.select().execute(), only the record inserted through
Table.insert().execute() is shown.

What are the differences between session.execute() and
Table.insert/select.execute() ? Are they using different connection objects?
Or is this behavior much more related to the transactions used by both
execute methods?

Note that when using sqllite in memory db, both records inserted by both
methods are always retrieved when query is issued.

-- 
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, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import sqlalchemy.pool as pool
import psycopg2

def getconn():
c = psycopg2.connect(user='postgres', host='127.0.0.1', database='session_test')
return c

engine = create_engine('postgresql+psycopg2://', creator=getconn)
Base = declarative_base()

class User(Base):
__tablename__ = 'users'

id = Column(Integer, primary_key=True)
name = Column(String)

def __init__(self, name):
self.name = name

Base.metadata.create_all(engine)
Base.metadata.bind = engine

Session = sessionmaker(bind=engine)
session = Session()

session.execute(User.__table__.insert().values(name='John'))
User.__table__.insert().values(name='Tim').execute()
# Only user Tim is shown
print User.__table__.select().execute().fetchall()
# Both user Tim and John are shown
print session.execute(User.__table__.select()).fetchall()
session.commit()