xml地图|网站地图|网站标签 [设为首页] [加入收藏]
python与数据库之mysql,Python使用Scrapy框架爬取数据
分类:编程

一、深入.NET框架

相关内容:

  • 使用pymysql直接操作mysql

    • 创建表
    • 查看表
    • 修改表
    • 删除表
    • 插入数据
    • 查看数据
    • 修改数据
    • 删除数据

     

  • 使用sqlmary操作mysql

    • 创建表
    • 查看表
    • 修改表
    • 删除表
    • 插入数据
    • 查看数据
    • 修改数据
    • 删除数据

 

 

首发时间:2018-02-24 23:59

修改:

  • 2018-06-15,发现自己关于pymysql写了对于数据的操作示例,但没有写表结构的示例,于是添加上

 


1. Scrapy框架

  Scrapy是python下实现爬虫功能的框架,能够将数据解析、数据处理、数据存储合为一体功能的爬虫框架。

1..NET框架具有两个组件:CLR(公共语言运行时)和FCL(框架类库),CLR是.NET框架的基础

直接操作mysql--pymysql:

直接操作mysql意思是利用python实现类似命令行模式下的mysql交互。

 

2. Scrapy安装

2.框架核心类库:

 

1. 安装依赖包

yum install gcc libffi-devel python-devel openssl-devel -y
yum install libxslt-devel -y

System.Collections.Generic:泛型操作

前提:

  • 首先需要安装python与mysql交互的库【PyMySQL 是在 Python3 版本中用于连接 MySQL 服务器的一个库】:

    • 安装模块:pymysql:

      pip3 install pymysql
      

      或者在Pycharm中安装

 2. 安装scrapy

pip install scrapy
pip install twisted==13.1.0

 注意事项:scrapy和twisted存在兼容性问题,如果安装twisted版本过高,运行scrapy startproject project_name的时候会提示报错,安装twisted==13.1.0即可。

System.IO:IO流操作

