SQLAlchemy通過models創建數據庫表


原地址:http://blog.csdn.net/jmilk/article/details/53184903

 

定義數據模型 models

SQLAlchemy 允許我們根據數據庫的表結構來創建數據模型, 反之亦可. 所以我們一般無須手動的登錄到數據庫中使用 SQL 語句來創建表, 我們只需把數據模型定義好了之后, 表結構也就有了.

  • 首先要初始化 SQLAlchemy, 在 models.py 中把 app 對象 傳入 SQLAlchemy :
    vim JmilkFan-s-Blog/models.py
from flask.ext.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 from flask.ext.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 沒有 flask.ext 這個模塊的話, 應該檢查 virtualenv 的環境是否正確, 是否有安裝所需要的依賴包, 如果沒有則執行:

pip install -r requirements.txt
  • 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中使用flask-sqlalchemy時db.create_all()無法創建表

如題,我在學習《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 >>> from app.models import User, Role >>> db.create_all()

或者在manage.py中導入數據庫模型也可以:

import os from app import create_app, db # 就是這一句 from app.models import User, Role from flask.ext.script import Manager, Shell from flask.ext.migrate import Migrate, MigrateCommand app = create_app(os.getenv('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。 可以看看下面的代碼,加上那幾行代碼就可以直接使用了。

#!/usr/bin/env python

from app import create_app, db from app.models import User, Role from flask.ext.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() 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM