众所周知,直接明文写sql操作数据库有很多不安全的地方。

借助一个SQLAlchemy的工具来进行python对象和数据库数据的映射,这样达到操作python对象即可改变数据库的数据。

1 创建数据库

-- This is the file to create COMPANY table and to populate it with 7 records.
-- Just copy and past them on psql prompt.
DROP TABLE learn.COMPANY;
CREATE TABLE learn.COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);
INSERT INTO learn.COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );

INSERT INTO learn.COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Allen', 25, 'Texas', 15000.00 );

INSERT INTO learn.COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );

INSERT INTO learn.COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );

INSERT INTO learn.COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (5, 'David', 27, 'Texas', 85000.00 );

INSERT INTO learn.COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );

INSERT INTO learn.COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );

2 基础使用

SQLAchemy的基础步骤为:

  • 1 创建python对象和数据库表的映射(需要每一个column的对应关系),注意tablename和table_args。
  • 2 创建session对象
    • 2.1 创建引擎
    • 2.2 绑定引擎到Sessionmaker
    • 2.3 创建session
  • 3 增删改查

我们首先查看一下数据库的数据。

我们先查询salary高于15000的人员:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine, Column, Integer, String

Base = declarative_base()


class Company(Base):
    __tablename__ = 'company'
    __table_args__ = ({"schema": "learn"},)
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)
    address = Column(String)
    salary = Column(Integer)


engine = create_engine('postgresql+psycopg2://postgres:root@localhost:5432/crabboss')
DBSession = sessionmaker(bind=engine)
session = DBSession()
companies = session.query(Company).filter(Company.salary > 15000).all()
for company in companies:
    print(f"id : {company.id:1} | name: {company.name:2} | age: {company.age:1} | address: {company.address:10} | salary: {company.salary:10}")
session.close()

代码执行结果:

3 增

此处我们没有设置主线为SERIAL,故手工将id设置为8.

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine, Column, Integer, String

Base = declarative_base()


class Company(Base):
    __tablename__ = 'company'
    __table_args__ = ({"schema": "learn"},)
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String)
    age = Column(Integer)
    address = Column(String)
    salary = Column(Integer)


engine = create_engine('postgresql+psycopg2://postgres:root@localhost:5432/crabboss')
DBSession = sessionmaker(bind=engine)
session = DBSession()

# 插入
new_user = Company(id=8, name="Tom", age=20, address="San Francisco", salary=30000)
session.add(new_user)
session.commit()

# 查询
companies = session.query(Company).filter(Company.salary > 15000).all()
for company in companies:
    print(f"id : {company.id:1} | name: {company.name:2} | age: {company.age:1} | address: {company.address:10} | salary: {company.salary:10}")
session.close()

结果如下:

4 删

先进行查询,之后删除。

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine, Column, Integer, String

Base = declarative_base()


class Company(Base):
    __tablename__ = 'company'
    __table_args__ = ({"schema": "learn"},)
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String)
    age = Column(Integer)
    address = Column(String)
    salary = Column(Integer)


engine = create_engine('postgresql+psycopg2://postgres:root@localhost:5432/crabboss')
DBSession = sessionmaker(bind=engine)
session = DBSession()

# 插入
# new_user = Company(id=8, name="Tom", age=20, address="San Francisco", salary=30000)
# session.add(new_user)
# session.commit()

# 删除
session.query(Company).filter(Company.name=="Tom").delete()
session.commit()

# 查询
companies = session.query(Company).filter(Company.salary > 15000).all()
for company in companies:
    print(f"id : {company.id:1} | name: {company.name:2} | age: {company.age:1} | address: {company.address:10} | salary: {company.salary:10}")
session.close()

结果如下:

5 改

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine, Column, Integer, String

Base = declarative_base()


class Company(Base):
    __tablename__ = 'company'
    __table_args__ = ({"schema": "learn"},)
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String)
    age = Column(Integer)
    address = Column(String)
    salary = Column(Integer)


engine = create_engine('postgresql+psycopg2://postgres:root@localhost:5432/crabboss')
DBSession = sessionmaker(bind=engine)
session = DBSession()

# 插入
# new_user = Company(id=8, name="Tom", age=20, address="San Francisco", salary=30000)
# session.add(new_user)
# session.commit()

# 删除
# session.query(Company).filter(Company.name=="Tom").delete()
# session.commit()

# 修改
session.query(Company).filter(Company.name=="Paul").update({"salary":30000})
session.commit()

# 查询
companies = session.query(Company).filter(Company.salary > 15000).all()
for company in companies:
    print(f"id : {company.id:1} | name: {company.name:2} | age: {company.age:1} | address: {company.address:10} | salary: {company.salary:10}")
session.close()

修改后结果如下:

6 参考文献