rottengeek

rottengeek 查看完整档案

杭州编辑  |  填写毕业院校  |  填写所在公司/组织 www.jianshu.com/u/f48150b5a1c6 编辑
编辑

后续python相关内容移步简书与知乎(python进阶,爬虫,数据分析,机器学习,自然语言处理,知识图谱)

简书地址:https://www.jianshu.com/u/f48...
知乎地址:https://www.zhihu.com/people/...

个人动态

rottengeek 发布了文章 · 2019-11-07

机器学习汇总

机器学习汇总

介绍

本模块包含自己学习机器学习过程中学习过的内容,包含基础案例和实战案例,大部分以ipynb的格式展示,包含数据集和源代码,可以下载使用练习,包含机器学习的常见算法,如逻辑斯蒂回归,决策树,支持向量机,集成算法,贝叶斯,聚类等等。

由于包含数据集内容比较大,鉴于网速没有上传到github,而且码云自带ipynb文件渲染,可以在线看代码,由于码云自带的图片无法渲染,有些内容是通过jupyter官网的nbviewer渲染的,下面是该项目的链接。

项目码云链接

目录

如果觉得我资料搜集和整体的还行,希望大佬打赏一下
image

image

查看原文

赞 4 收藏 3 评论 0

rottengeek 提出了问题 · 2019-11-03

Pycharm 2019 jupyter notebook 没有输出

image.png
如上图所示,在pycharm中使用jupyter notebook 运行时 no output

image.png
server也是启动的了

关注 1 回答 0

rottengeek 收藏了文章 · 2019-08-29

Mac下Eclipse提交任务到Hadoop集群

搭建Hadoop集群: VirtualBox+Ubuntu 14.04+Hadoop2.6.0

搭建好集群后, 在Mac下安装Eclipse并连接Hadoop集群

1. 访问集群

1.1. 修改Mac的hosts

添加Master的IP到Mac的hosts

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1    localhost
255.255.255.255    broadcasthost
::1             localhost

192.168.56.101  Master # 添加Master的IP

1.2 访问集群

Master下, 启动集群
Mac下, 打开http://master:50070/
能够成功访问, 看到集群的信息, 就可以了

2. 下载安装Eclipse

Eclipse IDE for Java Developers

http://www.eclipse.org/downloads/package...

3. 配置Eclipse

3.1 配置Hadoop-Eclipse-Plugin

3.1.1 下载Hadoop-Eclipse-Plugin

