📜  SQLAlchemy – 映射表列

📅  最后修改于: 2022-05-13 01:55:42.552000             🧑  作者: Mango

SQLAlchemy – 映射表列

在本文中,我们将看到如何在Python中使用 SQLAlchemy 映射表列。

您将需要一个数据库(MySQL、PostgreSQL、SQLite 等)才能使用。由于我们将在这篇文章中使用 MySQL,因此我们还将在Python中为 MySQL 安装 SQL 连接器。但是,除了 SQL 连接器之外,没有任何代码实现会随着数据库的变化而变化。

pip install pymysql

我们将使用 MySQL 中的示例 sakila 数据库。本文中涉及的所有示例都将使用 sakila 数据库中的 actor 表。如果您没有 sakila 数据库并且想在不安装它的情况下继续阅读本文,那么使用下面提到的链接中的 SQL 脚本来创建所需的模式和参与者表以及记录。

使用的数据库: Sakila 演员表脚本

我们将在下面提到的每个示例中引用相同的 SQL 查询 -

SELECT first_name FROM sakila.actor LIMIT 1;

我们可以在 SQLAlchemy 中映射列的不同方式是——

  • 将列直接映射到属性名称
  • 映射列与属性名称不同
  • 使用反射映射列
  • 使用前缀映射列

将列直接映射到属性名称

在下面的示例中,列映射是通过将每个表列映射为类属性来完成的。每个属性都具有与其所代表的相应表列相同的名称。然后我们在 MySQL 中建立连接到 sakila 数据库的 SQLAlchemy 引擎。然后创建一个会话对象来查询数据库。使用这个会话对象,我们将查询 `actor` 表中的第一条记录。我们通过访问“result”对象的“first_name”属性来获取第一条记录的“first_name”列的值。这表明,actor 表的列映射到 Actor 类的属性。

Python3
import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
  
Base = declarative_base()
  
# MAPPING TABLE ACTOR
class Actor(Base):
  
    __tablename__ = 'actor'
  
    actor_id    = db.Column(db.SmallInteger, autoincrement=True, primary_key=True)
    first_name  = db.Column(db.String(45), nullable=False)
    last_name   = db.Column(db.String(45), nullable=False)
    last_update = db.Column(db.TIMESTAMP, nullable=False)
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
# CREATE A SESSION OBJECT TO INITIATE QUERY IN DATABASE
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
  
# SELECT * FROM sakila.actor LIMIT 1;
result = session.query(Actor).first()
  
# DISPLAY FIRST NAME OF FIRST RECORD IN ACTOR TABLE
print("First Name (Record 1):", result.first_name)


Python3
import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
  
Base = declarative_base()
  
# MAPPING TABLE ACTOR
class Actor(Base):
  
    __tablename__ = 'actor'
  
    id        = db.Column('actor_id', db.SmallInteger, autoincrement=True, 
                          primary_key=True)
    fname     = db.Column('first_name', db.String(45), nullable=False)
    lname     = db.Column('last_name', db.String(45), nullable=False)
    update_on = db.Column('last_update', db.TIMESTAMP, nullable=False)
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
# CREATE A SESSION OBJECT TO INITIATE QUERY IN DATABASE
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
  
# SELECT * FROM sakila.actor LIMIT 1;
result = session.query(Actor).first()
  
# DISPLAY FIRST NAME OF FIRST RECORD IN ACTOR TABLE
print("First Name (Record 1):", result.fname)


Python3
import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
  
Base = declarative_base()
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
class Actor(Base):
    __table__ = db.Table("actor", Base.metadata, autoload_with=engine)
  
# CREATE A SESSION OBJECT TO INITIATE QUERY IN DATABASE
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
  
# SELECT COUNT(*) FROM Table LIMIT 1;
result = session.query(Actor).first()
  
# DISPLAY FIRST NAME OF FIRST RECORD IN ACTOR TABLE
print("First Name (Record 1):", result.first_name)


Python3
import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
  
Base = declarative_base()
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
class Actor(Base):
    __table__ = db.Table("actor", Base.metadata, autoload_with=engine)
    __mapper_args__ = {'column_prefix': '_'}
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
# CREATE A SESSION OBJECT TO INITIATE QUERY IN DATABASE
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
  
# SELECT COUNT(*) FROM Table LIMIT 1;
result = session.query(Actor).first()
  
# DISPLAY FIRST NAME OF FIRST RECORD IN ACTOR TABLE
print("First Name (Record 1):", result._first_name)


输出:

First Name (Record 1): PENELOPE

映射列与属性名称不同

这与第一个示例类似,只是稍作改动。此示例中提到的属性名称与列名称不同。这可以通过在 `Column()` 方法中提供一个附加参数来实现。该方法的第一个参数接受实际的列名,这允许使用不同的属性名来引用这些列。如果我们查看最终的 `print()` 方法,演员表中第一条记录的名字是使用 `fname` 属性引用的,而不是第一个示例中看到的 `first_name` 或实际列名。

Python3

import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
  
Base = declarative_base()
  
# MAPPING TABLE ACTOR
class Actor(Base):
  
    __tablename__ = 'actor'
  
    id        = db.Column('actor_id', db.SmallInteger, autoincrement=True, 
                          primary_key=True)
    fname     = db.Column('first_name', db.String(45), nullable=False)
    lname     = db.Column('last_name', db.String(45), nullable=False)
    update_on = db.Column('last_update', db.TIMESTAMP, nullable=False)
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
# CREATE A SESSION OBJECT TO INITIATE QUERY IN DATABASE
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
  
# SELECT * FROM sakila.actor LIMIT 1;
result = session.query(Actor).first()
  
# DISPLAY FIRST NAME OF FIRST RECORD IN ACTOR TABLE
print("First Name (Record 1):", result.fname)

输出:

First Name (Record 1): PENELOPE

使用反射映射列

在前面的两个示例中,我们需要使用类及其属性将每一列与表显式映射。在这种方法中,我们不需要单独提供每个表列的这种显式映射。使用反射,此任务通过提供元数据对象和 SQLAlchemy 引擎连接自动完成。在 `__table__` 属性中。然后,我们可以使用引擎和会话对象来查询参与者表以获取名字,就像在前面的示例中所做的那样,使用列名“first_name”作为属性名本身。

Python3

import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
  
Base = declarative_base()
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
class Actor(Base):
    __table__ = db.Table("actor", Base.metadata, autoload_with=engine)
  
# CREATE A SESSION OBJECT TO INITIATE QUERY IN DATABASE
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
  
# SELECT COUNT(*) FROM Table LIMIT 1;
result = session.query(Actor).first()
  
# DISPLAY FIRST NAME OF FIRST RECORD IN ACTOR TABLE
print("First Name (Record 1):", result.first_name)

输出:

First Name (Record 1): PENELOPE

使用前缀映射列

前缀的使用很少见,但仍然可以在某些用例中找到。在这个例子中,可以看出我们使用了一个额外的属性`__mapper_args__`,它是一个Python字典。它提供了一个作为“column_prefix”的键和一个“_”的值。这意味着我们要在所有列名或属性名前加上下划线。出于这个原因,我们使用 `_first_name` 而不是 `first_name` 作为相应列的属性。

Python3

import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
  
Base = declarative_base()
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
class Actor(Base):
    __table__ = db.Table("actor", Base.metadata, autoload_with=engine)
    __mapper_args__ = {'column_prefix': '_'}
  
# DEFINE THE ENGINE (CONNECTION OBJECT)
engine = db.create_engine("mysql+pymysql://root:password@localhost/sakila")
  
# CREATE A SESSION OBJECT TO INITIATE QUERY IN DATABASE
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
  
# SELECT COUNT(*) FROM Table LIMIT 1;
result = session.query(Actor).first()
  
# DISPLAY FIRST NAME OF FIRST RECORD IN ACTOR TABLE
print("First Name (Record 1):", result._first_name)

输出:

First Name (Record 1): PENELOPE