Learning SQL Alchemy
I spent a portion of my holidays studying the basics of SQL Alchemy. My first lesson is that SQL Alchemy is NOT an ORM for Python but instead a SQL abstraction tool with an ORM built-into it. At first I was having trouble understanding what this really meant, but after seeing an example it sunk in. Let's start by building a table.
from sqlalchemy import Table, Column, Integer, String
meta = sqlalchemy.MetaData("sqlite:///")
user_table = Table('userTable', meta,
Column('id', Integer, primary_key=True),
Column('name', String, unique=True, nullable=False),
Column('password', String, nullable=False))meta.create_all()
First thing we need is a MetaData object which holds all of our database schema information as well as our engine for executing queries. By passing "sqlite:///" in the MetData constructor we create an engine pointing at an in-memory SQLite database. To create a table, we just declare an instance of the Table object and pass in the necessary parameters: table name, our MetData instance and whatever columns we need in the table. The constructor for the Column class not only takes the column name and type, but constraints as well. Then all we have to do is execute the statement by using the create_all() method of the MetaData class.
Did you note the user_table variable we created? That comes in really handy when we want to start manipulating our new table.
insert = user_table.insert()
insert.execute(name='darrell', password='password1')
insert.execute(name='angie', password='password2')
insert.execute(name='nate', password='password3')
insert.execute(name='drew', password='password4')
See how easy inserting data is? There are methods just like the insert method above for select, insert and delete. Let's take a look at the select method.
select = user_table.select()
results = select.execute()for row in results:
print row.name, row.password
The result are just as you would expect.
darrell password1
angie password2
nate password3
drew password4
That's great, but how do we change Nate's password and then return only his record?
update = user_table.update(user_table.c.name=='nate')
update.execute(password='awesomeness')select = user_table.select(user_table.c.name=='nate')
results = select.execute()for row in results:
print row.name, row.password
It's very simple and readable code with one caveat: what is "user_table.c.name"? It's a convenience attribute containing a collection of all the columns in userTable. So what our update statement is saying in terms of SQL is "UPDATE userTable SET ????? WHERE name = 'nate'". The only thing we don't know at this point is what to change. That happens when we execute the statement on the next line. If you understand the update statement above, the select statement works exactly the same way. Our result is below.
nate awesomeness
We've seen select, update and insert, but what about delete?
delete = user_table.delete(user_table.c.name.like("d%"))
delete.execute()
select = user_table.select()
results = select.execute()
I couldn't help myself - I had to confuse the issue by using "LIKE". In my defense, now you know how to introduce a "LIKE" comparison into your code AND that the "c" attribute is more than just a collection of strings. Beyond that, the delete works exactly the way you would expect it to work: call the delete method by passing the constraining expression as a parameter and then execute the result.
Now I understand why SQL Alchemy is an SQL abstration tool. All I did in the examples above were execute very basic SQL statements; the ORM was never used. Why is this so powerful? Imagine being able to write the same code for a SQL Server database as you did for a MySQL server and having the confidence that it's going to work. That's the power of SQL Alchemy.
Labels: Python, SQL Alchemy






9 Comments:
have you tested sqlalchemy on python.net ?
By
< Fefo />, at Thu Jan 08, 01:39:00 AM
No I haven't tried running SQL Alchemy on IronPython (I'm assuming that's what you meant). Before I start doing that, I'd like to figure out how to get nose ported.
By
Darrell Hawley, at Thu Jan 08, 04:42:00 AM
You haven't even tapped into the Session stuff (and querying with sessions), and abstracting tables into models.
SQLAlchemy rocks.
By
davezor, at Thu Jan 08, 07:29:00 AM
People tell me that SQL Alchemy is better than Storm ORM, but actually I'm finding Storm to be quite usable. The only downside is that the documentation sucks. It might be worth looking into, as I've found it easier to use for what I need (which is an ORM much like the Django one)
By
Max, at Thu Jan 08, 11:03:00 AM
davezor, I agree. SQL Alchemy DOES rock. I'd like to see a tool like this in the .NET space though given time I would guess IronPython would be able to consume SQL Alchemy. We'll see.
By
Darrell Hawley, at Sun Jan 11, 11:26:00 AM
Max, I'll take a look at Storm just to see, though I'm of the opinion that working with tools that have little documentation is more work than it's worth.
By
Darrell Hawley, at Sun Jan 11, 11:28:00 AM
@darrell: i swear i've heard of a good orm for .net. i believe it was called linq or something similar. microsoft may have frozen development on it though. may be worth looking into.
By
davezor, at Sun Jan 11, 11:54:00 AM
davezor, There are many ORM's for .NET, though LINQ is not one of them. LINQ stands for Language INtegrated Query and makes it possible to query any number of sources directly in your C# or VB.NET code. In fact, it has a lot in common with list comprehensions. If it's not already in the works, I'm sure somebody will soon be writing an ORM based on LINQ, but in the mean time, I'll continue to use NHibernate and Castle ActiveRecord.
By
Darrell Hawley, at Sun Jan 11, 03:37:00 PM
"...but in the mean time, I'll continue to use NHibernate and Castle ActiveRecord."
for my .NET development, anyways.
By
Darrell Hawley, at Sun Jan 11, 03:41:00 PM
Post a Comment
<< Home