一、SQLAlchemy
SQLAlchemy是Python程式語言下的一款ORM框架,該框架建立在資料庫API之上,使用關係物件對映進行資料庫操作,簡言之便是:將物件轉換成SQL,然後使用資料API執行SQL並獲取執行結果。
ORM方法論基於三個核心原則:
簡單:以最基本的形式建模資料。
傳達性:資料庫結構被任何人都能理解的語言文件化。
精確性:基於資料模型建立正確標準化了的結構。
Dialect用於和資料API進行交流,根據配置檔案的不同呼叫不同的資料庫API,從而實現對資料庫的操作,如:
‘資料庫型別+資料庫驅動名稱://使用者名稱:口令@機器地址:埠號/資料庫名’
MySQL-Python
1 |
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> |
pymysql
1 |
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> |
MySQL-Connector
1 |
mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> |
cx_Oracle
1 |
oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] |
更多詳見:http://docs.sqlalchemy.org/en/latest/dialects/index.html
注:
1 2 3 4 5 6 7 8 9 |
2.7版本使用mysqldb 3.5版本使用pymysql 請用pip或者原始碼包安裝,確保環境可以正常使用。** 確保遠端資料庫伺服器可以正常使用,並且擁有全新可以遠端登入, 例如: 登入資料庫:mysql -uroot -p 建立資料庫:create database liuyao; 授權庫:grant all on liuyao.* to liuyao@"%" identified by 'liuyao'; 更新:flush privileges; |
1.基本操作:
1)連結資料庫:create_engine()
1 2 3 4 5 6 7 8 9 10 11 |
engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5) create_engine() 會返回一個資料庫引擎, mysql+mysqldb”指定了使用 MySQL-Python 來連線, 使用使用者名稱‘liuyao’和密碼‘liuyao’來連結資料庫 121.42.195.15是資料庫連結地址可以是localhost,127.0.0.1 ‘liuyao’是資料庫名 max_overflow是最大連線數 其他方法: “charset”指定了連線時使用的字符集(可省略)=utf8 echo 引數為 True 時,會顯示每條執行的 SQL 語句,生產環境下可關閉。 |
2)欄位和資料型別及操作方法
在sqlalchemy.schema包裡有資料庫關係的描述,列舉幾個最常用的:
欄位:Column
索引:Index
表:Table
資料型別在sqlalchemy.types包,列舉幾個最常用的:
二進位制:BIGINT
布林:BOOLEAN
字元:CHAR
可變字元:VARCHAR
日期:DATETIME
其他方法 execute,update,insert,select,delete,join等 自行補腦
3)建立表結構
使用 Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 進行資料庫操作。Engine使用Schema Type建立一個特定的結構物件,之後通過SQL Expression Language將該物件轉換成SQL語句,然後通過 ConnectionPooling 連線資料庫,再然後通過 Dialect 執行SQL,並獲取結果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from sqlalchemy import create_engine, Table, Column, Integer, / String, MetaData, ForeignKey import MySQLdb #建立資料庫連線 engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5) # 獲取後設資料 metadata = MetaData() # 定義表 user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) color = Table('color', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) # 建立資料表,如果資料表存在,則忽視 metadata.create_all(engine) 結果: mysql> show tables; +------------------+ | Tables_in_liuyao | +------------------+ | color | | user | +------------------+ 2 rows in set (0.00 sec) |
3)插入一條資料
使用 Engine/ConnectionPooling/Dialect 進行資料庫操作,Engine使用ConnectionPooling連線資料庫,然後再通過Dialect執行SQL語句。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#!/usr/bin/env python3 #coding:utf8 from sqlalchemy import create_engine engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/ liuyao", max_overflow=5) engine.execute( "INSERT INTO liuyao.color(id, name) VALUES ('1', 'liuyao');" ) result = engine.execute('select * from color') print(result.fetchall()) 結果: [(1L, 'liuyao'), (2L, 'v1')] |
4) 增刪改查
先建立資料庫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#!/usr/bin/env python3 #coding:utf8 from sqlalchemy import create_engine, Table, Column, Integer, String,MetaData, ForeignKey metadata = MetaData() #建立資料庫引擎 engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/ liuyao", max_overflow=5) conn = engine.connect() #建立一個表叫做user 在liuyao庫裡 user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) color = Table('color', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) metadata.create_all(engine) |
增加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 建立SQL語句,INSERT INTO "user" (id, name) VALUES (:id, :name) conn.execute(user.insert(),{'id':7,'name':'seven'}) conn.close() # 或者按照下面的方式建立 # sql = user.insert().values(id=123, name='wu') # conn.execute(sql) # conn.close() 結果: mysql> show tables; +------------------+ | Tables_in_liuyao | +------------------+ | color | | user | +------------------+ 2 rows in set (0.00 sec) mysql> select * from user; +----+-------+ | id | name | +----+-------+ | 7 | seven | +----+-------+ 1 row in set (0.00 sec) |
刪除
1 2 3 4 5 6 7 8 9 10 11 12 |
#刪除一條user表裡的 條件是id大於1的 sql = user.delete().where(user.c.id > 1) #執行 conn.execute(sql) #關閉連結 conn.close() 結果: mysql> select * from user; Empty set (0.00 sec) mysql> #因表裡只有一條資料,刪除之後,沒有任何資料存在 |
修改/更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
先建立幾條資料步驟略 顯示如下: mysql> select * from user; +----+--------+ | id | name | +----+--------+ | 1 | liuyao | | 2 | liuyao | | 3 | yaoyao | | 4 | yao | +----+--------+ 4 rows in set (0.00 sec) #更新 #把名字為liuyao的修改為no1 sql = user.update().where(user.c.name == 'liuyao').values(name='no1') conn.execute(sql) conn.close() 結果: mysql> select * from user; +----+--------+ | id | name | +----+--------+ | 1 | no1 | | 2 | no1 | | 3 | yaoyao | | 4 | yao | +----+--------+ 4 rows in set (0.00 sec) |
查詢
注:請匯入查詢模組
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
from sqlalchemy import select 其他模組同上 #查詢user表裡的內容 sql = select([user, ]) res =conn.execute(sql) print res.fetchall() conn.close() 結果: [(1L, 'no1'), (2L, 'no1'), (3L, 'yaoyao'), (4L, 'yao')] #查詢user表下的id sql = select([user.c.id, ]) res =conn.execute(sql) print res.fetchall() conn.close() 結果: [(1L,), (2L,), (3L,), (4L,)] #查詢user表和color表的name,條件是user表的id1=color的id1 sql = select([user.c.name, color.c.name]).where(user.c.id==color.c.id) 結果: [('no1', 'liuyao'), ('no1', 'v1')] #查詢user表的name,並按照條件排序 #按照名字排序 sql = select([user.c.name]).order_by(user.c.name) res =conn.execute(sql) print res.fetchall() conn.close() 結果: [('no1',), ('no1',), ('yao',), ('yaoyao',)] #按照id排序 sql = select([user.c.name]).order_by(user.c.id) res =conn.execute(sql) print res.fetchall() conn.close() 結果: [('no1',), ('no1',), ('yaoyao',), ('yao',)] #查詢user表的name,並按照條件分組 sql = select([user]).group_by(user.c.name) res =conn.execute(sql) print res.fetchall() conn.close() 結果: [(1L, 'no1'), (4L, 'yao'), (3L, 'yaoyao')] #按照id 結果: [(1L, 'no1'), (2L, 'no1'), (3L, 'yaoyao'), (4L, 'yao')] |
5)繼承SqlORM類來運算元據庫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#!/usr/bin/env python3 #coding:utf8 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker Base = declarative_base() #生成一個SqlORM 基類 engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao",echo=True) #echo如果為True,那麼當他執行整個程式碼的資料庫的時候會顯示過程 #建立一個類繼承Base基類 class Host(Base): #表名為hosts __tablename__ = 'hosts' #表結構 #primary_key等於主鍵 #unique唯一 #nullable非空 id = Column(Integer,primary_key=True,autoincrement=True) hostname = Column(String(64),unique=True,nullable=False) ip_addr = Column(String(128),unique=True,nullable=False) port = Column(Integer,default=22) Base.metadata.create_all(engine) #建立所有表結構 if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) #bind繫結 #建立與資料庫的會話session class #注意,這裡返回給session的是個class,不是例項 session = SessionCls() #插入欄位 h1 = Host(hostname='qd115',ip_addr='115.29.51.8') h2 = Host(hostname='ubuntu',ip_addr='139.129.5.191',port=80) h3 = Host(hostname='mysql',ip_addr='121.42.195.15',port=3306) #新增一個 #session.add(h3) #可以新增多個欄位 session.add_all( [h1,h2,h3]) #修改欄位名字,只要沒提交,此時修改也沒問題 #h2.hostname = 'ubuntu_test' #支援資料回滾 #session.rollback() #提交 session.commit() 結果: mysql> select * from hosts; +----+----------+---------------+------+ | id | hostname | ip_addr | port | +----+----------+---------------+------+ | 1 | qd115 | 115.29.51.8 | 22 | | 2 | ubuntu | 139.129.5.191 | 80 | | 4 | mysql | 121.42.195.15 | 3306 | +----+----------+---------------+------+ 3 rows in set (0.00 sec) |
注:SQLAlchemy無法修改表結構,如果需要可以使用SQLAlchemy開發者開源的另外一個軟體Alembic來完成。
6.繼承類式增刪改查:
使用 ORM/Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 所有元件對資料進行操作。根據類建立物件,物件轉換成SQL,執行SQL。
Query物件可以返回可迭代的值(iterator value),然後我們可以通過for in來查詢。不過Query物件的all()、one()以及first()方法將返回非迭代值(non-iterator value),比如說all()返回的是一個列表first()方法限制並僅作為標量返回結果集的第一條記錄:
1)先建立相關資料庫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#!/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine #建立資料庫 engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5) #生成一個SqlORM 基類 Base = declarative_base() #定義表結構 class User(Base): #表名 __tablename__ = 'users' #定義id,主鍵唯一, id = Column(Integer, primary_key=True) name = Column(String(50)) #尋找Base的所有子類,按照子類的結構在資料庫中生成對應的資料表資訊 Base.metadata.create_all(engine) #建立與資料庫的會話session class ,注意,這裡返回給session的是個class,不是例項 Session = sessionmaker(bind=engine) session = Session() #獲取session,然後把物件新增到session, #最後提交併關閉。Session物件可視為當前資料庫連線。 |
2.增加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
########### 增 ########## #定義一個欄位 zengjia = User(id=2, name='sbliuyao') #新增欄位 session.add(zengjia) #新增多個欄位 session.add_all([ User(id=3, name='sbyao'), User(id=4, name='liuyao') ]) #提交以上操作 session.commit() 結果: mysql> select * from users; +----+----------+ | id | name | +----+----------+ | 2 | sbliuyao | | 3 | sbyao | | 4 | liuyao | +----+----------+ 3 rows in set (0.00 sec) |
3.刪除
1 2 3 4 5 6 7 8 9 10 11 12 |
# ########## 刪除 ########## #刪除user表,id大於2的欄位 session.query(User).filter(User.id > 2).delete() session.commit() 結果: mysql> select * from users; +----+----------+ | id | name | +----+----------+ | 2 | sbliuyao | +----+----------+ 1 row in set (0.00 sec) |
4.修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
因上次操作已經刪除好多資料 請重新執行插入欄位操作 session.add_all([ User(id=3, name='sbyao'), User(id=4, name='liuyao'), User(id=5, name='mayun') ]) session.commit() 結果: mysql> select * from users; +----+----------+ | id | name | +----+----------+ | 2 | sbliuyao | | 3 | sbyao | | 4 | liuyao | | 5 | mayun | +----+----------+ 4 rows in set (0.00 sec) 在執行以下操作 #user表裡的id等於2的欄位修改為id=6 session.query(User).filter(User.id == 2).update({'id' : 6}) session.commit() 結果: mysql> select * from users; +----+----------+ | id | name | +----+----------+ | 3 | sbyao | | 4 | liuyao | | 5 | mayun | | 6 | sbliuyao | +----+----------+ 4 rows in set (0.00 sec) 其他方法: #把user表裡id大於2的name全部換成woshiyaoge session.query(User).filter(User.id > 2).update({'name' :'woshiyaoge'}) session.commit() mysql> select * from users; +----+------------+ | id | name | +----+------------+ | 3 | woshiyaoge | | 4 | woshiyaoge | | 5 | woshiyaoge | | 6 | woshiyaoge | +----+------------+ 4 rows in set (0.00 sec) |
5.查詢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
資料庫如下: mysql> select * from users; +----+------------+ | id | name | +----+------------+ | 3 | woshiyaoge | | 4 | woshiyaoge | | 5 | woshiyaoge | | 6 | woshiyaoge | | 7 | sbyao | | 8 | liuyao | | 9 | mayun | +----+------------+ 7 rows in set (0.00 sec) 方式1: #查詢user表下面name=liuyao的欄位 ret = session.query(User).filter_by(name='liuyao').all() #列印例項 print ret for i in ret: #列印結果 print(i.id,i.name,) 結果: [<__main__.User object at 0x0000000002F55860>] (8L, 'liuyao') 這種查詢方法可以返回一個User物件以及它的name屬性欄位的值。 方式2: #查詢user表裡欄位是name=liuyao的第一條資料 ret = session.query(User).filter_by(name='liuyao').first() print ret.name print ret.id 結果: liuyao 8 方式3: #查詢user表裡欄位是name是liuyao或者mayun的資訊列印出來 ret = session.query(User).filter(User.name.in_(['liuyao','mayun'])).all() print ret for i in ret: print(i.name,i.id) 結果: [<__main__.User object at 0x00000000030F1E48>, <__main__.User object at 0x000000000311D8D0>] ('liuyao', 8L) ('mayun', 9L) 方式4: #可以給返回的結果起一個別名,或者叫標籤:可有可無 ret = session.query(User.name.label('')).all() print ret,type(ret) 這裡的關鍵是label方法,它的意思是把User的name欄位改個名字叫name_label, 其相當於執行以下的SQL語句: SELECT users.name AS name_label FROM users 結果: [('woshiyaoge',), ('woshiyaoge',), ('woshiyaoge',), ('woshiyaoge',), ('sbyao',), ('liuyao',), ('mayun',)] <type 'list'> 方式5: #查詢User表根據id排序 ret = session.query(User).order_by(User.id).all() print ret for i in ret: print(i.name) 結果: [<__main__.User object at 0x00000000031978D0>, <__main__.User object at 0x0000000003197978>, <__main__.User object at 0x00000000031979E8>, <__main__.User object at 0x0000000003197A58>, <__main__.User object at 0x000000000316BE10>, <__main__.User object at 0x000000000316BE48>, <__main__.User object at 0x0000000003197940>] woshiyaoge woshiyaoge woshiyaoge woshiyaoge sbyao liuyao mayun 方式6: #查詢user表裡根據id排序輸入0到3的欄位 ret = session.query(User).order_by(User.id)[0:3] print ret for i in ret: print(i.name) 結果: [<__main__.User object at 0x00000000030F59E8>, <__main__.User object at 0x00000000030C9E80>, <__main__.User object at 0x00000000030C9C88>] woshiyaoge woshiyaoge woshiyaoge 方式7: # 建立Query查詢,filter是where條件,最後呼叫one()返回唯一行,如果呼叫all()則返回所有行: user = session.query(User).filter(User.id=='5').one() #列印型別和物件的name屬性: print 'type:', type(user) print 'name:', user.name |
7.外來鍵關聯
由於關聯式資料庫的多個表還可以用外來鍵實現一對多、多對多等關聯,相應地,ORM框架也可以提供兩個物件之間的一對多、多對多等功能。
1)一對多(一個User可以有多個Address)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
外來鍵引用relationship() 例: #!/usr/bin/env python3 #coding:utf8 #匯入所需模組 from sqlalchemy import create_engine,func from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String,ForeignKey from sqlalchemy.orm import sessionmaker,relationship #生成sqlorm基類 Base = declarative_base() #建立資料庫連線 engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5) #目的是一個人可以擁有多本書,那麼在資料庫裡的一對多關係 class User(Base): #表名 __tablename__ = 'user' #id欄位 id = Column(String(20), primary_key=True) #名字欄位 name = Column(String(20)) # 一對多:#內容不是表名而是定義的表結構名字 books = relationship('Book') class Book(Base): #表面 __tablename__ = 'book' #id欄位 id = Column(String(20), primary_key=True) #名字欄位 name = Column(String(20)) # “多”的一方的book表是通過外來鍵關聯到user表的: #ForeignKey是外來鍵 關聯user表的id欄位 user_id = Column(String(20), ForeignKey('user.id')) #建立所需表 Base.metadata.create_all(engine) if __name__ == '__main__': #繫結,生成回話 SessionCls = sessionmaker(bind=engine) session = SessionCls() #建立使用者 liuyao = User(id='1',name='liuyao') ali=User(id='2',name='ali') #新增欄位 session.add_all([liuyao,ali]) #提交 session.commit() #建立白鹿原這本書,指定誰是擁有者 Whitedeer = Book(id='1',name='White_deer',user_id = '1') #建立三體這本書,指定誰是擁有者 Threebody = Book(id='2',name='Three_body',user_id = '2') #新增欄位 session.add_all([Whitedeer,Threebody]) #提交 session.commit() |
結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
表: mysql> show tables; +------------------+ | Tables_in_liuyao | +------------------+ | book | | user | +------------------+ rows in set (0.00 sec) user表: mysql> select * from user; +----+--------+ | id | name | +----+--------+ | 1 | liuyao | | 2 | ali | +----+--------+ 2 rows in set (0.00 sec) book表#已經顯示關聯哪個user表id mysql> select * from book; +----+------------+---------+ | id | name | user_id | +----+------------+---------+ | 1 | White_deer | 1 | | 2 | Three_body | 2 | +----+------------+---------+ 2 rows in set (0.00 sec) |
2)多對多
建立一個雙向一對多關係,“反向”是一個許多人,指定一個額外的relationship()函式
並連線兩個使用relationship.back_populates引數
簡單來說, relationship函式是sqlalchemy對關係之間提供的一種便利的呼叫方式, backref引數則對關係提供反向引用的宣告。在最新版本的sqlalchemy中對relationship引進了back_populates引數。
先建立資料庫:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#!/usr/bin/env python3 #coding:utf8 from sqlalchemy import Column, Sequence, String, Integer, ForeignKey from sqlalchemy import create_engine # 匯入建立連線驅動 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import relationship, backref # 這個url可以用urlparse解析, 其中echo=True表示執行時顯示sql語句 engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5) #生成了declarative基類, 以後的model繼承此類 Base = declarative_base() class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) name = Column(String(64),unique=True,nullable=False) children = relationship("Child", back_populates="parent") class Child(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True) name = Column(String(64),unique=True,nullable=False) parent_id = Column(Integer, ForeignKey('parent.id')) parent = relationship("Parent", back_populates="children") Base.metadata.create_all(engine) #建立所有表結構 if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) #建立與資料庫的會話session class ,注意,這裡返回給session的是個class,不是例項 session = SessionCls() mama = Parent(id='1',name='mamaxx') baba = Parent(id='2',name='babaoo') session.add_all([mama,baba]) # onesb = Child(id='1',name='onesb',parent_id='2') # twosb = Child(id='2',name='twosb',parent_id='2') #session.add_all([onesb,twosb]) session.commit() |
3.)多對多之三表外來鍵關聯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#!/usr/bin/env python3 #coding:utf8 from sqlalchemy import create_engine,func,Table from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String,ForeignKey from sqlalchemy.orm import sessionmaker,relationship Base = declarative_base() #關係表 Host2Group = Table('host_2_group',Base.metadata, Column('host_id',ForeignKey('hosts.id'),primary_key=True), Column('group_id',ForeignKey('group.id'),primary_key=True), ) engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5) class Host(Base): __tablename__ = 'hosts' id = Column(Integer,primary_key=True,autoincrement=True) hostname = Column(String(64),unique=True,nullable=False) ip_addr = Column(String(128),unique=True,nullable=False) port = Column(Integer,default=22) groups = relationship('Group', secondary= Host2Group, backref = 'host_list') class Group(Base): __tablename__ = 'group' id = Column(Integer,primary_key=True) name = Column(String(64),unique=True,nullable=False) if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) session = SessionCls() g1 = Group(name='g1') g2 = Group(name='g2') g3 = Group(name='g3') g4 = Group(name='g4') session.add_all([g1,g2,g3,g4]) session.commit() |
請使用手機”掃一掃”x