使用:

  • 首先导入模块:import pymysql
  • 连接数据库 :数据库连接对象 = pymysql.connect("host="localhost",port=3306,user='root',passwd='123456',db='python_test') 【如果需要支持中文,则加上charset=”utf8”】图片 1
  • 创建游标【游标用于执行sql语句和管理查询到的结果】 :游标对象 = 数据库连接对象.cursor()
  • 执行sql语句 :游标对象.execute(SQL语句) ,返回值是受影响行数  【execute可以执行所有的sql语句,不论是表相关的,还是数据相关的。】
    • 由于默认开始事务,如果涉及修改、插入,则需要提交:连接对象.commit() ;以及撤销修改、插入的回滚:连接对象.rollback()
    • executemany是同时执行多条sql语句【以多组参数的格式,executemany(self,query,args)】:
    • 图片 2
  • 获取结果:

    • 获取一条结果:data = 游标对象.fetchone()

    • 获取全部结果:data=游标对象.fetchall()

    • 获取指定数量结果:data=游标对象.fetmany(x)

    • 获取结果后,就会将对应的结果删掉,比如fetchone是获取一条,那么这一条就会从原来的结果中删除

    • 游标对象.rowcount()可以获得执行sql语句后受影响的行数

    • 图片 3 

  • 关闭游标: 游标对象.close()

  • 关闭数据库连接:数据库连接对象.close()

 

3. 基于Scrapy爬取数据并存入到CSV

3.1. 爬虫目标,获取简书中热门专题的数据信息,站点为

图片 4

System.Net:网络编程

示例:

3.2. 爬取内容

  需要爬取专题的内容包括:专题内容、专题描述、收录文章数、关注人数,Scrapy使用xpath来清洗所需的数据,编写爬虫过程中可以手动通过lxml中的xpath获取数据,确认无误后再将其写入到scrapy代码中,区别点在于,scrapy需要使用extract()函数才能将数据提取出来。

System.Data:ADO.NET结构的类的访问

1.创建连接:

import pymysql

#创建连接
conn=pymysql.connect(host="localhost",port=3306,user="root",passwd="123456",db="python_test")
#创建游标
cursor=conn.cursor()
#..............操作过程
#关闭游标
cursor.close()
#关闭连接
conn.close()

3.3 创建爬虫项目

[root@HappyLau jianshu_hot_topic]# scrapy startproject jianshu_hot_topic

#项目目录结构如下:
[root@HappyLau python]# tree jianshu_hot_topic
jianshu_hot_topic
├── jianshu_hot_topic
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── items.py
│   ├── items.pyc
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── pipelines.pyc
│   ├── settings.py
│   ├── settings.pyc
│   └── spiders
│       ├── collection.py
│       ├── collection.pyc
│       ├── __init__.py
│       ├── __init__.pyc
│       ├── jianshu_hot_topic_spider.py    #手动创建文件,用于爬虫数据提取
│       └── jianshu_hot_topic_spider.pyc
└── scrapy.cfg

2 directories, 16 files
[root@HappyLau python]# 

System.Windows.Forms:窗体操作

2.执行创建表:

import pymysql

conn=pymysql.connect(host="localhost",port=3306,user="root",password="123456",db="it",charset="utf8")

cursor=conn.cursor()

sql="""
create table user(
id int PRIMARY KEY auto_increment,
username VARCHAR(20),
password VARCHAR(20),
address VARCHAR(35) 
)
"""
cursor.execute(sql)

conn.commit()
cursor.close()
conn.close()

 3.4 代码内容

1. items.py代码内容,定义需要爬取数据字段
# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy
from scrapy import Item
from scrapy import Field

class JianshuHotTopicItem(scrapy.Item):
 '''
 @scrapy.item,继承父类scrapy.Item的属性和方法,该类用于定义需要爬取数据的子段
 '''
 collection_name = Field()
 collection_description = Field()
 collection_article_count = Field()
 collection_attention_count = Field()

2. piders/jianshu_hot_topic_spider.py代码内容,实现数据获取的代码逻辑,通过xpath实现
[root@HappyLau jianshu_hot_topic]# cat spiders/jianshu_hot_topic_spider.py
#_*_ coding:utf8 _*_

import random
from time import sleep
from scrapy.spiders import CrawlSpider
from scrapy.selector import Selector
from scrapy.http import Request
from jianshu_hot_topic.items import JianshuHotTopicItem 

class jianshu_hot_topic(CrawlSpider):
 '''
 简书专题数据爬取,获取url地址中特定的子段信息
 '''
 name = "jianshu_hot_topic"
 start_urls = ["https://www.jianshu.com/recommendations/collections?page=2&order_by=hot"]

 def parse(self,response):
  '''
  @params:response,提取response中特定字段信息
  '''
  item = JianshuHotTopicItem()
  selector = Selector(response)
  collections = selector.xpath('//div[@class="col-xs-8"]') 
  for collection in collections:
   collection_name = collection.xpath('div/a/h4/text()').extract()[0].strip()
                 collection_description = collection.xpath('div/a/p/text()').extract()[0].strip()
                 collection_article_count = collection.xpath('div/div/a/text()').extract()[0].strip().replace('篇文章','')
                 collection_attention_count = collection.xpath('div/div/text()').extract()[0].strip().replace("人关注",'').replace("· ",'') 
   item['collection_name'] = collection_name
   item['collection_description'] = collection_description
   item['collection_article_count'] = collection_article_count 
   item['collection_attention_count'] = collection_attention_count

   yield item


  urls = ['https://www.jianshu.com/recommendations/collections?page={}&order_by=hot'.format(str(i)) for i in range(3,11)]
  for url in urls:
   sleep(random.randint(2,7))
   yield Request(url,callback=self.parse)

3. pipelines文件内容,定义数据存储的方式,此处定义数据存储的逻辑,可以将数据存储载MySQL数据库,MongoDB数据库,文件,CSV,Excel等存储介质中,如下以存储载CSV为例:
[root@HappyLau jianshu_hot_topic]# cat pipelines.py
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html


import csv 

class JianshuHotTopicPipeline(object):
    def process_item(self, item, spider):
     f = file('/root/zhuanti.csv','a+')
 writer = csv.writer(f)
 writer.writerow((item['collection_name'],item['collection_description'],item['collection_article_count'],item['collection_attention_count']))
        return item

4. 修改settings文件,
ITEM_PIPELINES = { 
    'jianshu_hot_topic.pipelines.JianshuHotTopicPipeline': 300,
}

System.Drawing:图形操作

3.执行查询:

import pymysql

#创建连接
conn=pymysql.connect(host="localhost",port=3306,user="root",passwd="123456",db="python_test",charset="utf8")
#创建游标
cursor=conn.cursor()

cursor.execute("select * from student;")
print(cursor.fetchone())#获取一条
print(cursor.fetchmany(2))#获取两条
print(cursor.fetchall())#获取结果集合中的全部

#关闭游标
cursor.close()
#关闭连接
conn.close()

 3.5 运行scrapy爬虫

  返回到项目scrapy项目创建所在目录,运行scrapy crawl spider_name即可,如下:

[root@HappyLau jianshu_hot_topic]# pwd
/root/python/jianshu_hot_topic
[root@HappyLau jianshu_hot_topic]# scrapy crawl jianshu_hot_topic
2018-02-24 19:12:23 [scrapy.utils.log] INFO: Scrapy 1.5.0 started (bot: jianshu_hot_topic)
2018-02-24 19:12:23 [scrapy.utils.log] INFO: Versions: lxml 3.2.1.0, libxml2 2.9.1, cssselect 1.0.3, parsel 1.4.0, w3lib 1.19.0, Twisted 13.1.0, Python 2.7.5 (default, Aug  4 2017, 00:39:18) - [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)], pyOpenSSL 0.13.1 (OpenSSL 1.0.1e-fips 11 Feb 2013), cryptography 1.7.2, Platform Linux-3.10.0-693.el7.x86_64-x86_64-with-centos-7.4.1708-Core
2018-02-24 19:12:23 [scrapy.crawler] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'jianshu_hot_topic.spiders', 'SPIDER_MODULES': ['jianshu_hot_topic.spiders'], 'ROBOTSTXT_OBEY': True, 'USER_AGENT': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0', 'BOT_NAME': 'jianshu_hot_topic'}

 查看/root/zhuanti.csv中的数据,即可实现。

 

