使用SqlAlchemy的查询语句
是的,这个问题很基础。
我已经成功使用 declarative_base 创建了我的数据库,并且可以往数据库里插入数据了。我只是对 SqlAlchemy 的 SQL 语句有一些疑问。
我创建了一个叫做 Location 的表。
有几个问题(见下面的代码):
在 "print row" 这条语句中,我必须指定每个我想输出的列名,比如 "print row.name, row.lat, 等等"。为什么要这样做?(否则打印出来的内容会是
"<classname.Location at <...>>"
)还有,和数据库互动并执行查询(比如选择、插入、更新等)的推荐方式是什么?似乎有很多选择:比如使用 sqlalchemy.orm.select,或者 engine.text
(<sql 查询>).execute().fetchall()
,甚至是conn.execute(<select>).
有这么多选项真不错,但现在让我感到很困惑。
非常感谢你的建议!
这是我的代码:
from sqlalchemy import create_engine
from sqlalchemy.sql import select
from location_db_setup import *
db_path = "sqlite:////volumes/users/shared/programming/python/web/map.db"
engine = create_engine(db_path, echo= True)
Session = sessionmaker(bind= engine)
session = Session()
session.query(Location).fetchall()
for row in locations:
print row
3 个回答
使用ORM(对象关系映射)与数据库互动时,推荐的方式不是直接写查询语句,而是使用与数据库表对应的对象,通常还会配合一个叫做会话的对象来使用。比如,SELECT查询在某些ORM中变成了get()或find()的调用,而在其他的ORM中则是query()的调用。INSERT操作则是创建一个你想要的对象(可能还需要明确地添加,比如在sqlalchemy中用session.add())。UPDATE操作就是编辑这个对象,而DELETE操作则是删除这个对象(例如使用session.delete())。ORM的目的就是帮你把这些操作转换成SQL语句,省去你手动写的麻烦。
你有没有看过这个教程?
Denis和Kylotan给了你很好的回答。我就专注讲讲第二点。
有时候这要看个人喜好。有些时候你需要数据库特定的功能,而ORM(对象关系映射)做不到,这时候你就应该使用 Session(<sql here>).execute()
或者 conn.execute(<sql here>)
。还有一种情况是,当你有一个非常复杂的查询,超出了你的理解范围,而你又找不到合适的ORM表达方式。
通常来说,使用ORM的功能,比如 select([...]).where(...
或者 Session.query(<Model here>).filter(...
(声明式基础)就足够了。几乎每个SQL查询都有对应的ORM写法。
- 你提供的代码不完整,还有错误。所以我们没法确定这里的
Location
到底是什么。我猜它是一个映射类,也就是说你是在请求所有Location
的对象,而不是行。当你打印一个对象时,你得到的是它的字符串表示。对象的字符串表示可以通过定义自定义的__str__
方法来改变。 - 虽然ORM是SQLAlchemy中最重要的部分,但它并不是唯一的部分。SQLAlchemy还提供了很多与ORM没有直接关系的功能。当你处理对象时,创建查询的首选方式是使用相应的会话方法。但有时候你需要一些不绑定到特定会话的可选择对象(这些对象不会直接执行,而是用于传递给会话方法的表达式)。这就是为什么在
sqlalchemy.orm
包中有一些函数。