使用 mysqlconnector,python3 环境下比较好用的mysql连接库
?
1
|
DB_CONNECT_STRING
=
'mysql+mysqlconnector://root:@localhost/demo?charset=utf8'
|
?
1
2
3
4
5
6
7
8
9
10
|
from
sqlalchemy
import
create_engine
from
sqlalchemy.orm
import
scoped_session, sessionmaker
from
sqlalchemy.ext.declarative
import
declarative_base
engine
=
create_engine(DB_CONNECT_STRING)
db_session
=
scoped_session(sessionmaker(autocommit
=
False
,
autoflush
=
False
,
bind
=
engine))
Base
=
declarative_base(metadata
=
MetaData(), metaclass
=
DeclarativeMeta)
Base.query
=
db_session.query_property()
|
这样 Base 可以作为 sqlalchemy的 Model 的 基类使用
?
1
2
3
4
5
6
|
class
User(Base):
__tablename__
=
'user_tab'
id
=
Column(Integer, primary_key
=
True
)
name
=
Column(String(
50
), unique
=
True
, index
=
True
, nullable
=
False
)
pwd
=
Column(String(
50
), nullable
=
False
)
real_name
=
Column(String(
50
), nullable
=
False
)
|
如上,定义model: User
BaseHandler 中需要 重写俩方法
?
1
2
3
4
5
6
|
class
BaseHandler(tornado.web.RequestHandler):
def
initialize(
self
):
self
.session
=
db_session
def
on_finish(
self
):
self
.session.close()
|
初始化时 加载 session,
请求结束关闭session
Handler中就可以正常使用sqlalchemy的语法了
?
1
|
user
=
self
.session.query(User).filter_by(name
=
name).first()
|
在环境搭建好后需要初始化数据库
如下 :
?
1
2
3
4
5
6
7
|
import
models.userModel
def
init_db():
# 在这里导入定义模型所需要的所有模块,这样它们就会正确的注册在
# 元数据上。否则你就必须在调用 init_db() 之前导入它们。
#import yourapplication.models
Base.metadata.create_all(bind
=
engine)
|
记住,在 create_all 之前需要导入 准备好的model
删除所有表可以
?
1
2
3
4
5
6
7
|
def
drop_db():
#from models.userModel import User
"""
"""
Base.metadata.drop_all(engine)
|
正常开发中,数据库发生变动的情况还是蛮多的,版本管理就是个问题。
python3 的环境的话,推荐使用 alembic,是 sqlalchemy 作者写的
安装好 alembic后 cd 到你的目录文件夹,运行
?
1
|
alembic init alembic
|
会在同目录下生成 alembic.ini 和alembic 目录
打开alembic.ini 配置一下 数据库连接
?
1
|
sqlalchemy.url
=
mysql
+
mysqlconnector:
/
/
root:@localhost
/
demo?charset
=
utf8
|
然后 打开alembic 目录下的 env.py
在这 需要把
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
def
run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
engine
=
engine_from_config(
config.get_section(config.config_ini_section),
prefix
=
'sqlalchemy.'
,
poolclass
=
pool.NullPool)
connection
=
engine.connect()
context.configure(
connection
=
connection,
target_metadata
=
target_metadata
)
try
:
with context.begin_transaction():
context.run_migrations()
finally
:
connection.close()
|
这里面的 target_metadata 取成 自己的 sqlalchemy 的 metadata
所以在之前加上
?
1
2
3
|
sys.path.append(os.getcwd())
from
lib.db
import
Base
target_metadata
=
Base.metadata
|
这里要求就是
包含Base 所在包的路径
Base 在import进来的时候,所有model 必须加载到,也就是在 Base 所在文件里面 import 所有model
在命令行执行
?
1
|
alembic revision
-
-
autogenerate
-
m
"start"
|
配置正确的话,会在alembic/versions 目录下生成 XXXX_start.py ,里面就包含了 更改model后数据库自动升级的信息,大致如下
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# revision identifiers, used by Alembic.
revision
=
'12743faa412'
down_revision
=
None
from
alembic
import
op
import
sqlalchemy as sa
from
sqlalchemy.dialects
import
mysql
def
upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column(
'user_info_tab'
, sa.Column(
'mobile'
, sa.String(length
=
50
), nullable
=
True
))
op.alter_column(
'user_roleinfo_tab'
,
'id_no'
,
existing_type
=
mysql.VARCHAR(length
=
50
),
nullable
=
False
)
### end Alembic commands ###
def
downgrade():
### commands auto generated by Alembic - please adjust! ###
op.alter_column(
'user_roleinfo_tab'
,
'id_no'
,
existing_type
=
mysql.VARCHAR(length
=
50
),
nullable
=
True
)
op.drop_column(
'user_info_tab'
,
'mobile'
)
### end Alembic commands ###
|
然后在命令行执行
?
1
|
alembic upgrade head
|
就一步更新到位了。
也可以使用
?
1
|
alembic revision
-
m
"Add a column"
|
生成空白的版本文件,自己填充升级降级信息。
同样,也可以自由控制版本升降
?
1
2
3
|
alembic upgrade
+
2
alembic downgrade
-
1
alembic upgrade ae1(版本号)
|