精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Python數據庫ORM工具sqlalchemy的學習筆記

開發 前端
SQLAlchemy是python的一個數據庫ORM工具,提供了強大的對象模型間的轉換,可以滿足絕大多數數據庫操作的需求,并且支持多種數據庫引擎(sqlite,mysql,postgres, mongodb等),在這里記錄基本用法和學習筆記。

SQLAlchemy是python的一個數據庫ORM工具,提供了強大的對象模型間的轉換,可以滿足絕大多數數據庫操作的需求,并且支持多種數據庫引擎(sqlite,mysql,postgres, mongodb等),在這里記錄基本用法和學習筆記。

一、安裝

通過pip安裝

  1. $ pip install SQLAlchemy 

二、使用

首先是連接到數據庫,SQLALchemy支持多個數據庫引擎,不同的數據庫引擎連接字符串不一樣,常用的有

  1. mysql://username:password@hostname/database 
  2. postgresql://username:password@hostname/database 
  3. sqlite:////absolute/path/to/database 
  4. sqlite:///c:/absolute/path/to/database 

 更多連接字符串的介紹參見這里

下面是連接和使用sqlite數據庫的例子

1. connection

使用傳統的connection的方式連接和操作數據庫

  1. from sqlalchemy import create_engine 
  2.  
  3. # 數據庫連接字符串 
  4. DB_CONNECT_STRING = 'sqlite:///:memory:' 
  5.  
  6. # 創建數據庫引擎,echo為True,會打印所有的sql語句 
  7. engine = create_engine(DB_CONNECT_STRING, echo=True
  8.  
  9. # 創建一個connection,這里的使用方式與python自帶的sqlite的使用方式類似 
  10. with engine.connect() as con: 
  11.     # 執行sql語句,如果是增刪改,則直接生效,不需要commit 
  12.     rs = con.execute('SELECT 5'
  13.     data = rs.fetchone()[0] 
  14.     print "Data: %s" % data 

 與python自帶的sqlite不同,這里不需要Cursor光標,執行sql語句不需要commit

2. connection事務

使用事務可以進行批量提交和回滾 

  1. from sqlalchemy import create_engine 
  2.  
  3. # 數據庫連接字符串 
  4. DB_CONNECT_STRING = 'sqlite:////Users/zhengxiankai/Desktop/Document/db.sqlite' 
  5. engine = create_engine(DB_CONNECT_STRING, echo=True
  6.  
  7. with engine.connect() as connection
  8.     trans = connection.begin() 
  9.     try: 
  10.         r1 = connection.execute("select * from User"
  11.         r2 = connection.execute("insert into User(name, age) values(?, ?)"'bomo', 24) 
  12.         trans.commit() 
  13.     except
  14.         trans.rollback() 
  15.         raise  

3. session

connection是一般使用數據庫的方式,sqlalchemy還提供了另一種操作數據庫的方式,通過session對象,session可以記錄和跟蹤數據的改變,在適當的時候提交,并且支持強大的ORM的功能,下面是基本使用 

  1. from sqlalchemy import create_engine 
  2. from sqlalchemy.orm import sessionmaker 
  3.  
  4. # 數據庫連接字符串 
  5. DB_CONNECT_STRING = 'sqlite:////Users/zhengxiankai/Desktop/Document/db.sqlite' 
  6.  
  7. # 創建數據庫引擎,echo為True,會打印所有的sql語句 
  8. engine = create_engine(DB_CONNECT_STRING, echo=True
  9.  
  10. # 創建會話類 
  11. DB_Session = sessionmaker(bind=engine) 
  12.  
  13. # 創建會話對象 
  14. session = DB_Session() 
  15.  
  16. # dosomething with session 
  17.  
  18. # 用完記得關閉,也可以用with 
  19. session.close()  

上面創建了一個session對象,接下來可以操作數據庫了,session也支持通過sql語句操作數據庫 

  1. session.execute('select * from User'
  2. session.execute("insert into User(name, age) values('bomo', 13)"
  3. session.execute("insert into User(name, age) values(:name, :age)", {'name''bomo''age':12}) 
  4.  
  5. # 如果是增刪改,需要commit 
  6. session.commit()  

注意參數使用dict,并在sql語句中使用:key占位

4. ORM

上面簡單介紹了sql的簡單用法,既然是ORM框架,我們先定義兩個模型類User和Role,sqlalchemy的模型類繼承自一個由declarative_base()方法生成的類,我們先定義一個模塊Models.py生成Base類 

  1. from sqlalchemy.ext.declarative import declarative_base 
  2.  
  3. Base = declarative_base()  

User.py 

  1. from sqlalchemy import ColumnInteger, String 
  2. from Models import Base 
  3.  
  4. class User(Base): 
  5.     __tablename__ = 'User' 
  6.     id = Column('id'Integer, primary_key=True, autoincrement=True
  7.     name = Column('name', String(50)) 
  8.     age = Column('age'Integer 

Role.py 

  1. from sqlalchemy import ColumnInteger, String 
  2. from Models import Base 
  3.  
  4. class Role(Base): 
  5.     __tablename__ = 'Role' 
  6.     id = Column('id'Integer, primary_key=True, autoincrement=True
  7.     name = Column('name', String(50))  

從上面很容易看出來,這里的模型對應數據庫中的表,模型支持的類型有Integer, String, Boolean, Date, DateTime, Float,更多類型包括類型對應的Python的類型參見:這里

Column構造函數相關設置

  • name:名稱
  • type_:列類型
  • autoincrement:自增
  • default:默認值
  • index:索引
  • nullable:可空
  • primary_key:外鍵

更多介紹參見這里

接下來通過session進行增刪改查 

  1. from sqlalchemy import create_engine 
  2. from sqlalchemy.orm import sessionmaker 
  3. from User import User 
  4. from Role import Role 
  5. from Models import Base 
  6.  
  7. DB_CONNECT_STRING = 'sqlite:////Users/zhengxiankai/Desktop/Document/db.sqlite' 
  8. engine = create_engine(DB_CONNECT_STRING, echo=True
  9. DB_Session = sessionmaker(bind=engine) 
  10. session = DB_Session() 
  11.  
  12. # 1. 創建表(如果表已經存在,則不會創建) 
  13. Base.metadata.create_all(engine) 
  14.  
  15. # 2. 插入數據 
  16. u = User(name = 'tobi', age = 200) 
  17. r = Role(name = 'user'
  18.  
  19. # 2.1 使用add,如果已經存在,會報錯 
  20. session.add(u) 
  21. session.add(r) 
  22. session.commit() 
  23. print r.id 
  24.  
  25. # 3 修改數據 
  26. # 3.1 使用merge方法,如果存在則修改,如果不存在則插入 
  27. r.name = 'admin' 
  28. session.merge(r) 
  29.  
  30. # 3.2 也可以通過這種方式修改 
  31. session.query(Role).filter(Role.id == 1).update({'name''admin'}) 
  32.  
  33. # 4. 刪除數據 
  34. session.query(Role).filter(Role.id == 1).delete() 
  35.  
  36. # 5. 查詢數據 
  37. # 5.1 返回結果集的第二項 
  38. user = session.query(User).get(2) 
  39.  
  40. # 5.2 返回結果集中的第2-3項 
  41. users = session.query(User)[1:3] 
  42.  
  43. # 5.3 查詢條件 
  44. user = session.query(User).filter(User.id < 6).first() 
  45.  
  46. # 5.4 排序 
  47. users = session.query(User).order_by(User.name
  48.  
  49. # 5.5 降序(需要導入desc方法) 
  50. from sqlalchemy import desc 
  51. users = session.query(User).order_by(desc(User.name)) 
  52.  
  53. # 5.6 只查詢部分屬性 
  54. users = session.query(User.name).order_by(desc(User.name)) 
  55. for user in users: 
  56.     print user.name 
  57.  
  58. # 5.7 給結果集的列取別名 
  59. users = session.query(User.name.label('user_name')).all() 
  60. for user in users: 
  61.     print user.user_name 
  62.  
  63. # 5.8 去重查詢(需要導入distinct方法) 
  64. from sqlalchemy import distinct 
  65. users = session.query(distinct(User.name).label('name')).all() 
  66.  
  67. # 5.9 統計查詢 
  68. user_count = session.query(User.name).order_by(User.name).count() 
  69. age_avg = session.query(func.avg(User.age)).first() 
  70. age_sum = session.query(func.sum(User.age)).first() 
  71.  
  72. # 5.10 分組查詢 
  73. users = session.query(func.count(User.name).label('count'), User.age).group_by(User.age) 
  74. for user in users: 
  75.     print 'age:{0}, count:{1}'.format(user.age, user.count
  76.  
  77. session.close() 

 5. 多表關系

上面的所有操作都是基于單個表的操作,下面是多表以及關系的使用,我們修改上面兩個表,添加外鍵關聯(一對多和多對一)

User模型 

  1. from sqlalchemy import ColumnInteger, String 
  2. from sqlalchemy import ForeignKey 
  3. from sqlalchemy.orm import relationship 
  4. from Models import Base 
  5.  
  6. class User(Base): 
  7.     __tablename__ = 'users' 
  8.     id = Column('id'Integer, primary_key=True, autoincrement=True
  9.     name = Column('name', String(50)) 
  10.     age = Column('age'Integer
  11.  
  12.     # 添加角色id外鍵(關聯到Role表的id屬性) 
  13.     role_id = Column('role_id'Integer, ForeignKey('roles.id')) 
  14.     # 添加同表外鍵 
  15.     second_role_id = Column('second_role_id'Integer, ForeignKey('roles.id')) 
  16.  
  17.     # 添加關系屬性,關聯到role_id外鍵上 
  18.     role = relationship('Role', foreign_keys='User.role_id', backref='User_role_id'
  19.     # 添加關系屬性,關聯到second_role_id外鍵上 
  20.     second_role = relationship('Role', foreign_keys='User.second_role_id', backref='User_second_role_id'

 Role模型 

  1. from sqlalchemy import ColumnInteger, String 
  2. from sqlalchemy.orm import relationship 
  3. from Models import Base 
  4.  
  5. class Role(Base): 
  6.     __tablename__ = 'roles' 
  7.     id = Column('id'Integer, primary_key=True, autoincrement=True
  8.     name = Column('name', String(50)) 
  9.  
  10.     # 添加關系屬性,關聯到User.role_id屬性上 
  11.     users = relationship("User", foreign_keys='User.role_id', backref="Role_users"
  12.     # 添加關系屬性,關聯到User.second_role_id屬性上 
  13.     second_users = relationship("User", foreign_keys='User.second_role_id', backref="Role_second_users"

 這里有一點需要注意的是,設置外鍵的時候ForeignKey('roles.id')這里面使用的是表名和表列,在設置關聯屬性的時候relationship('Role', foreign_keys='User.role_id', backref='User_role_id'),這里的foreign_keys使用的時候類名和屬性名

接下來就可以使用了 

  1. u = User(name='tobi', age=200) 
  2.  
  3. r1 = Role(name='admin'
  4. r2 = Role(name='user'
  5.  
  6. u.role = r1 
  7. u.second_role = r2 
  8.  
  9. session.add(u) 
  10. session.commit() 
  11.  
  12. # 查詢(對于外鍵關聯的關系屬性可以直接訪問,在需要用到的時候session會到數據庫查詢) 
  13. roles = session.query(Role).all() 
  14. for role in roles: 
  15.     print 'role:{0} users' 
  16.     for user in role.users: 
  17.         print '\t{0}'.format(user.name
  18.     print 'role:{0} second_users' 
  19.     for user in role.second_users: 
  20.         print '\t{0}'.format(user.name

 上面表示的是一對多(多對一)的關系,還有一對一,多對多,如果要表示一對一的關系,在定義relationship的時候設置uselist為False(默認為True),如在Role中 

  1. class Role(Base): 
  2.     ... 
  3.     user = relationship("User", uselist=False, foreign_keys='User.role_id', backref="Role_user" 

6. 多表查詢

多表查詢通常使用join進行表連接,***個參數為表名,第二個參數為條件,例如 

  1. users = db.session.query(User).join(Role, Role.id == User.role_id) 
  2.  
  3. for u in users: 
  4.     print u.name  

join為內連接,還有左連接outerjoin,用法與join類似,右連接和全外鏈接在1.0版本上不支持,通常來說有這兩個結合查詢的方法基本夠用了,1.1版本貌似添加了右連接和全外連接的支持,但是目前只是預覽版

還可以直接查詢多個表,如下 

  1. result = db.session.query(User, Role).filter(User.role_id = Role.id) 
  2. # 這里選擇的是兩個表,使用元組獲取數據 
  3. for u, r in result: 
  4.       print u.name  

三、數據庫遷移

sqlalchemy的數據庫遷移/升級有兩個庫支持alembic和sqlalchemy-migrate

由于sqlalchemy-migrate在2011年發布了0.7.2版本后,就已經停止更新了,并且已經不維護了,也積累了很多bug,而alembic是較后來才出現,而且是sqlalchemy的作者開發的,有良好的社區支持,所以在這里只學習alembic這個庫

alembic實現了類似git/svn的版本管理的控制,我們可以通過alembic維護每次升級數據庫的版本

1. 安裝

通過pip安裝,pip會自動安裝相關的依賴

  1. $ pip install alembic 

2. 初始化

安裝完成后再項目根目錄運行 

  1. yourproject/ 
  2.     alembic.ini 
  3.     YOUR_ALEMBIC_DIR/ 
  4.         env.py 
  5.         README 
  6.         script.py.mako 
  7.         versions/ 
  8.             3512b954651e_add_account.py 
  9.             2b1ae634e5cd_add_order_id.py 
  10.             3adcc9a56557_rename_username_field.py  

其中

  • alembic.ini 提供了一些基本的配置
  • env.py 每次執行Alembic都會加載這個模塊,主要提供項目Sqlalchemy Model 的連接
  • script.py.mako 遷移腳本生成模版
  • versions 存放生成的遷移腳本目錄

默認情況下創建的是基于單個數據庫的,如果需要支持多個數據庫或其他,可以通過alembic list_templates查看支持的模板 

  1. $ alembic list_templates 
  2. Available templates: 
  3.  
  4. generic - Generic single-database configuration. 
  5. multidb - Rudimentary multi-database configuration. 
  6. pylons - Configuration that reads from a Pylons project environment. 
  7.  
  8. Templates are used via the 'init' command, e.g.: 
  9.  
  10.   alembic init --template generic ./scripts  

3. 配置

使用之前,需要配置一下鏈接字符串,打開alembic.ini文件,設置sqlalchemy.url連接字符串,例如 

  1. sqlalchemy.url = sqlite:////Users/zhengxiankai/Desktop/database.db 

其他參數可以參見官網說明:http://alembic.zzzcomputing.com/en/latest/tutorial.html

4. 創建數據庫版本

接下來我們創建一個數據庫版本,并新建兩個表 

  1. $ alembic revision -m 'create table' 

創建一個版本(會在yourproject/YOUR_ALEMBIC_DIR/versions/文件夾中創建一個python文件1a8a0d799b33_create_table.py)

該python模塊包含upgrade和downgrade兩個方法,在這里添加一些新增表的邏輯 

  1. """create table 
  2.  
  3. Revision ID: 4fd533a56b34 
  4. Revises: 
  5. Create Date: 2016-09-18 17:20:27.667100 
  6.  
  7. ""
  8. from alembic import op 
  9. import sqlalchemy as sa 
  10.  
  11.  
  12. # revision identifiers, used by Alembic. 
  13. revision = '4fd533a56b34' 
  14. down_revision = None 
  15. branch_labels = None 
  16. depends_on = None 
  17.  
  18. def upgrade(): 
  19.     # 添加表 
  20.     op.create_table( 
  21.         'account'
  22.         sa.Column('id', sa.Integer, primary_key=True), 
  23.         sa.Column('name', sa.String(50), nullable=False), 
  24.         sa.Column('description', sa.Unicode(200)), 
  25.     ) 
  26.  
  27.     # 添加列 
  28.     # op.add_column('account', sa.Column('last_transaction_date', sa.DateTime)) 
  29.  
  30.  
  31.  
  32. def downgrade(): 
  33.     # 刪除表 
  34.     op.drop_table('account'
  35.  
  36.     # 刪除列 
  37.     # op.drop_column('account''last_transaction_date' 

這里使用到了了op對象,關于op對象的更多API使用,參見這里

5. 升級數據庫

剛剛實現了升級和降級的方法,通過下面命令升級數據庫到***版本 

  1. $ alembic upgrade head 

這時候可以看到數據庫多了兩個表alembic_version和account,alembic_version存放數據庫版本

關于升級和降級的其他命令還有下面這些 

  1. # 升到***版本 
  2. $ alembic upgrade head 
  3.  
  4. # 降到最初版本 
  5. $ alembic downgrade base 
  6.  
  7. # 升兩級 
  8. $ alembic upgrade +2 
  9.  
  10. # 降一級 
  11. $ alembic downgrade -1 
  12.  
  13. # 升級到制定版本 
  14. $ alembic upgrade e93b8d488143 
  15.  
  16. # 查看當前版本 
  17. $ alembic current 
  18.  
  19. # 查看歷史版本詳情 
  20. $ alembic history --verbose 
  21.  
  22. # 查看歷史版本(-r參數)類似切片 
  23. $ alembic history -r1975ea:ae1027 
  24. $ alembic history -r-3:current 
  25. $ alembic history -r1975ea:  

6. 通過元數據升級數據庫

上面我們是通過API升級和降級,我們也可以直接通過元數據更新數據庫,也就是自動生成升級代碼,先定義兩個Model(User,Role),這里我定義成三個文件 

  1. yourproject/ 
  2.     YOUR_ALEMBIC_DIR/ 
  3.     tutorial/Db 
  4.         Models.py 
  5.         User.py 
  6.         Role.py 

 代碼就放在一起了 

  1. from sqlalchemy.ext.declarative import declarative_base 
  2. from sqlalchemy import ColumnInteger, String 
  3. Base = declarative_base() 
  4.  
  5. class User(Base): 
  6.     __tablename__ = 'users' 
  7.  
  8.     id = Column('id'Integer, primary_key=True, autoincrement=True
  9.     name = Column('name', String) 
  10.  
  11. class Role(Base): 
  12.     __tablename__ = 'roles' 
  13.  
  14.     id = Column('id'Integer, primary_key=True, autoincrement=True
  15.     name = Column('name', String) 

 在YOUR_ALEMBIC_DIR/env.py配置元數據 

  1. target_metadata = None 

改為 

  1. import os 
  2. import sys 
  3.  
  4. # 這里需要添加相對路徑到sys.path,否則會引用失敗,嘗試過使用相對路徑,但各種不好使,還是使用這種方法靠譜些 
  5. sys.path.append(os.path.abspath(os.path.join(os.getcwd(), "../yourproject/tutorial/Db"))) 
  6.  
  7. from User import User 
  8. from Role import Role 
  9. from Models import Base 
  10. target_metadata = Base.metadata  

os.path.join(os.getcwd()這個獲取到的地址不是env.py的路徑,而是根目錄

在創建數據庫版本的時候添加--autogenerate參數,就會從Base.metadata元數據中生成腳本 

  1. $ alembic revision --autogenerate -m "add user table" 

這時候會在生成升級代碼 

  1. """add user table 
  2.  
  3. Revision ID: 97de1533584a 
  4. Revises: 8678ab6d48c1 
  5. Create Date: 2016-09-19 21:58:00.758410 
  6.  
  7. ""
  8. from alembic import op 
  9. import sqlalchemy as sa 
  10.  
  11.  
  12. # revision identifiers, used by Alembic. 
  13. revision = '97de1533584a' 
  14. down_revision = '8678ab6d48c1' 
  15. branch_labels = None 
  16. depends_on = None 
  17.  
  18. def upgrade(): 
  19.     ### commands auto generated by Alembic - please adjust! ### 
  20.     op.create_table('roles'
  21.     sa.Column('id', sa.Integer(), nullable=False), 
  22.     sa.Column('name', sa.String(), nullable=True), 
  23.     sa.PrimaryKeyConstraint('id'
  24.     ) 
  25.     op.create_table('users'
  26.     sa.Column('id', sa.Integer(), nullable=False), 
  27.     sa.Column('name', sa.String(), nullable=True), 
  28.     sa.PrimaryKeyConstraint('id'
  29.     ) 
  30.     op.drop_table('account'
  31.     ### end Alembic commands ### 
  32.  
  33.  
  34. def downgrade(): 
  35.     ### commands auto generated by Alembic - please adjust! ### 
  36.     op.create_table('account'
  37.     sa.Column('id', sa.INTEGER(), nullable=False), 
  38.     sa.Column('name', sa.VARCHAR(length=50), nullable=False), 
  39.     sa.Column('description', sa.VARCHAR(length=200), nullable=True), 
  40.     sa.Column('last_transaction_date', sa.DATETIME(), nullable=True), 
  41.     sa.PrimaryKeyConstraint('id'
  42.     ) 
  43.     op.drop_table('users'
  44.     op.drop_table('roles'
  45.     ### end Alembic commands ###  

由于我沒有定義account模型,會被識別為刪除,如果刪除了model的列的聲明,則會被識別為刪除列,自動生成的版本我們也可以自己修改,然后執行升級命令即可升級alembic upgrade head

需要注意的是

  1. Base.metadata聲明的類必須以數據庫中的一一對應,如果數據庫中有的表,而在元數據中沒有,會識別成刪除表
  2. revision創建版本之前執行之前需要升級到***版本
  3. 配置Base之前,需要保證所有的Model都已經執行(即導入)過一次了,否則無法讀取到,也就是需要把所有Model都import進來

數據庫升級有風險,升級前***先檢查一遍upgrade函數,可以的話做好備份哈

四、常見問題

1. String長度問題

如果使用mysql數據庫,String類型對應的是VARCHAR類型,需要指定長度,否則會報下面錯誤,而在sqlite不會出現 

  1. (in table 'user'column 'name'): VARCHAR requires a length on dialect mysql 

TODO:如有其他問題歡迎留言

五、參考鏈接

***安利一下自己的博客:http://blog.bomobox.org

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2019-11-20 08:50:16

PythonORM工具包SQLAlchemy

2014-12-29 10:29:40

OpenStack數據庫SQLAlchem

2023-05-17 10:16:04

ORM工具包SQLAlchemy

2011-03-03 11:07:57

Spring數據庫訪問ORM

2013-11-26 09:47:47

ORM

2015-01-12 15:07:56

SQLAlchemy數據庫開發OpenStac

2011-08-11 14:23:57

SQL Server 索引分區

2011-08-25 11:08:21

Sybase數據庫

2025-04-03 08:30:00

Python數據庫ORM

2011-08-22 15:43:08

IOS開發數據庫

2011-08-29 18:17:12

Oracle聯合查詢

2024-04-03 10:05:02

2023-11-02 08:56:59

ORMGORM

2024-01-15 13:34:00

2011-08-30 13:33:29

Qt數據庫

2021-08-19 07:25:02

數據庫Flask插件

2010-02-02 15:48:49

Python數據庫

2023-06-06 08:25:31

SQLAlchemy數據庫

2025-04-10 10:20:12

Web 應用異步數據庫FastAPI

2025-03-03 09:40:00

.NET數據庫SqlSugar
點贊
收藏

51CTO技術棧公眾號

在线性视频日韩欧美| 亚洲成人国产| 日韩欧美a级成人黄色| 成人在线免费观看视视频| 女尊高h男高潮呻吟| 校园春色亚洲| 久久久精品蜜桃| 国产精品久久久久久久久久99| 免费看黄色的视频| 国产精品一区二区免费福利视频 | 午夜欧美在线一二页| 国产一区二区免费电影| 亚洲第一在线播放| 成人在线丰满少妇av| 欧美男同性恋视频网站| 黄网站色视频免费观看| 国产喷水福利在线视频| 黄色欧美日韩| 亚洲国产一区二区三区四区| 欧美国产激情视频| 巨骚激情综合| 久久电影网站中文字幕| 欧美人在线视频| 亚洲第一香蕉网| 成人免费91| 精品美女国产在线| 亚洲国产精品毛片| 国产小视频一区| 日韩精品一二三区| 欧美人在线观看| 日韩精品电影一区二区| 精品国产18久久久久久二百| 欧美日韩国产色视频| 亚洲在线观看一区| 日韩有码电影| 成人免费视频免费观看| 国产精品久久久久久久久久东京| 久久精品亚洲a| 欧美黄视频在线观看| 色婷婷久久久综合中文字幕| 亚洲av综合色区| 国产爆初菊在线观看免费视频网站| 国产福利91精品一区| 国产成人短视频| 免费一级全黄少妇性色生活片| 精品日韩在线| 亚洲国产精品系列| 国产一级片中文字幕| 忘忧草在线www成人影院| 亚洲一区二区三区在线播放| 中文网丁香综合网| 免费播放片a高清在线观看| 国产在线国偷精品产拍免费yy| 日本精品视频在线观看| 精品处破女学生| 手机在线电影一区| 亚洲人在线视频| 日韩Av无码精品| 精品成人18| 555www色欧美视频| jizz大全欧美jizzcom| 韩日精品一区二区| 欧美香蕉大胸在线视频观看| 国产精品久久久久9999爆乳| 国产福利视频在线观看| 国产精品久久毛片av大全日韩| 欧洲精品国产| 亚洲av色香蕉一区二区三区| 丝袜诱惑制服诱惑色一区在线观看| 午夜美女久久久久爽久久| 精品无码av在线| 亚洲福利专区| 色综合天天综合网国产成人网| 艳妇荡乳欲伦69影片| 欧美第十八页| 精品国产一区二区三区久久狼黑人| 一级特黄曰皮片视频| 精品在线播放| 亚洲精品永久免费精品| 国产熟女高潮一区二区三区 | 96pao国产成视频永久免费| 特级毛片www| 老牛嫩草一区二区三区日本| 欧亚精品在线观看| 日韩精品一区二区亚洲av| 欧美黄色大片网站| 精品激情国产视频| 欧美特级一级片| 国内自拍视频一区二区三区 | 偷拍女澡堂一区二区三区| 亚州av日韩av| 一区二区亚洲欧洲国产日韩| 久久午夜福利电影| 日韩激情免费| 欧美成人精品三级在线观看 | 国产成人精品免费视| 亚洲午夜色婷婷在线| xxxxx99| 欧美电影三区| 欧美国产亚洲视频| 五月婷婷中文字幕| 国产精品一区亚洲| 国产日韩欧美在线播放| 99热这里只有精品3| 丁香婷婷深情五月亚洲| 久久久久久国产精品mv| 91社区在线观看播放| 亚洲欧美日韩国产综合| 日本精品久久久久久久久久| 午夜欧美巨大性欧美巨大| 欧美日韩午夜在线| 成人免费黄色av| 日韩精品久久久久久久软件91| 亚洲精品999| 欧美巨胸大乳hitomi| 国内精品亚洲| 国产欧美亚洲精品| 狠狠躁日日躁夜夜躁av| 国产拍欧美日韩视频二区| 国产在线拍揄自揄拍无码| www.色在线| 欧美精品在欧美一区二区少妇| 亚洲午夜久久久久久久久| 色综合综合网| 欧美激情国产日韩精品一区18| 69国产精品视频免费观看| 精品写真视频在线观看| 久久精品成人一区二区三区蜜臀| 欧美激情黑人| 日韩欧美在线视频免费观看| 中文字幕第三区| 国产一区二区亚洲| 欧美激情视频一区二区| 亚洲天堂视频网| 97se亚洲国产综合自在线不卡| 91制片厂免费观看| 日韩av福利| 精品成人a区在线观看| 鲁丝一区二区三区| 亚洲综合精品四区| 99久久综合狠狠综合久久止| 超碰免费97在线观看| 黄色91在线观看| 中文字幕在线观看视频www| 欧美日韩国产在线观看网站| 98视频在线噜噜噜国产| 性欧美8khd高清极品| 国产精品久久久久久久久免费相片 | 亚洲人成网站777色婷婷| 久久亚洲国产成人精品性色| 蜜桃精品视频在线| 日本一区视频在线观看| 涩涩视频在线播放| 精品少妇一区二区| 黄视频网站免费看| 久久99精品久久久久久国产越南| 日本黑人久久| 日韩国产激情| 亚洲欧美国产一本综合首页| 日韩精品一区二区三| 国产不卡视频在线观看| 亚洲综合视频一区| 九九热线视频只有这里最精品| 精品亚洲一区二区三区四区五区| 日韩免费在线视频观看| 成人手机电影网| 996这里只有精品| 亚洲伊人影院| 蜜臀久久99精品久久久久久宅男| 国产乱淫av片免费| 亚洲天堂网中文字| 亚洲制服在线观看| 亚洲精彩视频| 91久久极品少妇xxxxⅹ软件| 粗大黑人巨茎大战欧美成人| 91麻豆精品国产自产在线| 色哟哟一一国产精品| 九色综合狠狠综合久久| 日本丰满少妇黄大片在线观看| 国产精品一区二区美女视频免费看 | 欧美日韩亚洲一二三| 欧美最新另类人妖| 国产精品丝袜高跟| 麻豆视频在线| 日韩精品资源二区在线| 国产在线一区视频| 波多野结衣视频一区| 草草久久久无码国产专区| 岳的好大精品一区二区三区| 国产成人拍精品视频午夜网站| 国产69久久| 制服丝袜亚洲色图| 久操免费在线视频| 97精品超碰一区二区三区| 91av在线免费播放| 国产精品久久久乱弄| 91精品国产综合久久男男| 日本网站在线免费观看视频| 欧美一区二区在线看| 日韩精品一区二区av| 国产区在线观看成人精品| 91小视频在线播放| 伊人久久成人| 天堂√在线观看一区二区| 91麻豆精品| 91精品91久久久久久| 毛片免费在线观看| 91麻豆精品国产自产在线| 日韩美女视频网站| 日本一区二区成人| 亚洲成a人无码| 日韩在线卡一卡二| 懂色av粉嫩av蜜臀av| 日韩极品在线| 91深夜福利视频| 中文字幕在线视频久| 久久人人爽人人爽爽久久| 韩国中文字幕hd久久精品| 欧美日韩在线观看视频| 人人澡人人澡人人看| 91视视频在线观看入口直接观看www| 人人干人人视频| 激情欧美丁香| 影音先锋亚洲视频| 天堂一区二区三区四区| 91香蕉电影院| 国精产品一区二区三区有限公司| 欧美国产亚洲精品久久久8v| 调教视频免费在线观看| 国产网站欧美日韩免费精品在线观看| 国产精品嫩草影院精东| 色婷婷综合五月| 久久久久亚洲av成人片| 亚洲欧洲日韩综合一区二区| 日韩在线免费观看av| 成人激情小说网站| 中文字幕久久av| 久久xxxx| 国产精品久久..4399| 久久久人成影片免费观看| 欧美日韩在线播放一区二区| 成人春色在线观看免费网站| 91久久中文字幕| 亚洲一区二区三区四区| 4438全国亚洲精品在线观看视频| av大大超碰在线| 亚洲男人av电影| 天堂a中文在线| 欧美变态凌虐bdsm| 国产精品一区二区av白丝下载 | 久久99蜜桃精品| 成人三级视频在线播放| 亚洲人成久久| 性一交一乱一伧国产女士spa| 欧美国产先锋| 强伦女教师2:伦理在线观看| 久久综合88| 亚洲欧洲一区二区| 国产精品嫩草影院在线看| 久久久亚洲综合网站| 亚洲欧洲美洲av| 欧美自拍视频在线观看| 超碰在线99| 97精品久久久中文字幕免费| 污视频网站在线免费| 久久五月情影视| 91亚洲天堂| 不卡av在线播放| 最新超碰在线| 欧美国产亚洲精品久久久8v| 啦啦啦中文在线观看日本| 中文字幕无线精品亚洲乱码一区 | 37p粉嫩大胆色噜噜噜| www.久久精品| 捆绑凌虐一区二区三区| 国产乱子伦视频一区二区三区 | 国产精品中出一区二区三区| 亚洲国产高清在线观看| 国产成人精品日本亚洲11 | 国产精品久久不卡| 99久久精品费精品国产一区二区 | 久久久综合视频| 久久精品成人av| 国产免费久久精品| 亚洲国产123| 最新不卡av在线| 5566中文字幕| 夜夜精品视频一区二区 | 成人免费观看在线| 99伊人成综合| 熟女人妇 成熟妇女系列视频| 日韩—二三区免费观看av| 91高清国产视频| 久久99精品久久久| 白嫩情侣偷拍呻吟刺激| 久久午夜免费电影| 懂色av粉嫩av蜜臀av一区二区三区| 亚洲欧美日韩一区二区| 久草精品视频在线观看| 亚洲国产视频网站| 久久久久99精品成人片我成大片 | 在线观看毛片网站| 欧美日韩国产高清一区二区三区 | 91在线超碰| 国产精品第1页| 久久视频社区| 欧美不卡福利| 91精品高清| 日日摸日日碰夜夜爽av| 久久99精品国产91久久来源| 中国极品少妇xxxx| 国产精品剧情在线亚洲| 亚洲国产精品午夜在线观看| 在线亚洲精品福利网址导航| 国产视频手机在线| 亚洲欧美激情视频| 丁香花在线电影小说观看| 国产女人精品视频| 国产精品一区高清| 亚洲中文字幕无码av永久| 国产麻豆成人精品| 亚洲女人毛茸茸高潮| 色婷婷一区二区三区四区| 黄色av免费观看| 美女视频黄免费的亚洲男人天堂| av在线一区不卡| 久久综合中文色婷婷| 亚洲视频免费| 制服.丝袜.亚洲.中文.综合懂| 国产精品蜜臀av| 久久国产乱子伦精品| 亚洲人成欧美中文字幕| 亚洲精品国产精品国产| 精品国产乱码久久久久久蜜柚| 国产精品啊v在线| 亚洲成人激情小说| 亚洲天堂免费在线观看视频| 一本久道久久综合无码中文| 在线观看久久av| av在线日韩| 色视频一区二区三区| 久热综合在线亚洲精品| 99久久久无码国产精品性 | 一级黄色片在线播放| 色综合亚洲精品激情狠狠| 97成人资源| 日本一区二区在线视频| 老**午夜毛片一区二区三区| 西西444www无码大胆| 欧美亚洲一区二区三区四区| 91成人高清| 成人精品视频久久久久| 51精产品一区一区三区| 黄页网站在线看| 亚洲第一福利一区| 污污视频在线免费看| 4p变态网欧美系列| 国产尤物久久久| 熟女人妇 成熟妇女系列视频| 中文一区一区三区高中清不卡| 中文字幕在线观看免费| 久久精品99久久久久久久久| 精品中文视频| 99er在线视频| 99在线精品观看| 中文字幕精品无| 精品国内自产拍在线观看| 亚洲乱码一区| 国产白丝袜美女久久久久| 国产亚洲一本大道中文在线| 中文字幕乱码中文字幕| 欧美成人免费va影院高清| 日韩在线成人| 日本www在线播放| 日本一区二区不卡视频| 国产av无码专区亚洲a∨毛片| 久久久久国色av免费观看性色| 自拍自偷一区二区三区| 中文字幕亚洲乱码| 一区二区视频在线| 日韩亚洲视频在线观看| 成人午夜激情免费视频| 影音先锋中文字幕一区| 性欧美一区二区| 欧美不卡视频一区| 久久天堂av| 国产视频在线观看网站| 久久久不卡网国产精品二区| 国产精品久久久久毛片| 97在线观看视频| 欧美大黑bbbbbbbbb在线| 中文字幕天堂av| 欧美久久一区二区| 黄色在线免费观看网站| 一区二区三区在线观看www| 北条麻妃国产九九精品视频| 最新在线中文字幕| 久久久久久国产精品| 日韩精品第一区| 亚洲调教欧美在线|