可下载 Github 上的 hadoop2x-eclipse-plugin(备用下载地址:http://pan.baidu.com/s/1i4ikIoP

3.1.2 安装Hadoop-Eclipse-Plugin

在Applications中找个Eclise, 右键, Show Package Contents

图片描述

将插件复制到plugins目录下, 然后重新打开Eclipse就可以了

图片描述

3.2 连接Hadoop集群

3.2.1 配置Hadoop安装目录

将Hadoop安装包解压到任何目录, 不用做任何配置, 然后在Eclipse中指向该目录即可

图片描述

3.2.2 配置集群地址

点击右上角的加号

图片描述

添加Map/Reduce视图

图片描述

选择Map/Reduce Locations, 然后右键, 选择New Hadoop location

图片描述

需要改Location name, Host, DFS Master下的Port, User name ( Master会引用Mac中的hosts配置的IP ), 完成后, Finish

图片描述

3.2.3 查看HDFS

查看是否可以直接访问HDFS

图片描述

4. 集群中运行WordCount

4.1 创建项目

File -> New -> Other -> Map/Reduce Project

输入项目名: WordCount, 然后点击, Finish

4.2 创建类

创建一个类, 报名org.apache.hadoop.examples, 类名: WordCount

4.3 WordCount代码

复制下面的代码到WordCount.java中

package org.apache.hadoop.examples;
 
import java.io.IOException;
import java.util.StringTokenizer;
 
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
 
public class WordCount {
 
  public static class TokenizerMapper 
       extends Mapper<Object, Text, Text, IntWritable>{
 
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();
 
    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }
 
  public static class IntSumReducer 
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();
 
    public void reduce(Text key, Iterable<IntWritable> values, 
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);
    }
  }
 
  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length != 2) {
      System.err.println("Usage: wordcount <in> <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

4.4 配置Hadoop参数

将所有修改过的配置文件和log4j.properties, 复制到src目标下

这里我复制了slaves, core-site.xml, hdfs-site.xml, mapred-site.xml, yarn-site.xml

4.4 配置HDFS输入输出路径

鼠标移动到WordCount.java上, 右键, Run As, Java Application

图片描述

此时, 程序不会正常运行. 再次右键, Run As, 选择Run Configurations

填入输入输出路径 (空格分割)

图片描述

配置完成后点击, Run. 此时会出现, Permission denied

5. 运行中出现的问题

5.1 Permission denied

没有权限访问HDFS

# 假设Mac的用户名为hadoop
groupadd supergroup # 添加supergroup组
useradd -g supergroup hadoop # 添加hadoop用户到supergroup组

# 修改hadoop集群中hdfs文件的组权限, 使属于supergroup组的所有用户都有读写权限
hadoop fs -chmod 777 /

6. 查看Hadoop源码

6.1 下载源码

http://apache.claz.org/hadoop/common/had...

6.2 链接源码

右上角的搜索框中, 搜索Open Type

图片描述

输入NameNode, 选择NameNode, 发现看不了源码

点击Attach Source -> External location -> External Floder

图片描述

参考资料

使用Eclipse编译运行MapReduce程序 Hadoop2.6.0_Ubuntu/CentOS

查看原文

rottengeek 提出了问题 · 2018-12-10

1药网药品说明书爬取

https://www.111.com.cn/

这个是1药网的地址,我想要爬取上述网站上的所有药品说明书,可以现在遇到的问题下,在药品目录下,查看某一类药品的时候,药品分页的,而分页的最大页数是50页,但是其实真正的药品不止50页那么少,我应该如何弄到所有的药品呢。

关注 1 回答 0

rottengeek 收藏了文章 · 2018-12-07

sqlalchemy学习笔记

SQLAlchemy是python的一个数据库ORM工具,提供了强大的对象模型间的转换,可以满足绝大多数数据库操作的需求,并且支持多种数据库引擎(sqlite,mysql,postgres, mongodb等),在这里记录基本用法和学习笔记

一、安装

通过pip安装

$ pip install SQLAlchemy

二、使用

首先是连接到数据库,SQLALchemy支持多个数据库引擎,不同的数据库引擎连接字符串不一样,常用的有

mysql://username:password@hostname/database
postgresql://username:password@hostname/database
sqlite:////absolute/path/to/database
sqlite:///c:/absolute/path/to/database

更多连接字符串的介绍参见这里

下面是连接和使用sqlite数据库的例子

1. connection

使用传统的connection的方式连接和操作数据库

from sqlalchemy import create_engine

# 数据库连接字符串
DB_CONNECT_STRING = 'sqlite:///:memory:'

# 创建数据库引擎,echo为True,会打印所有的sql语句
engine = create_engine(DB_CONNECT_STRING, echo=True)

# 创建一个connection,这里的使用方式与python自带的sqlite的使用方式类似
with engine.connect() as con:
    # 执行sql语句,如果是增删改,则直接生效,不需要commit
    rs = con.execute('SELECT 5')
    data = rs.fetchone()[0]
    print "Data: %s" % data

与python自带的sqlite不同,这里不需要Cursor光标,执行sql语句不需要commit

2. connection事务

使用事务可以进行批量提交和回滚

from sqlalchemy import create_engine

# 数据库连接字符串
DB_CONNECT_STRING = 'sqlite:////Users/zhengxiankai/Desktop/Document/db.sqlite'
engine = create_engine(DB_CONNECT_STRING, echo=True)

with engine.connect() as connection:
    trans = connection.begin()
    try:
        r1 = connection.execute("select * from User")
        r2 = connection.execute("insert into User(name, age) values(?, ?)", 'bomo', 24)
        trans.commit()
    except:
        trans.rollback()
        raise

3. session

connection是一般使用数据库的方式,sqlalchemy还提供了另一种操作数据库的方式,通过session对象,session可以记录和跟踪数据的改变,在适当的时候提交,并且支持强大的ORM的功能,下面是基本使用

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# 数据库连接字符串
DB_CONNECT_STRING = 'sqlite:////Users/zhengxiankai/Desktop/Document/db.sqlite'

# 创建数据库引擎,echo为True,会打印所有的sql语句
engine = create_engine(DB_CONNECT_STRING, echo=True)

# 创建会话类
DB_Session = sessionmaker(bind=engine)

# 创建会话对象
session = DB_Session()

# dosomething with session

# 用完记得关闭,也可以用with
session.close()

上面创建了一个session对象,接下来可以操作数据库了,session也支持通过sql语句操作数据库

session.execute('select * from User')
session.execute("insert into User(name, age) values('bomo', 13)")
session.execute("insert into User(name, age) values(:name, :age)", {'name': 'bomo', 'age':12})

# 如果是增删改,需要commit
session.commit()

注意参数使用dict,并在sql语句中使用:key占位

4. ORM

上面简单介绍了sql的简单用法,既然是ORM框架,我们先定义两个模型类UserRole,sqlalchemy的模型类继承自一个由declarative_base()方法生成的类,我们先定义一个模块Models.py生成Base类

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

User.py

from sqlalchemy import Column, Integer, String
from Models import Base

class User(Base):
    __tablename__ = 'User'
    id = Column('id', Integer, primary_key=True, autoincrement=True)
    name = Column('name', String(50))
    age = Column('age', Integer)

Role.py

from sqlalchemy import Column, Integer, String
from Models import Base

class Role(Base):
    __tablename__ = 'Role'
    id = Column('id', Integer, primary_key=True, autoincrement=True)
    name = Column('name', String(50))

从上面很容易看出来,这里的模型对应数据库中的表,模型支持的类型有Integer, String, Boolean, Date, DateTime, Float,更多类型包括类型对应的Python的类型参见:这里

Column构造函数相关设置

  • name:名称

  • type_:列类型

  • autoincrement:自增

  • default:默认值

  • index:索引

  • nullable:可空

  • primary_key:外键

更多介绍参见这里

接下来通过session进行增删改查

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from User import User
from Role import Role
from Models import Base

DB_CONNECT_STRING = 'sqlite:////Users/zhengxiankai/Desktop/Document/db.sqlite'
engine = create_engine(DB_CONNECT_STRING, echo=True)
DB_Session = sessionmaker(bind=engine)
session = DB_Session()

# 1. 创建表(如果表已经存在,则不会创建)
Base.metadata.create_all(engine)

# 2. 插入数据
u = User(name = 'tobi', age = 200)
r = Role(name = 'user')

# 2.1 使用add,如果已经存在,会报错
session.add(u)
session.add(r)
session.commit()
print r.id

# 3 修改数据
# 3.1 使用merge方法,如果存在则修改,如果不存在则插入(只判断主键,不判断unique列)
r.name = 'admin'
session.merge(r)

# 3.2 也可以通过这种方式修改
session.query(Role).filter(Role.id == 1).update({'name': 'admin'})

# 4. 删除数据
session.query(Role).filter(Role.id == 1).delete()

# 5. 查询数据
# 5.1 返回结果集的第二项
user = session.query(User).get(2)

# 5.2 返回结果集中的第2-3项
users = session.query(User)[1:3]

# 5.3 查询条件
user = session.query(User).filter(User.id < 6).first()

# 5.4 排序
users = session.query(User).order_by(User.name)

# 5.5 降序(需要导入desc方法)
from sqlalchemy import desc
users = session.query(User).order_by(desc(User.name))

# 5.6 只查询部分属性
users = session.query(User.name).order_by(desc(User.name))
for user in users:
    print user.name

# 5.7 给结果集的列取别名
users = session.query(User.name.label('user_name')).all()
for user in users:
    print user.user_name

# 5.8 去重查询(需要导入distinct方法)
from sqlalchemy import distinct
users = session.query(distinct(User.name).label('name')).all()

# 5.9 统计查询
user_count = session.query(User.name).order_by(User.name).count()
age_avg = session.query(func.avg(User.age)).first()
age_sum = session.query(func.sum(User.age)).first()

# 5.10 分组查询
users = session.query(func.count(User.name).label('count'), User.age).group_by(User.age)
for user in users:
    print 'age:{0}, count:{1}'.format(user.age, user.count)

# 6.1 exists查询(不存在则为~exists())
from sqlalchemy.sql import exists
session.query(User.name).filter(~exists().where(User.role_id == Role.id))
# SELECT name AS users_name FROM users WHERE NOT EXISTS (SELECT * FROM roles WHERE users.role_id = roles.id)

# 6.2 除了exists,any也可以表示EXISTS
session.query(Role).filter(Role.users.any())

# 7 random
from sqlalchemy.sql.functions import random
user = session.query(User).order_by(random()).first()

session.close()

参考链接:

5. 多表关系

上面的所有操作都是基于单个表的操作,下面是多表以及关系的使用,我们修改上面两个表,添加外键关联(一对多和多对一)

User模型

from sqlalchemy import Column, Integer, String
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from Models import Base

class User(Base):
    __tablename__ = 'users'
    id = Column('id', Integer, primary_key=True, autoincrement=True)
    name = Column('name', String(50))
    age = Column('age', Integer)

    # 添加角色id外键(关联到Role表的id属性)
    role_id = Column('role_id', Integer, ForeignKey('roles.id'))
    # 添加同表外键
    second_role_id = Column('second_role_id', Integer, ForeignKey('roles.id'))

    # 添加关系属性,关联到role_id外键上
    role = relationship('Role', foreign_keys='User.role_id', backref='User_role_id')
    # 添加关系属性,关联到second_role_id外键上
    second_role = relationship('Role', foreign_keys='User.second_role_id', backref='User_second_role_id')

Role模型

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship
from Models import Base

class Role(Base):
    __tablename__ = 'roles'
    id = Column('id', Integer, primary_key=True, autoincrement=True)
    name = Column('name', String(50))

    # 添加关系属性,关联到User.role_id属性上
    users = relationship("User", foreign_keys='User.role_id', backref="Role_users")
    # 添加关系属性,关联到User.second_role_id属性上
    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使用的时候类名和属性名

接下来就可以使用了

u = User(name='tobi', age=200)

r1 = Role(name='admin')
r2 = Role(name='user')

u.role = r1
u.second_role = r2

session.add(u)
session.commit()

# 查询(对于外键关联的关系属性可以直接访问,在需要用到的时候session会到数据库查询)
roles = session.query(Role).all()
for role in roles:
    print 'role:{0} users'
    for user in role.users:
        print '\t{0}'.format(user.name)
    print 'role:{0} second_users'
    for user in role.second_users:
        print '\t{0}'.format(user.name)

上面表示的是一对多(多对一)的关系,还有一对一,多对多,如果要表示一对一的关系,在定义relationship的时候设置uselist为False(默认为True),如在Role中

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

6. 多表查询

多表查询通常使用join进行表连接,第一个参数为表名,第二个参数为条件,例如

users = db.session.query(User).join(Role, Role.id == User.role_id)

for u in users:
    print u.name

join为内连接,还有左连接outerjoin,用法与join类似,右连接和全外链接在1.0版本上不支持,通常来说有这两个结合查询的方法基本够用了,1.1版本貌似添加了右连接和全外连接的支持,但是目前只是预览版

还可以直接查询多个表,如下

result = db.session.query(User, Role).filter(User.role_id = Role.id)
# 这里选择的是两个表,使用元组获取数据
for u, r in result:
      print u.name

三、数据库迁移

sqlalchemy的数据库迁移/升级有两个库支持alembicsqlalchemy-migrate

由于sqlalchemy-migrate在2011年发布了0.7.2版本后,就已经停止更新了,并且已经不维护了,也积累了很多bug,而alembic是较后来才出现,而且是sqlalchemy的作者开发的,有良好的社区支持,所以在这里只学习alembic这个库

alembic实现了类似git/svn的版本管理的控制,我们可以通过alembic维护每次升级数据库的版本

1. 安装

通过pip安装,pip会自动安装相关的依赖

$ pip install alembic

2. 初始化

安装完成后再项目根目录运行

$ alembic init YOUR_ALEMBIC_DIR

alembic会在根目录创建YOUR_ALEMBIC_DIR目录和alembic.ini文件,如下

yourproject/
    alembic.ini
    YOUR_ALEMBIC_DIR/
        env.py
        README
        script.py.mako
        versions/
            3512b954651e_add_account.py
            2b1ae634e5cd_add_order_id.py
            3adcc9a56557_rename_username_field.py

其中

  • alembic.ini 提供了一些基本的配置

  • env.py 每次执行Alembic都会加载这个模块,主要提供项目Sqlalchemy Model 的连接

  • script.py.mako 迁移脚本生成模版

  • versions 存放生成的迁移脚本目录

默认情况下创建的是基于单个数据库的,如果需要支持多个数据库或其他,可以通过alembic list_templates查看支持的模板

$ alembic list_templates
Available templates:

generic - Generic single-database configuration.
multidb - Rudimentary multi-database configuration.
pylons - Configuration that reads from a Pylons project environment.

Templates are used via the 'init' command, e.g.:

  alembic init --template generic ./scripts

3. 配置

使用之前,需要配置一下链接字符串,打开alembic.ini文件,设置sqlalchemy.url连接字符串,例如

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

其他参数可以参见官网说明:http://alembic.zzzcomputing.com/en/latest/tutorial.html

4. 创建数据库版本

接下来我们创建一个数据库版本,并新建两个表

$ alembic revision -m 'create table'

创建一个版本(会在yourproject/YOUR_ALEMBIC_DIR/versions/文件夹中创建一个python文件1a8a0d799b33_create_table.py

该python模块包含upgradedowngrade两个方法,在这里添加一些新增表的逻辑

"""create table

Revision ID: 4fd533a56b34
Revises:
Create Date: 2016-09-18 17:20:27.667100

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '4fd533a56b34'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # 添加表
    op.create_table(
        'account',
        sa.Column('id', sa.Integer, primary_key=True),
        sa.Column('name', sa.String(50), nullable=False),
        sa.Column('description', sa.Unicode(200)),
    )

    # 添加列
    # op.add_column('account', sa.Column('last_transaction_date', sa.DateTime))



def downgrade():
    # 删除表
    op.drop_table('account')

    # 删除列
    # op.drop_column('account', 'last_transaction_date')

这里使用到了了op对象,关于op对象的更多API使用,参见这里

这里生成的文件名是依照在alembic.ini文件声明的模板来的,默认为版本号+名字,可以加上一些日期信息,否则不好排序,更多参数参见这里

file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d_%%(minute).2d_%%(rev)s_%%(slug)s

另外通常我们也改一下生成模板script.py.mako,加上编码信息,否则在升级脚本中如果有中文会报错

#!/usr/bin/python
# -*- coding:utf-8 -*-

5. 升级数据库

刚刚实现了升级和降级的方法,通过下面命令升级数据库到最新版本

$ alembic upgrade head

这时候可以看到数据库多了两个表alembic_versionaccountalembic_version存放数据库版本

关于升级和降级的其他命令还有下面这些

# 升到最高版本
$ alembic upgrade head

# 降到最初版本
$ alembic downgrade base

# 升两级
$ alembic upgrade +2

# 降一级
$ alembic downgrade -1

# 升级到制定版本
$ alembic upgrade e93b8d488143

# 查看当前版本
$ alembic current

# 查看历史版本详情
$ alembic history --verbose

# 查看历史版本(-r参数)类似切片
$ alembic history -r1975ea:ae1027
$ alembic history -r-3:current
$ alembic history -r1975ea:

6. 通过元数据升级数据库

上面我们是通过API升级和降级,我们也可以直接通过元数据更新数据库,也就是自动生成升级代码,先定义两个Model(User, Role),这里我定义成三个文件

yourproject/
    YOUR_ALEMBIC_DIR/
    tutorial/Db
        Models.py
        User.py
        Role.py

代码就放在一起了

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column('id', Integer, primary_key=True, autoincrement=True)
    name = Column('name', String)

class Role(Base):
    __tablename__ = 'roles'

    id = Column('id', Integer, primary_key=True, autoincrement=True)
    name = Column('name', String)

YOUR_ALEMBIC_DIR/env.py配置元数据

target_metadata = None

改为

import os
import sys

# 这里需要添加相对路径到sys.path,否则会引用失败,尝试过使用相对路径,但各种不好使,还是使用这种方法靠谱些
sys.path.append(os.path.abspath(os.path.join(os.getcwd(), "../yourproject/tutorial/Db")))

from User import User
from Role import Role
from Models import Base
target_metadata = Base.metadata

os.path.join(os.getcwd()这个获取到的地址不是env.py的路径,而是根目录

在创建数据库版本的时候添加--autogenerate参数,就会从Base.metadata元数据中生成脚本

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

这时候会在生成升级代码

"""add user table

Revision ID: 97de1533584a
Revises: 8678ab6d48c1
Create Date: 2016-09-19 21:58:00.758410

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '97de1533584a'
down_revision = '8678ab6d48c1'
branch_labels = None
depends_on = None

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.create_table('roles',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('users',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.drop_table('account')
    ### end Alembic commands ###


def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.create_table('account',
    sa.Column('id', sa.INTEGER(), nullable=False),
    sa.Column('name', sa.VARCHAR(length=50), nullable=False),
    sa.Column('description', sa.VARCHAR(length=200), nullable=True),
    sa.Column('last_transaction_date', sa.DATETIME(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.drop_table('users')
    op.drop_table('roles')
    ### 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不会出现

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

如有问题欢迎到我的博客留言

五、参考链接

最后安利一下自己的博客:http://zhengbomo.github.com

查看原文

rottengeek 提出了问题 · 2018-11-01

百科类网站的数据库是如何设计的

clipboard.png

百科类网站的数据库设计

如上图所示,是一个医学的百科网站,比如 典型症状这这个网页中 都是 大段 p标签的文本,我不知道他们数据库中是如何存储的,如果用mysql等关系库,该怎么设计数据库呢

关注 1 回答 1

rottengeek 关注了标签 · 2018-09-22

知识图谱

有关联关系的知识点构成的语义网络

关注 7

rottengeek 关注了用户 · 2018-09-11

Lin_R @lin_r

准则一:简单即美。
准则二:让每一个程序只做好一件事。
准则三:尽快建立原型。
准则四:舍高效率而取可移植性。
准则五:采用纯文本文件来存储数据。
准则六:充分利用软件的杆杆效应。
准则七:使用shell脚本来提高杆杆效应和可移植性。
准则八:避免强制性的用户界面。
准则九:让每一个程序都成为过滤器。
永远记住:搬起石头砸自己的脚总比裹足不前要好

关注 297

rottengeek 提出了问题 · 2018-09-10

维基百科爬虫

如何实现爬取维基百科上的所有疾病名称,以及该疾病对应的同义词,同义词一般文本内就存在。
给个思路!

关注 2 回答 1

rottengeek 关注了标签 · 2018-09-05

自然语言处理

自然語言處理(英语:Natural Language Processing,簡稱NLP)是人工智慧和語言學領域的分支學科。在這此領域中探討如何處理及運用自然語言;自然語言認知則是指讓電腦「懂」人類的語言。

自然語言生成系統把計算機數據轉化為自然語言。自然語言理解系統把自然語言轉化為計算機程序更易于處理的形式。

关注 211

认证与成就

  • 获得 210 次点赞
  • 获得 10 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 10 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-05-14
个人主页被 2.8k 人浏览