二、深入C#数据类型

4.执行插入、修改、删除:

import pymysql

#创建连接
conn=pymysql.connect(host="localhost",port=3306,user="root",password="123456",db="python_test",charset="utf8")
#创建游标
cursor=conn.cursor()

print("-----------插入----------------")
cursor.execute("insert into student values ('nazha',2000,'男');")
cursor.execute("select * from student;")
print(cursor.fetchall())
print("-----------插入----------------")
#cursor.executemany(self,query,args)
cursor.executemany("insert into student value(%s,%s,%s);",[('zhangsan',18,'男'),('lisi',18,'男')])
cursor.execute("select * from student;")
print(cursor.fetchall())
print("-----------修改----------------")
cursor.execute("update student set name = 'zhangsan1' where name = 'zhangsan';")
cursor.execute("select * from student;")
print(cursor.fetchall())
print("----------删除-----------------")
cursor.execute("delete from student where name = 'lisi';")
cursor.execute("select * from student;")
print(cursor.fetchall())
print("---------------------------")

#需要提交才能插入、成功修改、删除
conn.commit()
#关闭游标
cursor.close()
#关闭连接
conn.close()

结果:

(('lilei', 18, '男'), ('hanmeimei', 18, '女'), ('huluwa', 18, '男'), ('sunwukong', 18, '男'), ('baigujing', 3000, '女'), ('nazha', 2000, '男'))
---------------------------
(('lilei', 18, '男'), ('hanmeimei', 18, '女'), ('huluwa', 18, '男'), ('sunwukong', 18, '男'), ('baigujing', 3000, '女'), ('nazha', 2000, '男'), ('zhangsan', 18, '男'), ('lisi', 18, '男'))
---------------------------
(('lilei', 18, '男'), ('hanmeimei', 18, '女'), ('huluwa', 18, '男'), ('sunwukong', 18, '男'), ('baigujing', 3000, '女'), ('nazha', 2000, '男'), ('zhangsan1', 18, '男'), ('lisi', 18, '男'))
---------------------------
(('lilei', 18, '男'), ('hanmeimei', 18, '女'), ('huluwa', 18, '男'), ('sunwukong', 18, '男'), ('baigujing', 3000, '女'), ('nazha', 2000, '男'), ('zhangsan1', 18, '男'))
---------------------------

4. 遇到的问题总结

  1. twisted版本不见容,安装过新的版本导致,安装Twisted (13.1.0)即可

2. 中文数据无法写入,提示'ascii'错误,通过设置python的encoding为utf即可,如下:

>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf8')
>>> sys.getdefaultencoding()
'utf8'

 3. 爬虫无法获取站点数据,由于headers导致,载settings.py文件中添加USER_AGENT变量,如:

USER_AGENT="Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

 Scrapy使用过程中可能会遇到结果执行失败或者结果执行不符合预期,其现实的logs非常详细,通过观察日志内容,并结合代码+网上搜索资料即可解决。

1.结构体:结构体是由struct修饰的类,结构体是值类型(枚举也是值类型)

5.设置支持中文【创建连接时添加charset=”utf8”】:

import pymysql

#创建连接
# conn=pymysql.connect(host="localhost",port=3306,user='root',passwd='123456',db='python_test')
conn=pymysql.connect(host="localhost",port=3306,user='root',passwd='123456',db='python_test',charset="utf8")

#创建游标
cursor = conn.cursor()

effect_row= cursor.execute("select * from student;")


print("执行成功,受影响行数:",effect_row)
print(cursor.fetchall())

conn.commit()

cursor.close()
conn.close()

添加前:

图片 5

添加后:

图片 6

 

 

 

 


public struct Student
{
}

使用sqlalchemy操作mysql:

 

2.拆箱和装箱:

介绍:

  • ORM 将数据库中的表与面向对象语言中的类建立了一种对应关系,【ORM可以说是参照映射来处理数据的模型,比如说:需要创建一个表,可以定义一个类,而这个类存在与表相映射的属性,那么可以通过操作这个类来创建一个表】
  • sqlmary是一个mysql的ORM

