一、对象映射关系(ORM)

orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言

优点:

  • 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来
  • ORM使我们构造固化数据结构变得简单易行

缺点:

  • 无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的

二、SQLAlchemy

在Python中,最有名的ORM框架是SQLAlchemy。用户包括openstack\Dropbox等知名公司或应用

Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:

MySQL-Python MySQLdb模块
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql
mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector
mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle
oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.html

注:支持连接MySQL、Oracles数据库

安装:

pip install SQLAlchemy
pip install pymysql
#由于mysqldb依然不支持py3,所以这里我们用pymysql与sqlalchemy交互

windows下python2.7环境MySQLdb模块安装

官网http://www.codegood.com/downloads下载  MySQL-python-1.2.3.win32-py2.7.exe文件
下载完成后本地安装
执行命令pip install MySQL-python完成,本地import MySQLdb

1、基本使用

查看mysql基础知识移步-》》http://www.cnblogs.com/lianzhilei/p/5993282.html

下面就开始让你见证orm的nb之处,盘古开天劈地之前,我们创建一个表是这样的:

CREATE TABLE user (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(32),
password VARCHAR(64),
PRIMARY KEY (id)
)

这只是最简单的sql表,如果再加上外键关联什么的,一般程序员的脑容量是记不住那些sql语句的,于是有了orm,实现上面同样的功能,代码如下:

# 创建表结构

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,Integer,String engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8",echo=True) #echo=True 打印程序运行详细信息 Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) Base.metadata.create_all(engine) #创建表结构 # 打印输出
# 2016-10-26 08:42:02,619 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
# 2016-10-26 08:42:02,619 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,622 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
# 2016-10-26 08:42:02,622 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,624 INFO sqlalchemy.engine.base.Engine show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin'
# 2016-10-26 08:42:02,624 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,649 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
# 2016-10-26 08:42:02,649 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,651 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
# 2016-10-26 08:42:02,651 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,652 INFO sqlalchemy.engine.base.Engine SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8)
# COLLATE utf8_bin AS anon_1
# 2016-10-26 08:42:02,652 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,655 INFO sqlalchemy.engine.base.Engine DESCRIBE `user`
# 2016-10-26 08:42:02,655 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,657 INFO sqlalchemy.engine.base.Engine ROLLBACK
# 2016-10-26 08:42:02,660 INFO sqlalchemy.engine.base.Engine
# CREATE TABLE user (
# id INTEGER NOT NULL AUTO_INCREMENT,
# name VARCHAR(32),
# password VARCHAR(64),
# PRIMARY KEY (id)
# )
#
#
# 2016-10-26 08:42:02,660 INFO sqlalchemy.engine.base.Engine {}
# 2016-10-26 08:42:02,904 INFO sqlalchemy.engine.base.Engine COMMIT

查询表结构:

mysql> desc user;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(32) | YES | | NULL | |
| password | varchar(64) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec) 

你说,娘那个腚的,并没有感觉代码量变少啊,呵呵, 孩子莫猴急,好戏在后面

除上面的创建之外,还有一种创建表的方式,虽不常用,但还是看看吧

from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey
from sqlalchemy.orm import mapper metadata = MetaData() user = Table('user', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(50)),
Column('fullname', String(50)),
Column('password', String(12))
) class User(object):
def __init__(self, name, fullname, password):
self.name = name
self.fullname = fullname
self.password = password mapper(User, user) #the table metadata is created separately with the Table construct, then associated with the User class via the mapper() function

另一种方式

2、创建数据

最基本的表我们创建好了,那我们开始用orm创建一条数据试试

# 创建表数据

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) #Base.metadata.create_all(engine) #创建表结构 Session_class = sessionmaker(bind=engine) #Session_class现在不是实例,而是类
Session = Session_class() #生成Session实例 user_obj = User(name="lzl",password="123456") #生成你要创建的数据对象
print(user_obj.name,user_obj.id) #此时还没创建对象呢,不信你打印一下id发现还是None Session.add(user_obj) #把要创建的数据对象添加到这个session里, 一会统一创建
print(user_obj.name,user_obj.id) #此时也依然还没创建 Session.commit() #现此才统一提交,创建数据 # lzl None
# lzl None

我擦,写这么多代码才创建一条数据,你表示太tm的费劲了,正要转身离开,我拉住你的手不放开,高潮快来了。。

3、查询数据

# 查询

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) Session_class = sessionmaker(bind=engine) #Session_class现在不是实例,而是类
Session = Session_class() #生成Session实例 my_user = Session.query(User).filter_by(name="lzl").first()
print(my_user) #my_user此时是一个对象
#<__main__.User object at 0x03EFC6D0> print(my_user.id,my_user.name,my_user.password)
# 1 lzl 123456

不过刚才上面的显示的内存对象对址你是没办法分清返回的是什么数据的,除非打印具体字段看一下,如果想让它变的可读,只需在定义表的类下面加上这样的代码:

def __repr__(self):
  return "<User(name='%s', password='%s')>" % (
  self.name, self.password) print(my_user)
#<User(name='lzl', password='123456')>

获取所有数据:

#当前数据表信息

mysql> select * from user;
+----+------------+----------+
| id | name | password |
+----+------------+----------+
| 1 | lianzhilei | 123456 |
| 2 | lzl | 123456 |
| 3 | lzl | 123456 |
| 6 | alex | 34567 |
| 7 | alex | 34567 |
| 8 | wupeiqi | 33422 |
+----+------------+----------+
6 rows in set (0.00 sec) print(Session.query(User.name,User.id).all() )
# [('lianzhilei', 1), ('lzl', 2), ('lzl', 3), ('alex', 6), ('alex', 7), ('wupeiqi', 8)]

多条件查询:

# 多条件查询

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker
from sqlalchemy import func engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) def __repr__(self):
return "<User(name='%s', password='%s')>" % (
self.name, self.password) Session_class = sessionmaker(bind=engine) #Session_class现在不是实例,而是类
Session = Session_class() #生成Session实例 objs = Session.query(User).filter(User.id>3).filter(User.id<8).all()
print(objs)
# [<User(name='alex', password='34567')>, <User(name='alex', password='34567')>]

统计:

# 统计

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker
from sqlalchemy import func engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) def __repr__(self):
return "<User(name='%s', password='%s')>" % (
self.name, self.password) Session_class = sessionmaker(bind=engine) #Session_class现在不是实例,而是类
Session = Session_class() #生成Session实例 print(Session.query(User).filter(User.name.like("l%")).count())
#3

分组:

# 分组

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker
from sqlalchemy import func engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) def __repr__(self):
return "<User(name='%s', password='%s')>" % (
self.name, self.password) Session_class = sessionmaker(bind=engine) #Session_class现在不是实例,而是类
Session = Session_class() #生成Session实例 print(Session.query(func.count(User.name),User.name).group_by(User.name).all())
#[(2, 'alex'), (1, 'lianzhilei'), (2, 'lzl'), (1, 'wupeiqi')]

相当于原生sql为

SELECT count(user.name) AS count_1, user.name AS user_name
FROM user GROUP BY user.name

4、修改

# 修改

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) def __str__(self):
return "<User(name='%s', password='%s')>" % (
self.name, self.password) Session_class = sessionmaker(bind=engine) #Session_class现在不是实例,而是类
Session = Session_class() #生成Session实例 my_user = Session.query(User).filter_by(name="lzl").first()
print(my_user)
#<User(name='lzl', password='123456')> my_user.name = "lianzhilei" Session.commit() #提交数据 mysql> select * from user;
+----+------------+----------+
| id | name | password |
+----+------------+----------+
| 1 | lianzhilei | 123456 |
| 2 | lzl | 123456 |
| 3 | lzl | 123456 |
+----+------------+----------+
3 rows in set (0.00 sec)

5、回滚

# 回滚

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #生成orm基类 class User(Base):
__tablename__ = "user" #表名
id = Column(Integer,primary_key=True)
name = Column(String(32))
password = Column(String(64)) def __repr__(self):
return "<User(name='%s', password='%s')>" % (
self.name, self.password) Session_class = sessionmaker(bind=engine) #Session_class现在不是实例,而是类
Session = Session_class() #生成Session实例 my_user = Session.query(User).filter_by(id = 1).first()
my_user.name = "Jack"
print(my_user)
# <User(name='Jack', password='123456')> Rain_user = User(name="Rain",password="12345")
Session.add(Rain_user)
print(Session.query(User).filter(User.name.in_(["Jack","Rain"])).all()) # 这时看session里有你刚添加和修改的数据
#[<User(name='Jack', password='123456')>, <User(name='Rain', password='12345')>] Session.rollback() print(Session.query(User).filter(User.name.in_(["Jack","Rain"])).all()) #再查就发现刚才添加的数据没有了。
#[]

 6、外键关联

我们先创建个study_record表与student进行关联

# 外键关联

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Column,Integer,ForeignKey,DATE
from sqlalchemy.orm import sessionmaker,relationship engine = create_engine("mysql+pymysql://root:zyw@123@192.168.0.59/lzl",
encoding="utf-8") Base = declarative_base() class Student(Base):
__tablename__ ="student"
id = Column(Integer,primary_key=True)
name = Column(String(32),nullable=False)
register_date = Column(DATE,nullable=False) def __repr__(self):
return "<%s name:%s>"%(self.id,self.name) class StudyRecord(Base):
__tablename__ = "study_record"
id = Column(Integer,primary_key=True)
day = Column(Integer,nullable=False)
status = Column(String(32),nullable=False)
stu_id = Column(Integer,ForeignKey("student.id")) #关联student表里的id my_student = relationship("Student",backref="my_study_record") # Student为关联的类
    def __repr__(self):
return "<%s name:%s>" % (self.id, self.name) Base.metadata.create_all(engine) Session_class = sessionmaker(bind=engine)
session = Session_class() s1 = Student(name="lzl",register_date="2016-10-26")
s2 = Student(name="alex",register_date="2015-10-26")
s3 = Student(name="eric",register_date="2014-10-26")
s4 = Student(name="rain",register_date="2013-10-26") r1 = StudyRecord(day=1,status="YES",stu_id=1)
r2 = StudyRecord(day=2,status="No",stu_id=1)
r3 = StudyRecord(day=3,status="YES",stu_id=1)
r4 = StudyRecord(day=1,status="YES",stu_id=2) session.add_all([s1,s2,s3,s4,r1,r2,r3,r4])
session.commit()

注:my_student = relationship("Student",backref="my_study_record")这个nb,允许你在user表里通过backref字段反向查出所有它在addresses表里的关联项

查询:

# 外键查询

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Column,Integer,ForeignKey,DATE
from sqlalchemy.orm import sessionmaker,relationship engine = create_engine("mysql+pymysql://root:zyw@123@192.168.0.59/lzl",
encoding="utf-8") Base = declarative_base() class Student(Base):
__tablename__ ="student"
id = Column(Integer,primary_key=True)
name = Column(String(32),nullable=False)
register_date = Column(DATE,nullable=False) def __repr__(self):
return "<id:%s name:%s>"%(self.id,self.name) class StudyRecord(Base):
__tablename__ = "study_record"
id = Column(Integer,primary_key=True)
day = Column(Integer,nullable=False)
status = Column(String(32),nullable=False)
stu_id = Column(Integer,ForeignKey("student.id")) #关联student表里的id my_student = relationship("Student",backref="my_study_record") # Student为关联的类 def __repr__(self):
return "<name:%s day:%s status:%s>" % (self.my_student.name,self.day,self.status) Base.metadata.create_all(engine) Session_class = sessionmaker(bind=engine)
session = Session_class() stu_obj = session.query(Student).filter(Student.name=="lzl").first()
print(stu_obj)
#<id:1 name:lzl> print(stu_obj.my_study_record)
#[<name:lzl day:1 status:YES>, <name:lzl day:2 status:No>, <name:lzl day:3 status:YES>]

  

 7、多外键关联

下表中,Customer表有2个字段都关联了Address表,首先先创建表结构

# 多外键关联

from sqlalchemy import create_engine
from sqlalchemy import Integer,String,Column,ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker,relationship engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8",echo= True) Base = declarative_base() class Customer(Base):
__tablename__ = "customer"
id = Column(Integer,primary_key=True)
name = Column(String(32))
billing_address_id = Column(Integer,ForeignKey("address.id"))
shipping_address_id = Column(Integer, ForeignKey("address.id")) billing_address = relationship("Address",foreign_keys=[billing_address_id]) #必须写foreign_keys
shipping_address = relationship("Address",foreign_keys=[shipping_address_id]) class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
street = Column(String(32))
city = Column(String(32))
state = Column(String(32)) Base.metadata.create_all(engine) mysql> desc address;
+--------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| street | varchar(32) | YES | | NULL | |
| city | varchar(32) | YES | | NULL | |
| state | varchar(32) | YES | | NULL | |
+--------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec) mysql> desc customer;
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(32) | YES | | NULL | |
| billing_address_id | int(11) | YES | MUL | NULL | |
| shipping_address_id | int(11) | YES | MUL | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

生成数据:

Session = sessionmaker(bind=engine)
session = Session() a1 = Address(street="Tiantongyuan",city="ChangPing",state="BJ")
a2 = Address(street="Wudaokou",city="HaiDian",state="BJ")
a3 = Address(street="Yanjiao",city="LangFang",state="HB") session.add_all([a1,a2,a3])
c1 = Customer(name="lzl",billing_address_id=1,shipping_address_id=2)
c2 = Customer(name="Alex",billing_address_id=3,shipping_address_id=3) session.add_all([c1,c2]) session.commit()

查询数据:

class Customer(Base):
__tablename__ = "customer"
id = Column(Integer,primary_key=True)
name = Column(String(32))
billing_address_id = Column(Integer,ForeignKey("address.id"))
shipping_address_id = Column(Integer, ForeignKey("address.id")) billing_address = relationship("Address",foreign_keys=[billing_address_id]) #必须写foreign_keys
shipping_address = relationship("Address",foreign_keys=[shipping_address_id]) def __repr__(self):
return "<name:%s billing_add:%s shipping_add:%s>"%(self.name,self.billing_address.street,
self.shipping_address.street) #Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session() cus_obj = session.query(Customer).filter_by(name="lzl").first()
print(cus_obj)
# <name:lzl billing_add:Tiantongyuan shipping_add:Wudaokou>

  

 8、多对多关联

现在来设计一个能描述“图书”与“作者”的关系的表结构,需求是

  1. 一本书可以有好几个作者一起出版
  2. 一个作者可以写好几本书

创建表结构:

#一本书可以有多个作者,一个作者又可以出版多本书

from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
encoding="utf-8") Base = declarative_base() #创建book_m2m_author表,表不用用户操作,系统自动维护,自动添加数据
book_m2m_author = Table('book_m2m_author', Base.metadata,
Column('book_id',Integer,ForeignKey('books.id')),
Column('author_id',Integer,ForeignKey('authors.id')),
) class Book(Base):
__tablename__ = 'books'
id = Column(Integer,primary_key=True)
name = Column(String(64))
pub_date = Column(DATE)
#关联Author类,secondary表示通过book_m2m_author表进行查询关联数据,backref反向查询也一样
authors = relationship('Author',secondary=book_m2m_author,backref='books') def __repr__(self):
return self.name class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True)
name = Column(String(32)) def __repr__(self):
return self.name Base.metadata.create_all(engine)

创建表数据: 

#创建数据

Session = sessionmaker(bind=engine)
session = Session() b1 = Book(name="learn python with Alex",pub_date="2014-05-02")
b2 = Book(name="learn linux with Alex",pub_date="2015-05-02")
b3 = Book(name="learn go with Alex",pub_date="2016-05-02") a1 = Author(name="Alex")
a2 = Author(name="Jack")
a3 = Author(name="Rain") #关键来了,创建关联关系
b1.authors = [a1,a3]
b3.authors = [a1,a2,a3] session.add_all([b1,b2,b3,a1,a2,a3])
session.commit() mysql> select * from book_m2m_author;
+---------+-----------+
| book_id | author_id |
+---------+-----------+
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
| 1 | 3 |
| 2 | 3 |
+---------+-----------+
5 rows in set (0.00 sec) mysql> select * from authors;
+----+------+
| id | name |
+----+------+
| 1 | Alex |
| 2 | Jack |
| 3 | Rain |
+----+------+
3 rows in set (0.00 sec) mysql> select * from books;
+----+------------------------+------------+
| id | name | pub_date |
+----+------------------------+------------+
| 1 | learn python with Alex | 2014-05-02 |
| 2 | learn go with Alex | 2016-05-02 |
| 3 | learn linux with Alex | 2015-05-02 |
+----+------------------------+------------+
3 rows in set (0.00 sec)

查询:

author_obj = session.query(Author).filter_by(name="Alex").first()
print(author_obj,author_obj.books) book_obj = session.query(Book).filter_by(id=2).first()
print(book_obj,book_obj.authors) # Alex [learn python with Alex, learn go with Alex]
# learn go with Alex [Alex, Jack, Rain]

  

9、多对多删除

删除数据时不用管boo_m2m_authors , sqlalchemy会自动帮你把对应的数据删除

通过书删除作者

author_obj =s.query(Author).filter_by(name="Jack").first()

book_obj = s.query(Book).filter_by(name="跟Alex学把妹").first()

book_obj.authors.remove(author_obj) #从一本书里删除一个作者
s.commit()

直接删除作者 

删除作者时,会把这个作者跟所有书的关联关系数据也自动删除

author_obj =s.query(Author).filter_by(name="Alex").first()
# print(author_obj.name , author_obj.books)
s.delete(author_obj)
s.commit()

