[sqlalchemy] Mixing declarative style with expression language

2013-02-12 Thread Oltmans
Greetings, I trust everyone is doing well.

Our code base uses SQLAlchemy and some of the old code uses expression 
language style code e.g. 


appts = Table(Appointment, META, autoload=True, autoload_with=DB)
statement = select([appts.c.appointmentId], and_(
appts.c.appointmentId == 212


))
results = select_all(statement)


where as some of our code uses declarative style classes e.g.

class Appointment(Alchemy_Base, QueryMixin):

__tablename__ = Appointment
appointmentId = Column(Integer, primary_key=True)

@classmethod
def get_by_id(cls, appointment_id):
query = cls.query.filter_by(appointmentId=appointment_id)
return query.one()


Some of our scripts are going to use both of these files (both expression 
style and declarative style) so my question is, is it (i.e. mixing two 
styles of code) going to cause any sort of problems or we're going to be 
okay? 

I am asking because some people in our company are suggesting that we 
convert all code into one format (devs want to convert expression style old 
code into declarative style code).

Kindly let me know your suggestions. BTW, we're using MySQL as database and 
Python 2.6.4. Thanks in advance. 

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




Re: [sqlalchemy] Mixing declarative style with expression language

2013-02-12 Thread Michael Bayer

On Feb 12, 2013, at 9:21 AM, Oltmans rolf.oltm...@gmail.com wrote:

 Greetings, I trust everyone is doing well.
 
 Our code base uses SQLAlchemy and some of the old code uses expression 
 language style code e.g. 
 
 
 appts = Table(Appointment, META, autoload=True, autoload_with=DB)
 statement = select([appts.c.appointmentId], and_(
 appts.c.appointmentId == 212
 
 
 ))
 results = select_all(statement)
 
 
 where as some of our code uses declarative style classes e.g.
 
 class Appointment(Alchemy_Base, QueryMixin):
 
 __tablename__ = Appointment
 appointmentId = Column(Integer, primary_key=True)
 
 @classmethod
 def get_by_id(cls, appointment_id):
 query = cls.query.filter_by(appointmentId=appointment_id)
 return query.one()
 
 
 Some of our scripts are going to use both of these files (both expression 
 style and declarative style) so my question is, is it (i.e. mixing two styles 
 of code) going to cause any sort of problems or we're going to be okay? 
 
 I am asking because some people in our company are suggesting that we convert 
 all code into one format (devs want to convert expression style old code into 
 declarative style code).
 
 Kindly let me know your suggestions. BTW, we're using MySQL as database and 
 Python 2.6.4. Thanks in advance. 

OK well this answer got kind of long.   This is the TLDR:   make sure your 
select_all() function is making use of the same Session that your 
Appointment.get_by_id() method is using..   If that make sense, then you're 
good to go.Ultimately your code would probably be more succinct and cleaner 
if you moved to an all ORM style, but as far as actual execution problems just 
sharing the Session as a point of execution is enough.

With the TLDR given, here is the detailed explanation:

There's one aspect to this style that is worth taking a look at, which is the 
scope of connection checkouts and transactions.It's not so critical that 
you're producing SQL queries using two different systems, what can cause 
problems in some situations is that those two sets of SQL queries are invoked 
using different connection contexts, and once the application wants to use both 
styles in an interactive way, but due to the use of many different connections 
simultaneously, the work of the two systems carries on in separate transactions 
which are isolated from each other and can produce conflicts.

So in the abstract, what we are talking about is if you wrote a program like 
this (this is not SQLAlchemy code):

connection = database.connect()

connection.execute(statement 1)

connection.execute(statement 2)

connection.execute(statement 3)

connection.commit()

connection.close()


Above, that's pretty simple, three statements on a connection, within a 
transaction.  When we invoke statement 2, the work of statement 1 will be 
available to us, and invoking statement 3, we'll be able to see the work of 
statement 2 and 1 as well.   Other parts of the program or other applications 
that are using the same database, will in all likelihood not see much of the 
effects of these three statements until we commit the transaction, which is due 
to a behavior known as transaction isolation.   The one case you actually won't 
have any isolation is if your MySQL database is using MyISAM tables.   If 
you're on MyISAM, most of what I'm writing about here probably doesn't matter 
because there's no real transactions present.  But assuming you're on InnoDB, 
the above style is the best way to go.   This is in contrast to this:

conn1 = database.connect()
conn1.execute(statement 1)

conn2 = database.connect()
conn2.execute(statement 2)
conn2.commit()

conn3 = database.connect()
conn3.execute(statement 3)

conn1.commit()
conn3.commit()

So above, we illustrate using three separate connections to emit the three 
statements, using three separate transactions.  Just to make it even more 
disastrous I've interleaved the first and third transactions.   If you're using 
InnoDB, the above system will be very prone to issues, assuming there's some 
degree of relationship between those three statements.   The effects of 
statement1 won't be visible to that of statement2, nor will statement3 have any 
context.  The risk of conflicts and locks is greatly increased as well.  We're 
mixing up transactions and additionally putting a lot more burden on the 
database with three separate connections in use as well as three individual 
commits.


So when using SQLAlchemy we want to make sure the way a series of steps 
proceeds is closer to the first version.When mixing the Core and ORM as 
you're doing, this is doable, but you need to invoke the Core and ORM queries 
using the same context.   Normally, if you invoke  Core statement like this:


stmt = table.select()
result = engine.execute(stmt)

or even like this:

result = stmt.execute()

what we're using above is a feature called implicit execution, where