装箱:就是把值类型转换为引用类型

前提:

  • 安装模块:pip3 install sqlalchemy

object o=1;

使用:

  • 导入模块:
    • 导入连接数据库模块:from sqlalchemy import create_engine
    • 如果需要创建新表,则需要导入表结构定义模块:from sqlalchemy.ext.declarative import declarative_base
    • 导入其他相关模块,主要是映射的类,如字段映射为Column,如数据类型int映射为Integer,如索引映射为Index,需要什么导入什么:from sqlalchemy import Column,Integer,String
    • 映射关系:
      数据库中 映射 模块【如果可以从多个模块处导入,用 | 分隔】【方式太多,可能有漏,但不影响导入】
      Table from sqlalchemy import Table
      int Integer from sqlalchemy.types import Integer
      索引 Index from sqlalchemy import Index
           
      字段、列 Column from sqlalchemy import Column
      varchar VARCHAR、String from sqlalchemy.types import String    |   from sqlalchemy import String
      外键 ForeignKey
      from sqlalchemy import ForeignKey
           
           
  • 连接数据库:连接对象=create_engine('数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名',编码格式,echo)
    • sqlalchemy支持多种API操作模式,可以使用不同的模式来连接操作数据库:'数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'
      • 比如pymsql【py3常用】:mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>
    • 其他参数:
      • echo是否显示ORM转成实际sql语句的过程,echo=True为显
      • encoding为连接时使用的字符集

 

拆箱:就是把引用类型转换为值类型

操作:

