SQLAlchemy 連接 MySQL 數據庫(二)

一、數據創建

如果想要和 MySQL 交談也得先通過 SQLAlchemy 建立一個會話:

from sqlalchemy.orm import sessionmaker

# 創建與數據庫的會話session class ,注意,這裏返回給session的是個class,不是實例
Session_class = sessionmaker(bind=engine)
session = Session_class()   # 生成session實例,相當於遊標

通過session對象,session可以記錄和跟蹤數據的改變,在適當的時候提交,並且支持強大的ORM的功能。生成會話之後,我們需要一些測試數據。而 Faker 就是用來生成虛假數據的庫。安裝:

$ pip install faker

下面結合 Faker 庫創建一些測試數據:

def Create(session):
    #創建了10個用戶
    faker_users = [User(
        username=faker.name(),
        password=faker.word(),
        email=faker.email(),
        ) for i in range(10)]
    session.add_all(faker_users)

    # 5個分類
    faker_categories = [Category(name=faker.word()) for i in range(5) ]
    session.add_all( faker_categories )
    # 20個標籤
    faker_tags = [Tag(name=faker.word()) for i in range(20)]
    session.add_all(faker_tags)
    # 100篇文章
    for i in range(100):
        article = Article(
            title = faker.sentence(),
            content = ' '.join( faker.sentences(nb=random.randint(10,20))),
            author = random.choice(faker_users),
            category = random.choice(faker_categories),
            )
        for tag in random.sample(faker_tags,random.randint(2,5)):
            article.tags.append(tag)
        session.add(article)

    session.commit()

if __name__ == '__main__':
    #Base.metadata.create_all(engine)

    faker = Factory.create()
    Session_class = sessionmaker(bind=engine)
    session = Session_class()

    Create(session)

在上面的代碼中我們創建了10個用戶,5個分類,20個標籤,100篇文章,並且爲每篇文章隨機選擇了2~5個標籤。

使用 SQLAlchemy 往數據庫中添加數據,我們只需要創建相關類的實例,調用 session.add() 添加一個,或者 session.add_all() 一次添加多個, 最後 session.commit() 就可以了。

二、查詢

數據庫最常用的就是查詢功能,這裏查詢(Query)對象就是通過Session會話的query()方法獲取的,需要注意的是這個方法的參數數目是可變的,也就是說我們可以傳入任意多的參數數目,參數的類型可以是任意的類組合或者是類的名稱。

1、返回列表和標量

(1).比如:

def Query_Iteration(session):
    # 此處得到Query對象返回的是一組可迭代的User實例表
    for user in session.query(User):
        print( "( username : %s ) , ( password : %s ),( email : %s )" 
            % (user.username,user.password , user.email) )

此處得到Query對象返回的是一組可迭代的User實例表,後我們通過for in語句訪問,依次輸出 用戶名:user.username , 密碼:user.password 和 郵箱:user.email 。
(2).當然如果只需要“用戶名”和“密碼”,對於對象實例的其他屬性不感興趣的話,也可以直接查詢它們(類的屬性名稱)

def Query_Iteration1(session):
    for name,password in session.query(User.username , User.password):
        print( " %s , %s " % ( name , password) ) 

(3).SQLAlchemy的Query對象可以通過Python數組分片來實現控制記錄的數目和位置。

def Query_Iteration2(session):
    for user in session.query(User).order_by(User.id)[1:3]:
        print(" %s , %s " % ( user.username,user.password) )

(4).假如我們需要篩選過濾特定結果,則可以使用filter_by()方法,這個方法使用關鍵詞參數:

def Query_Iteration3(session):
    for user in session.query(User).filter_by( username='Cheryl Jackson'):
        print(user.password)

此處說明查詢User表,按照User表中username=’Cheryl Jackson’過濾結果。

(5).Query對象的all()、one()以及first()方法將返回非迭代值,比如說all()返回的是一個列表,
first()方法限制並僅作爲標量返回結果集的第一條記錄,

2、使用原義SQL

Query對象能夠靈活的使用原義SQL查詢字符串作爲查詢參數。

def Query_SQL(session):
    users = session.execute('select * from users')
    for u in users:
        print(u)

三、更新和添加

# 更新一個字段
def Update(session):
    a = session.query(Article).get(10)
    a.title = 'test'
    session.add(a)
    session.commit() 

session.query(Article).get(10)返回的是Article表中第10條記錄。

# 插入新用戶,
def Add_User(session):
    new_user = User( username = 'wang' , password='23',email='[email protected]')
    session.add( new_user )
    session.commit()

四、刪除

def Delete(session):
    a = session.query(Article).get(10)
    session.delete(a)
    session.commit()

刪除直接調用 delete 刪除獲取到的對象,提交 session 即可。

五、完整代碼

