SQLAlchemy通过models创建数据库表
定义数据模型 models
SQLAlchemy 允许我们根据数据库的表结构来创建数据模型, 反之亦可. 所以我们⼀般⽆须⼿动的登录到数据库中使⽤ SQL 语句来创建表, 我们只需把数据模型定义好了之后, 表结构也就有了.
⾸先要初始化 SQLAlchemy, 在 models.py 中把 app 对象传⼊ SQLAlchemy :
vim JmilkFan-s-Blog/models.py
sqlalchemy import SQLAlchemy
from main import app
# INIT the sqlalchemy object
# Will be load the SQLALCHEMY_DATABASE_URL from config.py
# SQLAlchemy 会⾃动的从 app 对象中的 DevConfig 中加载连接数据库的配置项
db = SQLAlchemy(app)
db 是 class SQLAlchemy 的实例化对象, 包含了 SQLAlchemy 对数据库操作的⽀持类集.
In [7]: db
Out[7]: <SQLAlchemy engine='mysql+pymysql://root:fanguiju@127.0.0.1:3306/myblog?charset=utf8'>
接下来, 我们就可以在 models.py 中定义 models 类了:
class User(db.Model):
"""Represents Proected users."""
# Set the name for table
__tablename__ = 'users'
id = db.Column(db.String(45), primary_key=True)
username = db.Column(db.String(255))
password = db.Column(db.String(255))
def __init__(self, username):
self.username = username
def __repr__(self):
"""Define the string format for instance of User."""
return "<Model User `{}`>".format(self.username)
这样我们就得到了⼀个 User models, 该模型是基于 users 表的. 该数据表拥有 3 个字段 id/username/password 对应这由 class db.Column 实例化出来的 3 个对象, 当 class User 继承⾃ db.Model 时, SQLAlchemy 与数据库的连接通过就已经⾃动的 Ready 了.
db.Column: 其构造器的第⼀个参数是可选的, 如果传⼊实参时, 表⽰创建的字段名. 反之, 则默认使⽤该实例化对象的名字(即 User 的类属性名); 第⼆个参数指定了字段的数据类型.
__init__(): 其实我们可以省略定义 class User 的构造器. 这样的话 SQLAlchemy 会⾃动帮我们创建构造器, 并且所有定义的字段名将会成为此构造器的关键字参数名. EXAMPLE:
def __init__(self, id, username, password):
1
__repr__(): 该⽅法返回⼀个对象的字符串表达式. 与 __str__() 不同, 前者返回的是字符串表达式, 能被 eval() 处理;后者返回的是字符串, 不能被 eval() 处理得到原来的对象, 但与 print 语句结合使⽤时, 会被默认调⽤. 与 repr() 类似, 将对象转化为便于供 Python 解释器读取的形式, 返回⼀个可以⽤来表⽰对象的可打印字符串.
In [15]:user = User('JMilkfan')
In [16]:user
<Model User `JMilkfan`>
# 直接调⽤对象实际上是隐式的调⽤了 User.__repr__(user)
# __repr__() 其定义了类实例化对象的可打印字符串表达式
1
2
3
4
5
6
创建表
在创建表之间需要先创建数据库
mysql -uroot -pfanguiju -e "CREATE DATABASE myblog default charset utf8 COLLATE utf8_general_ci;"
mysql -uroot -pfanguiju -e "GRANT ALL ON myblog.* TO 'user'@'127.0.0.1' IDENTIFIED BY 'fanguiju';"
mysql -uroot -pfanguiju -e "GRANT ALL ON myblog.* TO 'user'@'localhost' IDENTIFIED BY 'fanguiju';"
mysql -uroot -pfanguiju -e "GRANT ALL ON myblog.* TO 'user'@'%' IDENTIFIED BY 'fanguiju';"
指定数据库 myblog 的字符集为 utf8.
然后, 我们仍然可以通过 manage.py 来添加创建数据库表的指令:
# import Flask Script object
script import Manager, Server
import main
import models
# Init manager object via app object
manager = Manager(main.app)
# Create some new commands
manager.add_command("server", Server())
@manager.shell
def make_shell_context():
"""Create a python CLI.
return: Default import object
type: `Dict`
"""
return dict(app=main.app,
db=models.db,
User=models.User)
if __name__ == '__main__':
manager.run()
NOTE: 从现在开始我们每在 models.py 中新定义⼀个数据模型, 都需要在 manager.py 中导⼊并添加到返回 dict 中.
这样我们就可以通过 manager 的 shell 指令⾏来进⾏数据库表的创建了:
(blog)fanguiju@fanguiju:/opt/JmilkFan-s-Blog$ python manage.py shell
>>> db.create_all()
注意: 如果在进⼊ manager shell 时触发 ERROR 没有 这个模块的话, 应该检查 virtualenv 的环境是否正确, 是否有安装所需要的依赖包, 如果没有则执⾏:
pip install -
1
最后, 登录数据库验证数据表表是否由正确创建
mysql> show tables;
+------------------+
| Tables_in_myblog |
+------------------+
| users            |
+------------------+
1 row in set (0.00 sec)
mysql> desc users;
+----------+--------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id      | varchar(45)  | NO  | PRI | NULL    |      |
| username | varchar(255) | YES  |    | NULL    |      |
| password | varchar(255) | YES  |    | NULL    |      |
+----------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
以同样的⽅法我们可以创建所和需要的所有数据库表.
问题:
如题,我在学习《Flask Web开发:基于Python的Web应⽤开发实战》这本书第七章的时候,在shell中使⽤db.create_all()创建sqlite数据库。但是发现这个命令只能创建出sqlite⽂件,不能创建数据库table。
(venv) FlaskStudy$ python manage.py shell
>>> from app import db
>>> db.create_all()
⼏次尝试过后,发现如果在执⾏db.create_all()前导⼊我创建的数据库模型,就能正常的创建出表了:
(venv) FlaskStudy$ python manage.py shell
>>> from app import db
>>> dels import User, Role
>>> db.create_all()
或者在manage.py中导⼊数据库模型也可以:
import os
from app import create_app, db
#就是这⼀句
dels import User, Role
script import Manager, Shell
igrate import Migrate, MigrateCommand
app = create_v('FLASK_CONFIG') or 'default')
manager = Manager(app)
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
这是什么原理呢?求⼤神给讲解⼀下。
刚刚看完第7章。我感觉你的manager.py有点问题,缺少shell上下⽂,所以说你打开的就是⼀个普通的shell, 并不可以直接使⽤ app⾥⾯的变量,必须⼿动import。可以看看下⾯的代码,加上那⼏⾏代码就可以直接使⽤了。
sql数据库创建表步骤#!/usr/bin/env python
from app import create_app, db
dels import User, Role
script import Manager, Shell
app = create_app()
manager = Manager(app)
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role)
manager.add_command("shell", Shell(make_context=make_shell_context))
if __name__ == '__main__':
manager.run()

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。