10、中文

engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl?charset=utf8")

#修改查看数据库字符编码
mysql> alter database lzl character set utf8;
Query OK, 1 row affected (0.00 sec) mysql> show variables like 'character_set_database';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| character_set_database | utf8 |

Python开发【模块】:sqlalchemy的更多相关文章

  1. python开发模块基础:re正则

    一,re模块的用法 #findall #直接返回一个列表 #正常的正则表达式 #但是只会把分组里的显示出来#search #返回一个对象 .group()#match #返回一个对象 .group() ...

  2. python开发模块基础:异常处理&hashlib&logging&configparser

    一,异常处理 # 异常处理代码 try: f = open('file', 'w') except ValueError: print('请输入一个数字') except Exception as e ...

  3. python开发模块基础:os&sys

    一,os模块 os模块是与操作系统交互的一个接口 #!/usr/bin/env python #_*_coding:utf-8_*_ ''' os.walk() 显示目录下所有文件和子目录以元祖的形式 ...

  4. python开发模块基础:序列化模块json,pickle,shelve

    一,为什么要序列化 # 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化'''比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给?现在我们能想到的方法就是存在文 ...

  5. python开发模块基础:time&random

    一,time模块 和时间有关系的我们就要用到时间模块.在使用模块之前,应该首先导入这个模块 常用方法1.(线程)推迟指定的时间运行.单位为秒. time.sleep(1) #括号内为整数 2.获取当前 ...

  6. python开发模块基础:collections模块&paramiko模块

    一,collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdic ...

  7. python ORM模块sqlalchemy的使用

    1.安装sqlalchemy pip install sqlalchemy 2.导入必要的包及模块 import sqlalchemy from sqlalchemy.ext.declarative ...

  8. python开发模块基础:正则表达式

    一,正则表达式 1.字符组:[0-9][a-z][A-Z] 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示字符分为很多类,比如数字.字母.标点等等.假如你现在要求一个位置&q ...

  9. Python开发——目录

    Python基础 Python开发——解释器安装 Python开发——基础 Python开发——变量 Python开发——[选择]语句 Python开发——[循环]语句 Python开发——数据类型[ ...

  10. python开发_常用的python模块及安装方法

    adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheetahcherrypy:一个WEB frameworkctype ...

随机推荐

  1. WAMP环境下配置虚拟主机

    1.编辑httpd.conf,查找#Include conf/extra/httpd-vhosts.conf,把前面注释符号“#”删掉 2.编辑httpd-vhosts.conf文件, <Vir ...

  2. PL/SQL developer(绿色版)安装及配置

    1.PL/SQL Developer下载地址:百度网盘: 2.tsname.ora配置: orcl = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS )) ) (CO ...

  3. ie8下修改input的type属性报错

    摘要: 现在有一个需求如图所示,当用户勾选显示明文复选框时,要以明文显示用户输入的密码,去掉勾选时要变回密文,刚开始想到的就是修改输入框的type来决定显示明文还是密文,使用jQuery的attr来做 ...

  4. [spring] 对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾

    org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 26 in XML document from ...

  5. 使用 MVVMLight 消息通知

    欢迎阅读我的MVVMLight教程系列文章<关于 MVVMLight 设计模式系列> 在文章的其实我们就说了,MVVMLight的精华就是消息通知机制,设计的非常不错.这个东西在MVVML ...

  6. GIS-ArcGIS 数据库备份还原

    Create directory sdebak as 'E:\10_DataFile'; alter system set deferred_segment_creation=false; ALTER ...

  7. laravel框架容器管理的一些要点

    本文面向php语言的laravel框架的用户,介绍一些laravel框架里面容器管理方面的使用要点.文章很长,但是内容应该很有用,希望有需要的朋友能看到.php经验有限,不到位的地方,欢迎帮忙指正. ...

  8. mac 操作idea快捷键

    http://blog.csdn.net/rainytooo/article/details/51469126 在mac下idea的常用快捷键如下,下面的快捷键都亲自试用,并有一些和eclipse对比 ...

  9. linux系统socket通信编程详解函数

    linux socket编程之TCP与UDP   TCP与UDP区别 TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之 ...

  10. 关于KEIL仿真的虚拟串口讲解

    这个是最后的效果图,右下方是串口打印的设置 第一步:在程序上写入关于串口一的配置,以及初始化和串口输出的内容 第二步:需要的时候在进行配置,在OPTIONS OF TARGET一栏的c/c++中(其原 ...