# coding: utf-8

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, Integer , Text
from sqlalchemy.orm import relationship
from sqlalchemy import Table,ForeignKey

import random
from sqlalchemy.orm import sessionmaker
from faker import Factory

# 初始化數據庫連接:
# '數據庫類型+數據庫驅動名稱://用戶名:口令@機器地址:端口號/數據庫名'
engine = create_engine('mysql+pymysql://root:0208@localhost:3306/blog?charset=utf8')

# 創建對象的基類:
Base = declarative_base()

class User(Base):
    # 表的名字:
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    username = Column(String(64), nullable=False, index=True)
    password = Column(String(64), nullable=False)
    email    = Column(String(64), nullable=False, index=True)
    articles = relationship('Article' , backref='author')
    userinfo = relationship('UserInfo',backref='user',uselist=False)

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.username)

class Article(Base):
    __tablename__ = 'articles'
    id      = Column( Integer, primary_key =True )
    title   = Column( String(255) , nullable=False , index = True )
    content = Column(Text)
    user_id = Column(Integer,ForeignKey('users.id'))
    cate_id = Column(Integer, ForeignKey('categories.id'))
    tags = relationship('Tag', secondary='article_tag', backref='articles')

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__ , self.title)

class UserInfo(Base):
    __tablename__ = 'userinfos'
    id = Column(Integer, primary_key =True)
    name = Column( String(64))
    qq = Column(String(11))
    phone=Column(String(11))
    link=Column(String(64))
    user_id = Column(Integer,ForeignKey('users.id'))

class Category(Base):
    __tablename__ = 'categories'
    id = Column(Integer,primary_key=True)
    name = Column(String(64) ,nullable=False,index = True )
    articles = relationship('Article',backref='category')

# 中間表 自己創建。不需要手動管理,orm自動維護
article_tag = Table(
    'article_tag',Base.metadata,
    Column('article_id',Integer,ForeignKey('articles.id')),
    Column('tag_id',Integer,ForeignKey('tags.id'))
)

class Tag(Base):
    __tablename__='tags'
    id = Column(Integer,primary_key=True)
    name = Column( String(64) , nullable=False , index = True)

def CreateData(session):
    #創建了10個用戶
    faker_users = [User(
        username=faker.name(),
        password=faker.word(),
        email=faker.email(),
        ) for i in range(10)]
    session.add_all(faker_users)

    # 5個分類
    faker_categories = [Category(name=faker.word()) for i in range(5) ]
    session.add_all( faker_categories )
    # 20個標籤
    faker_tags = [Tag(name=faker.word()) for i in range(20)]
    session.add_all(faker_tags)
    # 100篇文章
    for i in range(100):
        article = Article(
            title = faker.sentence(),
            content = ' '.join( faker.sentences(nb=random.randint(10,20))),
            author = random.choice(faker_users),
            category = random.choice(faker_categories),
            )
        for tag in random.sample(faker_tags,random.randint(2,5)):
            article.tags.append(tag)
        session.add(article)

    session.commit()

# 更新一個字段
def Update(session):
    a = session.query(Article).get(20)
    a.title = 'test'
    session.add(a)
    session.commit() 

# 添加一個標籤,在  tags表中添加了新的字段
def Add(session):
    a = session.query(Article).get(20)
    a.tags.append( Tag(name='Python test'))
    session.add(a)
    session.commit()

def Delete(session):
    a = session.query(Article).get(10)
    session.delete(a)
    session.commit()

def Query_Iteration(session):
    # 此處得到Query對象返回的是一組可迭代的User實例表
    for user in session.query(User).order_by(User.id):
        print( "( username : %s ) , ( password : %s ),( email : %s )" 
            % (user.username,user.password , user.email) )

#當然如果只需要“用戶名”和“密碼”,也可以直接查詢它們(類的屬性名稱)
def Query_Iteration1(session):
    for name,password in session.query(User.username , User.password):
        print( " %s , %s " % ( name , password) ) 

def Query_Iteration2(session):
    for user in session.query(User).order_by(User.id)[1:3]:
        print(" %s , %s " % ( user.username,user.password) )

def Query_Iteration3(session):
    for user in session.query(User).filter_by( username='Cheryl Jackson'):
        print(user.password)

def Query_NonIterator(session):
        # all 則是獲取所有
    print(session.query(User).all() )

def Query_SQL(session):
    users = session.execute('select * from users')
    for u in users:
        print(u)

# 插入新用戶,
def Add_User(session):
    new_user = User( username = 'wang' , password='23',email='[email protected]')
    session.add( new_user )
    session.commit()

if __name__ == '__main__':
    #Base.metadata.create_all(engine)

    faker = Factory.create()
    Session_class = sessionmaker(bind=engine)
    session = Session_class()

    #CreateData(session)

    #Update(session)
    #Add(session)
    Add_User(session)

    #Delete(session)
    session.close()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章