基本操作:

  • 创建新表

    • 方法一: 使用declarative

      • 1.导入模块from sqlalchemy.ext.declarative import declarative_base
      • 2.根据需要的元素来导入模块``from sqlalchemy import Column
        • 导入需要的数据类型【注:数据类型在sqlalchemy中也有指向,所以也可以from sqlalchemy import String,Integer,Char】:from sqlalchemy.types import *
      • 3.创建连接,
      • 3.使用declarative_base来获得一个类对象,此处我定义该对象为Base
      • 定义一个类,继承declarative_base生成的类对象Base
        • 使用__tablename__来定义表名
        • 使用 列名 = Column(数据类型,其他列属性…)等类似格式来定义字段
          • nullable=False 代表这一列不可以为空,index=True 表示在该列创建索
      • 创建表:Base.metadata.create_all(engine)

        from sqlalchemy import create_engine#负责导入连接数据库的对象
        from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api
        from sqlalchemy import Column #负责导入列
        from sqlalchemy.types import *#负责导入列类型
        
        #数据库连接
        engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8',echo=True)
        #方式一:
        Base = declarative_base()
        
        class User(Base):
            __tablename__ = 'user'#表名
            id = Column(Integer,primary_key=True)
            name = Column(String(32))
            password = Column(String(64))
        
        Base.metadata.create_all(engine)
        

     

    • 方法二:使用Table
      • 1.导入模块: from sqlalchemy import Table
      • 2.连接数据库:engine=create_engine(….)
      • 3.获取meta类,metadata=MetaData(engine)
      • 4.创建Table对象( 比如:t=Table("group" ,metadata,Column("id",Integer,primary_key=True),Column("group_name",String(32)))  )
      • 5.创建表:metadata.create_all()
        from sqlalchemy import create_engine
        from sqlalchemy import Table
        from sqlalchemy import MetaData
        from sqlalchemy import Column
        from sqlalchemy.types import *
        from sqlalchemy.ext.declarative import declarative_base
        
            ####下面的注释部分可以与上面一句的未注释的替换
            engine=create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8',echo=True)
            metadata=MetaData(engine) ###  
            # Base=declarative_base()

            t=Table(
            "group" ,metadata,#表名
            # "group",Base.metadata,
            Column("id",Integer,primary_key=True),
            Column("group_name",String(32))
            )

            metadata.create_all()
            # Base.metadata.create_all(engine)

 

  • 查看表:
    • db_table=Base.metadata.tables#仅有当次运行中继承了Base而创建的新表
    • db_tables=engine.table_names()#仅有表名
  • 删除表:Base.metadata.drop_all(engine)
  • 修改表:
    • 直接修改表所对应的类结构是无法修改成功的,
    • 如果需要修改在程序中自定义的表的结构,那么需要手动修改,手动的方式有很多,比如直接engine.execute(sql语句)。。。。

 

 

 

  • 插入 数据【这里仅针对使用declarative_base创建的表,对于不是程序中才创建的,可以自己使用declarative_base建一个类来映射之前的表,只要映射一致,就能插入数据】

    • 1.连接数据库:engine=create_engine(….)
    • 1.导入模块:from sqlalchemy.orm import sessionmaker
    • 2.获取session_class类:Session_class=sessionmaker(bind=engine)
    • 3.获取session对象:s=Session_class()
    • 4.使用s来添加:
      • s.add()
      • s.add_all()
    • 5.提交数据: s.commit()

      from sqlalchemy import create_engine#负责导入连接数据库的对象
      from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api
      from sqlalchemy import Column #负责导入列
      from sqlalchemy.types import *#负责导入列类型
      
      #数据库连接
      engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8',echo=True)
      Base = declarative_base()
      class User(Base):
          __tablename__ = 'user'#表名
          id = Column(Integer,primary_key=True)
          name = Column(String(32))
          password = Column(String(64))
          group = Column(Integer)
      
      Base.metadata.create_all(engine)
      
        from sqlalchemy.orm import sessionmaker
        obj1=User(name='lisi',password='123456',group=1)

        Session=sessionmaker(bind=engine)
        s=Session()
        s.add(obj1)#

        users=[User(name='wangwu',password='123456',group=1),
               User(name='zhaoliu', password='123456', group=1),
               User(name='sunqi', password='123456', group=1)
               ]
        s.add_all(users)#

        s.commit()

 

 

  • 查找 数据

    • 同样适用sessionmaker来查找,与插入相同,需要创建session_class对象(我定义为s)
    • 使用s来查找:

      • s.query(表对应类)是相当于select对应表,后面可以跟first()、all()等来获取结果,也可以加filter、filter_by等来筛选结果
      • 获取全部 : s.query(表对应类).all() 【返回的是一个结果列表】
      • 查找指定: s.query(表对应类).filter(表对应类.xxx==xxxx)【filter获取的是结果集,需要使用all(),first()等方法来获取结果】
      • 查找指定: s.query(表对应类).filter_by(xxx=xxxx)
      • 附:虽然返回值是一个结果集,但这个集合是一个类对象,如果想查看内容,需要在表对应的类中增加__repr__方法。
      • 多个筛选条件使用“,”隔开
      • 常见可用筛选条件【User是一个表对应的类】:

        使用filter,filter_by时:
        User.name==’lisi’
        User.name.like(“lisi%”))
        User.name != ’lisi’
        User.name.any()
        or_(筛选条件) 【代表里面的多个筛选条件以or组合,需要导入:from sqlalchemy import or_】
        and_(筛选条件) 【代表里面的多个筛选条件以and组合,需要导入:from sqlalchemy import and_】【默认是and】
        in_([筛选条件])  【使用比如User.name.in_(['xiaxia', 'lilei', 'lover'])】
        使用all时,以下是放在query里面的:
        User.name  [这相当于不使用where的select name from 表]
         
         
      • 连接查询使用:s.query(表对应类).join(表对应类.xxx==xxxx)

      • 还有group_by,order_by等用法这里不做讲解[什么时候有空再补吧!]

        from sqlalchemy import create_engine#负责导入连接数据库的对象
        from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api
        from sqlalchemy import Column #负责导入列
        from sqlalchemy.types import *#负责导入列类型
        
        #数据库连接
        engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8')
        Base = declarative_base()
        class User(Base):
            __tablename__ = 'user'#表名
            id = Column(Integer,primary_key=True)
            name = Column(String(32))
            password = Column(String(64))
            group = Column(Integer)
        
            def __repr__(self):
                return "<id:%s name:%s group:%s>"%(self.id,self.name,self.group)
        Base.metadata.create_all(engine)
        
            from sqlalchemy.orm import sessionmaker
            obj1=User(name='lisi',password='123456',group=1)

            Session=sessionmaker(bind=engine)
            s=Session()

            a=s.query(User).all()
            a2=s.query(User).filter(User.name=='lisi').first()
            a3=s.query(User).filter_by(name='lisi').first()



            print(a)
            print(a2)
            print(a3)

 

 

  • 修改 数据:

    • 修改数据的基础是先查找到数据,查找:row=s.query(X).filter(X.xxx=xxx).first()
    • 使用赋值语句修改 :row.xxx=xxxx

      from sqlalchemy import create_engine#负责导入连接数据库的对象
      from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api
      from sqlalchemy import Column #负责导入列
      from sqlalchemy.types import *#负责导入列类型
      
      #数据库连接
      engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8')
      Base = declarative_base()
      class User(Base):
          __tablename__ = 'user'#表名
          id = Column(Integer,primary_key=True)
          name = Column(String(32))
          password = Column(String(64))
          group = Column(Integer)
      
          def __repr__(self):
              return "<id:%s name:%s group:%s>"%(self.id,self.name,self.group)
      Base.metadata.create_all(engine)
      
        from sqlalchemy.orm import sessionmaker
        obj1=User(name='lisi',password='123456',group=1)

        Session=sessionmaker(bind=engine)
        s=Session()


        row=s.query(User).filter(User.name=='lisi').first()
        row.name='lisi2'
        s.commit()

 

 

  • 删除 数据:

    • 删除数据的基础是先查找到数据,查找:row=s.query(X).filter(X.xxx=xxx)
    • 使用delete删除:row.delete()

      # coding: utf-8
      from sqlalchemy import create_engine#负责导入连接数据库的对象
      from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api
      from sqlalchemy import Column #负责导入列
      from sqlalchemy.types import *#负责导入列类型
      
      #数据库连接
      engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8')
      Base = declarative_base()
      class User(Base):
          __tablename__ = 'user'#表名
          id = Column(Integer,primary_key=True)
          name = Column(String(32))
          password = Column(String(64))
          group = Column(Integer)
          def __repr__(self):
              return "<id:%s name:%s group:%s>"%(self.id,self.name,self.group)
      
      Base.metadata.create_all(engine)
      
        from sqlalchemy.orm import sessionmaker
        obj1=User(name='lisi',password='123456',group=1)

        Session=sessionmaker(bind=engine)
        s=Session()


        a3=s.query(User).filter_by(name='lisi1')
        a3.delete()
        s.commit()

 

  • 外键相关:

    • 外键使用foregin_key创建
    • 类中的relationship的作用:帮助ORM获知他们的外键关系,以便ORM使用外键获取相关数据
      • relationship中的backref的用途:relationship使得可以在一个表中定义的relationshop能被两个表使用,另一个表使用backref来获取相关信息
      • relationship中的foreign_keys的用途:当有多个relationship时,为了避免ORM混淆多个relationship,特别的标注哪个外键是哪个relationship
      • relationship中的secondary的用途:在多对多的关系中,填入的值是中间表,维持两边表关系。
    • 一对一的外键关系:

      • 1.导入模块:from sqlalchemy import Foreign_key
      • 2.建立外键(如:group = Column(Integer,ForeignKey("group.id")),建立关系(如:group_relation=relationship('Group',backref="g_users")
      • 3.插入数据
      • 4.查询到一条数据:如row=s.query(User).filter(User.name=='lisi').first()
      • 5.尝试A表调用关系来获取B(row.group_relation.group_name),B使用backref来获取A的数据(row2.g_users)
      • 下面的实例大概就是“一个开发人员对应一个开发组的关系”

      #负责导入连接数据库的对象 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api from sqlalchemy import Column,ForeignKey #负责导入列 from sqlalchemy.types import *#负责导入列类型 from sqlalchemy.orm import relationship

      #数据库连接 engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8') Base = declarative_base()

    class Group(Base):
        __tablename__="group"
        id=Column(Integer,primary_key=True)
        group_name=Column(String(32),nullable=False)

        def __repr__(self):
            return "<id:%s group_name:%s>"%(self.id,self.group_name)

    class User(Base):
        __tablename__ = 'user'#表名
        id = Column(Integer,primary_key=True)
        name = Column(String(32),nullable=False)
        password = Column(String(64),nullable=False)
        group = Column(Integer,ForeignKey("group.id"))#这里创建外键

        group_relation=relationship('Group',backref="g_users")#为ORM指明关系,方便ORM处理,第一个是对应的类
        def __repr__(self):
            return "<id:%s name:%s>"%(self.id,self.name)
    Base.metadata.create_all(engine)

    from sqlalchemy.orm import sessionmaker
    # group1=Group(group_name='python')
    # group2=Group(group_name='linux')
    # group3=Group(group_name='AI')
    # user1=User(name='lisi',password='123456',group=1)
    # user2=User(name='zhangsan',password='123456',group=2)
    # user3=User(name='wangwu',password='123456',group=3)
    # user4=User(name='lilei',password='123456',group=3)


    Session=sessionmaker(bind=engine)
    s=Session()
    # s.add_all([group1,group2,group3,user1,user2,user3,user4])
    # s.commit()

    # row=s.query(User).filter(User.name=='lisi').first()
    row=s.query(User).first()
    print(row.group_relation.group_name)#这里User通过关系来获取Group的数据
    row2=s.query(Group).first()
    print(row2)
    print(row2.g_users)#这里Group通过relationship的backref来获取User的数据

-   一对多关系,外键关联
    -   `以一个老师能做一个班的班主任此外还能做另一个班的副班主任为例【即一个老师能对应多个班级】`
    -   一对多关系的创建的核心是relationship中的foreign_keys
    -   `附:当你建表成功而插入数据失败时,可以尝试先删除掉数据表,有时候因为外键依赖会导致插入失败 

`

            #负责导入连接数据库的对象
            from sqlalchemy import create_engine
            from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api
            from sqlalchemy import Column,ForeignKey #负责导入列
            from sqlalchemy.types import *#负责导入列类型
            from sqlalchemy.orm import relationship

            #数据库连接
            engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8')
            Base = declarative_base()



            class Grade(Base):
                __tablename__="grade"
                id=Column(Integer,primary_key=True)
                grade_name=Column(String(32),nullable=False)

                def __repr__(self):
                    return "<id:%s group_name:%s>"%(self.id,self.grade_name)

            class Teacher(Base):
                __tablename__ = 'teacher'#表名
                id = Column(Integer,primary_key=True)
                name = Column(String(32),nullable=False)
                primary_grade = Column(Integer,ForeignKey("grade.id"))
                second_grade = Column(Integer,ForeignKey("grade.id"))

                primary_grade_relation=relationship('Grade',backref="first_teacher",foreign_keys=[primary_grade])
                second_grade_relation=relationship('Grade',backref="second_teacher",foreign_keys=[second_grade])
                def __repr__(self):
                    return "<id:%s name:%s>"%(self.id,self.name)


            Base.metadata.create_all(engine)

            from sqlalchemy.orm import sessionmaker
            # grade1=Grade(grade_name='python')
            # grade2=Grade(grade_name='linux')
            # grade3=Grade(grade_name='AI')
            # grade4=Grade(grade_name='Java')
            # t1=Teacher(name='lisi',primary_grade=1,second_grade=2)
            # t2=Teacher(name='zhangsan',primary_grade=2,second_grade=1)
            # t3=Teacher(name='wangwu',primary_grade=4,second_grade=3)
            # t4=Teacher(name='lilei',primary_grade_relation=grade3,second_grade=4)
            #这里外键相关的比如primary_grade=x可以使用primary_grade_relation=对象来代替,
            # 会根据对象来转成对应id,不过问题是不知道grade3的准确id,因为可能创建顺序不一致

            Session=sessionmaker(bind=engine)
            s=Session()
            # s.add_all([grade1,grade2,grade3,grade4])
            # s.add_all([t1,t2,t3,t4])
            # s.commit()

            row=s.query(Teacher).filter(Teacher.name=='lisi').first()

            print(row.name,row.primary_grade_relation.grade_name)#这里Teacher通过关系来获取Grade的数据
            print(row.name,row.second_grade_relation.grade_name)
            row2=s.query(Grade).first()
            print(row2.grade_name,row2.first_teacher)#这里Grade通过relationship的backref来获取Teacher的数据
            print(row2.grade_name,row2.second_teacher)

`` 

-   多对多外键关联
    -   以选课中一门课能有多名学生,一个学生可以选多门课为示例:
    -   其中relationship中的secondary的值是中间表,负责维持中间表与另外两表的关系,创建多对多的核心是secondary
            #负责导入连接数据库的对象
            from sqlalchemy import create_engine
            from sqlalchemy.ext.declarative import declarative_base#负责导入创建表的api
            from sqlalchemy import Column,ForeignKey #负责导入列
            from sqlalchemy.types import *#负责导入列类型
            from sqlalchemy.orm import relationship

            #数据库连接
            engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8')
            Base = declarative_base()

            class SelectInfo(Base):
                __tablename__="selectClassInfo"
                id=Column(Integer,primary_key=True)
                sid=Column(Integer,ForeignKey("student.id"))
                cid=Column(Integer,ForeignKey("course.id"))


            """使用declarative_base和Table 创建表时,secondary的填写不一样
            selectInfo2=Table(
            'selectClassInfo',Base.metadata,
            Column('sid',Integer,ForeignKey('student.id'))
            Column('cid',Integer,ForeignKey('student.id'))
            )
            """

            class Student(Base):
                __tablename__="student"
                id=Column(Integer,primary_key=True)
                name=Column(String(32),nullable=False)

                def __repr__(self):
                    return "<id:%s name:%s>"%(self.id,self.name)

            class Course(Base):
                __tablename__ = 'course'
                id = Column(Integer,primary_key=True)
                name = Column(String(32),nullable=False)

                student_relation=relationship('Student',secondary="selectClassInfo",backref="courses")
                # student_relation=relationship('Student',secondary=selectClassInfo2,backref="courses") 
                # #如果使用Table来创建中间表,上面是这样填的

                def __repr__(self):
                    return "<id:%s name:%s>"%(self.id,self.name)


            Base.metadata.create_all(engine)

            from sqlalchemy.orm import sessionmaker
            #
            # s1=Student(name='lisi')
            # s2=Student(name='zhangsan')
            # s3=Student(name='wangwu')
            # s4=Student(name='lilei')
            # c1=Course(name='python',student_relation=[s1,s2])
            # c2=Course(name='linux',student_relation=[s3])
            # c3=Course(name='AI',student_relation=[s3,s4])
            # c4=Course(name='Java')
            # c4.student_relation=[s1,s2,s3,s4]##在一边增加关系之后,在secondary中会加入两边的数据
            #
            #
            #
            Session=sessionmaker(bind=engine)
            s=Session()
            # s.add_all([s1,s2,s3,s4,c1,c2,c3,c4])
            # s.commit()

            row=s.query(Course).filter(Course.id=='4').first()

            print(row.name,row.student_relation)#这里Course通过关系来获取Student的数据
            row2=s.query(Student).filter(Student.id=="3").first()
            print(row2.name,row2.courses)#这里Student通过relationship的backref来获取Course的数据

 

 

 

 

int num=(int)o;

补充说明:

1.engine 可以直接运行sql语句,方式是engine.execute(),返回值是结果集,可以使用fetchall等方法来获取结果

2.其实创建表还有很多方法,可以使用各种对象来创建【比如在上面Table方式中也可以使用t来create(engine)】,但建议使用方式一

3.同样的,不单创建表有各种方法,查看表,删除表等也有多种操作方式,也是因为可以使用多种对象来操作

4.session也可以直接运行sql语句: session.execute()

 

 

附上sessionmake API官方文档:里面详尽而简单的讲解了用法

以及一个第三方辅助文档: 里面有不少关于sqlalchemy的用法例子

 


3.值传递和引用传递(有无ref修饰)

a.有ref修饰时,修改的值会永久保留

b.无ref修饰时,是值类型的,修改的值不会永久保留

c.无ref修饰时,是引用类型的,修改的值会永久保留

三、泛型集合

1.集合的概念:

集合就是将一堆数据类型的数据放在一起的一种容器,和数组是很相似的东西。

2.集合的分类以及声明方法

a.集合分为非泛型和泛型集合,非泛型又分单列(ArrayList)和双列(Hashtable),泛型也分单列(List<T>)和双列(Dictionary<K,V>)。

单列的T数据类型可以为object类型,双列的K,V也可以是object类型

b.集合的声明

ArrayList list=new ArrayList();

Hashtable list=new Hashtable();

List<T> list=new List<T>();

Dictionary<K,V> list=new Dictionary<K,V>();

3.集合的方法和属性

1.Add(),增加数据的方法

2.Remove(),删除数据的方法,()里填的是一整条的数据,单列集合的删除,集合会去自动维护数据,这样集合不会出现某个索引的值是为空的

3.RemoveAt(),同样也是删除数据的方法,()里填的是索引(单列)双列没有RemoveAt()方法,

4.Clear(),清空集合的所有数据

5.Count属性,可以得到集合有几条数据

6.Capacity属性,集合的容量,集合的容量是成倍(二倍)的增加的,Count为0时,Capacity为0,Count为1时,Capacity为4

7.Contains(),单列集合用来判断某个数据是否存在

8.ContainsKey(),双列判断是否存在某个Key值

9.ContainsValue(),双列判断是否存在某个Value值

4.集合的遍历方法

HashTable和Dictionary遍历不同就是,遍历值类型的时候,HashTable需要进行类型转换(拆箱,装箱)

HashTable:

(1).通过Key值遍历 foreach (string item in list.Keys) { Console.WriteLine(list[item]); }

(2).通过value值遍历 foreach (Student item in list.Values) { Console.WriteLine((Student)item.Name); }

(3).通过整体的双列集合遍历 foreach (DictionaryEntry item in list) { Console.WriteLine(item.Key); Console.WriteLine(((Student)item.Value).Name); }

Dictionary:

(1).通过Key值遍历 foreach (string item in list.Keys) { Console.WriteLine(list[item]); }

(2).通过value值遍历 foreach (Student item in list.Values) { Console.WriteLine(item.Name); }

(3).通过整体遍历 foreach (KeyValuePair<T,V> item in list) { Console.WriteLine(item.Key); Console.WriteLine((item.Value).Name); }

四、深入类的方法

1.方法重载:通过传的参数的不同从而调用不同的方法,方法名相同,参数类型不同,参数顺序不同,参数个数不同,和返回值无关

参数类型不同:

public void Play(int num){};

public void Play(string name){};

参数顺序不同:

public void Play(int num,int age){};

public void Play(int age,int num){};

参数个数不同:

public void Play(int num){};

public void Play(string name,int num){};

和返回值无关:

public string Play(int num){};

public int Play(int num){};

2.类的构造:和类名相同,无返回值

无参构造:

public class Student

本文由澳门新葡亰手机版发布于编程,转载请注明出处:python与数据库之mysql,Python使用Scrapy框架爬取数据

上一篇:PHP之外观模式,reactor加密源码保软件安全 下一篇:re正则表达式模块,将过去时间格式化成xx
猜你喜欢
热门排行
精彩图文