SQLAlchemy是一个对象关系映射工具,或者说ORM,它允许开发者以更多的Pythonic方式来处理数据库。像SQLAlchemy这样的工具让你用Python甚至不同的语言代替SQL来查询和操作数据库中的数据。Python有许多ORM库,你可以使用SQLAlchemy,它是关系型数据库中最流行的库之一。SQLAlchemy还可以与许多网络框架一起使用,包括flask和数据库,如SQLite、MySQL和Postgres。现在让我们来了解一下关于SQLAlchemy的情况。
为什么使用SQLAlchemy?
一些程序员宁愿用Pure Python编写数据库交互,而不是原始SQL。Python开发者可以使用他们熟悉的语言与数据库交互,并对数据库系统进行抽象。这可以加快开发速度,特别是在项目的早期阶段。一些程序员可能不介意在不同的语言之间切换,但使用单一的语言来启动和运行第一个原型可能会更容易。非常擅长SQL的程序员可能会用SQL写出比抽象的ORM更有性能的查询。另一方面,如果你不精通SQL,那么像SQLAlchemy这样的工具可以为你提供完全可用的查询性能,开箱即用。使用ORM将数据库的复杂性转移到应用程序代码中,而不是将其保留在自己的系统中。你仍然需要至少了解基本的SQL,但由于ORM简化了数据层的工作,许多开发人员选择使用它。
安装SQLAlchemy
SQLalchemy是一个独立于Python基础安装的库,所以为了使用它,我们首先需要安装它。安装很简单,我们只需要在命令行中输入pip install sqlalchemy,你会看到一些像这样的输出。
python $pip install sqlalchemy
Collecting sqlalchemy
Downloading SQLAlchemy-1.4.9-cp39-cp39-win_amd64.whl (1.5 MB)
|████████████████████████████████| 1.5 MB 328 kB/s
Collecting greenlet!=0.4.17
Downloading greenlet-1.0.0-cp39-cp39-win_amd64.whl (95 kB)
|████████████████████████████████| 95 kB 830 kB/s
Installing collected packages: greenlet, sqlalchemy
Successfully installed greenlet-1.0.0 sqlalchemy-1.4.9
SQLAlchemy核心(SQL表达式语言)
SQLAlchemy Core有一个以模式为中心的观点,关注于表、键和SQL概念。SQLAlchemy Core也被称为SQL表达式语言。SQL表达式语言是一种创建SQL语句和表达式的Pythonic方式,与完整的ORM模型相比,它使用的抽象程度较低。它专注于实际的数据库模式,并以一种标准化的方式,在许多不同的后台数据库中提供一致的语言。
导入SQLalchemy
这里的代码导入了SQLalchemy库并将其别名为db变量。
import sqlalchemy as db
创建引擎
我们要做的第一件事是调用**create_engine()**函数,输入我们要连接的数据库的名称。我们将把这个函数的结果保存在一个叫做引擎的变量中。引擎允许你的应用程序有多个数据库连接,并且它为你管理这些连接。
engine = db.create_engine('sqlite:///cars.db')
连接到数据库
为了建立与数据库的连接,我们可以使用**connect()**函数并将结果保存在一个名为connection的变量中。这个连接是真正的Python数据库API连接的一个代理。
connection = engine.connect()
将表加载到SQLAlchemy中
要将一个表加载到SQLalchemy中,我们可以使用**Table()**函数。这个函数接收表的名称、数据库元数据、自动加载设置和我们已经创建的引擎。
metadata = db.MetaData()
cars = db.Table('cars', metadata, autoload=True, autoload_with=engine)
构建一个查询
我们现在可以使用存储在carls变量中的表来构造一个查询。回顾一下,为了从数据库中获得所有的结果,我们在原始SQL中使用SELECT * FROM cars。在SQLalchemy中,我们可以使用**select()**函数,并传入我们要查询的表。
query = db.select([cars])
执行查询
要实际运行查询,我们需要使用**execute()**函数并传入我们构建的查询。这个函数返回一个结果代理,它代理了来自 Python 数据库 API 的游标对象。
result_proxy = connection.execute(query)
获取数据
最后一步是使用结果代理来调用**fetchall()**函数。这将返回一个结果集,我们可以打印出结果,并注意到这个表中的所有记录都被显示出来。
result_set = result_proxy.fetchall()
print(result_set)
[('Ford', 'Mustang Mach E', 2022), ('Tesla', 'Model 3', 2020), ('Kia', 'Niro EV', 2022), ('Porsche', 'Taycan 4S', 2021)]
添加where()
大多数时候,你想获得符合给定条件的数据。我们可以在SQLalchemy中使用**where()**函数做到这一点。让我们通过连锁调用where()重写现有的select()查询。例如,让我们找到数据库中所有年份为2022年的汽车。
import sqlalchemy as db
engine = db.create_engine('sqlite:///cars.db')
connection = engine.connect()
metadata = db.MetaData()
cars = db.Table('cars', metadata, autoload=True, autoload_with=engine)
query = db.select([cars]).where(cars.columns.year == 2022)
result_proxy = connection.execute(query)
result_set = result_proxy.fetchall()
print(result_set)
[('Ford', 'Mustang Mach E', 2022), ('Kia', 'Niro EV', 2022)]
插入到SQLalchemy中
要使用SQLalchemy向数据库插入一条记录,我们可以使用insert()函数。这里我们设置了查询,然后使用连接对象来执行查询。
query = cars.insert().values(make="Kia", model="Telluride", year="2021")
connection.execute(query)
如果我们再次选择所有记录,我们可以看到数据库中的新条目。
import sqlalchemy as db
engine = db.create_engine('sqlite:///cars.db')
connection = engine.connect()
metadata = db.MetaData()
cars = db.Table('cars', metadata, autoload=True, autoload_with=engine)
query = db.select([cars])
result_proxy = connection.execute(query)
result_set = result_proxy.fetchall()
print(result_set)
[('Ford', 'Mustang Mach E', 2022), ('Tesla', 'Model 3', 2020), ('Kia', 'Niro EV', 2022), ('Porsche', 'Taycan 4S', 2021), ('Kia', 'Telluride', 2021)]
在SQLalchemy中创建数据库
在这一节中,让我们创建一个名为users.db的新数据库。我们可以在这里看到如何创建一个新的数据库和表。
import sqlalchemy as db
engine = db.create_engine('sqlite:///users.db')
metadata = db.MetaData()
connection = engine.connect()
users = db.Table('Users', metadata,
db.Column('user_id', db.Integer, primary_key=True),
db.Column('first_name', db.Text),
db.Column('last_name', db.Text),
db.Column('email_address', db.Text))
metadata.create_all(engine)
SQLalchemy批量插入
现在我们可以通过传入一个要插入数据库的对象列表来同时插入多条记录。
insert_query = users.insert().values([
{"first_name": "Bob", "last_name": "Jones", "email_address": "bjones@notrealemail.com"},
{"first_name": "Jack", "last_name": "Erich", "email_address": "jerich@notrealemail.com"},
{"first_name": "Rick", "last_name": "Stein", "email_address": "rstein@notrealemail.com"},
{"first_name": "Sally", "last_name": "Green", "email_address": "sgreen@notrealemail.com"}
])
connection.execute(insert_query)
使用列进行选择
最后,我们可以再次从数据库中获取所有记录,只选择每个记录的第一个名字。
select_query = db.select([users.columns.first_name])
query_result = connection.execute(select_query)
for person in query_result:
print(person[0])
Bob
Jack
Rick
Sally
