経験的記憶喪失(純手作業)=>Python-ORMのpeewee:モデル-フィールド-インデックス-制約-トランザクション(一)


前言
githubに行って「python orm」を検索すると、最高starは意外にもsqlalchemyではなく、peeweeが後にpeeweeを知って、sqlalchemyより簡単で使いやすい.学ぶ価値があるよ!!私は全体的に感じています(peeweeはDjango-ORMの分離版のようですが、Django-ORMやSqlAlchemyより小さく、簡単で、ドキュメントも友好的です)
もう一つ重要な感じは、peeweeのAPIメソッド名がSQL文の単語とほぼ似ていることです.たとえば、比較してみましょう(キーワード構文はupdateとwhereです):
SQL  :update Lang set name='Python' where name='Java';
Peewee:Lang.update(name='Python').where(Lang.name == 'Java')

この良心的なAPIは、私たちの学习コストを大幅に下げることができて、また私たちのSQLに対する记忆を强化することができます!!!管理職住所:http://docs.peewee-orm.com/en...公式Githubアドレス:https://github.com/coleifer/p...
インストールとインポート
pip install peewee
from peewee import *
# peewee       ,  peewee ,         。         ,    
#        ,        。     。

データベース#データベース#
postgresqlとsqlite
peeweeはsqlite、mysql、postgresqlデータベースのみをサポートしています.oracleなどを使う必要がある場合は、迂回してください.のsqliteとpostgresqlが必要な場合は、構成を参照してください.http://docs.peewee-orm.com/en...
mysql
もちろん私はよくMySQLを使っていますが、これからのすべてはmysqlをめぐって、以下のように基本的な構成です.
mysql_db = MySQLDatabase(
    'lin',                 #    
    user='root',           #    
    password='123',        #   
    host='IP',             # IP
    port=3306,             #   
    charset='utf8mb4'      #      , utf8mb4   utf8   
)

peeweeのmysqlエンジンのデフォルトではpymysqlが優先されます.pymysqlをインストールしていない場合は、MySQLdbを探します.ないと間違いを報告します.ええ、もう何年代ですか.python 3の時代ですから、pymysqlモジュールを使えばいいです.インストールしていなければ、飛び出してインストールすればいいです.
pip install pymysql

pymysqlで駆動する以上、MySQLDatabase()の書き方はpymysqlオブジェクトのインスタンス化パラメータ構成と同じです.私があげた例のパラメータが足りない場合は、次のリンクに来て自分で選んでください.https://github.com/PyMySQL/Py...
データベース接続の確立
print(mysql_db.connect())

データベース接続を閉じる
print(mysql_db.close())

データベース接続が停止しているかどうかをテストします
mysql_db.is_closed()

データベースのすべてのテーブルをリストします.
mysql_db.get_tables()   

すべてのフィールドの詳細を表示します.
print(db.get_columns('owner'))    #    owner   ,    

すべてのプライマリ・キーのフィールドをリストします.
print(db.get_primary_keys('owner'))

すべての索引フィールドの詳細を表示します.
print(db.get_indexes('owner'))

すべての外部キーのフィールドをリストします.
print(db.get_foreign_keys('owner'))

Python各種webフレームワーク埋め込みpeeweeケース転送ゲート:官档-webケース:http://docs.peewee-orm.com/en...
表→レコード→フィールド
ORM構文とデータベースの対応関係は次のとおりです.
ORM構造
データベース#データベース#
クラス#クラス#

インスタンス(オブジェクト)
きろく
クラス属性

デフォルト自己増分キーID
クラスを定義し、peeweeモジュールのModelクラスを継承します.このクラスはModelとして使用できます.まず「空のテーブル」を作成します.
mysql_db = MySQLDatabase('lin_test', user='root', password='123',
                     host='ip', port=3306, charset='utf8mb4')
class Owner(Model):
    class Meta:             
        database=mysql_db   #    "  "     ,        
mysql_db.create_tables([Owner])    #   ,         ,         

上記のコードでは、空のテーブルを作成できます.なぜ「空のテーブル」は引用符で囲まれているのでしょうか.
    peewee orm   ,"     (primary key)",   "  "      
"   id", "    int",      "primary"   "  (auto_increment)"    

ただし、カスタムフィールドをプライマリ・キーに設定すると、デフォルトのidフィールドが上書きされます.
name = CharField(primary_key=True)   # name     ,      id    

官档も、自分で自増プライマリ・キーを作成し、デフォルトidを上書きしたい場合に説明しています.AutoFieldフィールドを使用できます.
new_id = AutoField()    #              int          。 
"         id   ,           Integer,    "

IDを増やしてから話しましたが、クラスごとに
class Meta:
    database= xxx   #            ,      。                

それなら、1つのデータベースに多くのテーブルを作成するには、毎回テーブルごとにデータベースを指定する必要がありますか?このように:
class User(Model):
    class Meta:
        database = mysql_db

class Owner(Model):
    class Meta:
        database = mysql_db

これは少し煩わしいですが、ベースクラスを定義してデータベースを指定し、他のサブクラスモデルが継承すればいいです.
class BaseModel(Model):
    name = CharField(max_length=10)    #      name   
    class Meta:
        database = mysql_db
        
class User(BaseModel):    #     
    pass
class Owner(BaseModel):   #     
    pass
    
mysql_db.create_tables([User, Owner])    #      ,      ,      

上記のコードCharFieldのように、より多くのタイプのフィールド定義は、官档が詳細に与えられているので、私はこれ以上説明しません.官職-フィールド-パラメータ:http://docs.peewee-orm.com/en...しかし、次は主によく使われる(少し難しい)ものを選んで話します.の
外部キーフィールド(ForeignKeyField)
一般外部キー
class BaseModel(Model):    #   
    name = CharField(max_length=10)
    class Meta:
        database = mysql_db

class Owner(BaseModel):   #    
    pass

class Pet(BaseModel):     #    
    owner = ForeignKeyField(
        Owner, 
        backref='owner_conn',  #          。"  ,            "
        on_delete='Cascade',   #     
            #    None,   ,          。   。           。
            #    Cascade ,         。             。        
        on_update=Cascade,     #     ,    on_delete
    )

階層外部キー(通常は階層分類、自己関連クエリー)
class Category(BaseModel):
    name = CharField()
    parent = ForeignKeyField('self', null=True, backref='children') 
     : "self"         ,       ,     

日付フィールド(DateTimeField)
import datetime
......
date_time= DateTimeField(default=datetime.datetime.now) 

表のプロパティ(Meta)
テーブルのプロパティは、テーブル名を変更したり、プライマリ・キーを設定したり、プライマリ・キーを結合したり、インデックスを設定したり、インデックスを結合したりする操作です.余計なことは言わないで,官職に会う.官档Meta:http://docs.peewee-orm.com/en...
索引と制約
インデックスを設定するには、次の3つの方法があります.
  • フィールドのパラメータを定義することによって:一般インデックス
    name = CharField(index=True)
    一意インデックス
    name = CharField(unique=True)
  • テーブル属性Metaを定義することによって:ユニークインデックス
    class Meta:
        indexes = (
            (('  1', '  2'), True),    #   1   2      ,True       
            (('  1', '  2'), False),   #   1   2      ,False       
        )
          ,    ,      ,      ,           ,   。    。
  • を結合する.
  • インデックスAPI:官档:http://docs.peewee-orm.com/en...

  • コンストレイントを設定するには、次の2つの方法があります.
  • フィールドのパラメータを定義する:------通常、単一フィールドのプライマリ・キーとして使用される:
    name = CharField(primary_key=True)
  • テーブル属性Metaを定義することによって、一般的に結合キーとして使用される:
    class Meta:
        primary_key = CompositeKey('  1', '  2')
        # primary_key = False      #         (   ,         id  )
    
  • 取引
    withコンテキスト構文をサポートし、トランザクションのネストをサポートします.ネストされたトランザクションは、最も近いレイヤ間のコードだけをロールバックすることに注意してください.with文に包まれたコードは,異常がある限りロールバックする.ネストされたトランザクションにも例外があり、すべてのレイヤのトランザクションがロールバックされます.もちろん、手動rollback()でロールバックすることもできます.ネストされたトランザクションの例は次のとおりです.
    with mysql_db.atomic() as transaction1:    #      。  atomic(),         。 
        User.create(username='Tom')
        with mysql_db.atomic() as transaction2: #      
            User.create(username='Jerry')
            User.create(username='Spike')
            transaction2.rollback()            #     ,     rollback()  
        User.create(username='Butch')
        
    #         ,          with()         ,   rollback()   
    #         :             with()   ,            rollback()
    
    #     ,       ,    with         (  with as     )。 
    #             ,           (    )。       。
    #     :       : transaction2.rollback()     transaction1.rollback()。   !

    commit()を持つネストされたトランザクションの例は次のとおりです.(トランザクションのコード範囲を縮小すると、「パンに挟まれたものが少なくなった」という意味)
    with mysql_db.atomic() as transaction1:      #      
        User.create(username='Tom')
        with mysql_db.atomic() as transaction2:  #      
            User.create(username='Jerry')
            transaction2.commit()                #      ,       commit
            User.create(username='Spike')
            transaction2.rollback()  # rollback()  
        User.create(username='Butch')
    
    # commit(),      ,                 ,  rollback()   
    #         : (        commit()      ,           rollback() )

    上記のトランザクションの例では、次の点に注意してください.
  • 各層のトランザクションは、自分のレイヤ内のrollback()にかかわらず有効であり、他のレイヤを管理することはできません.
  • commit()クリップを使っても、自分の層内にrollback()がなければ、あなたのcommit()は無効です(クリップできません)
  • トランザクションはそれほど悪くありません.官職にはいくつかの使い方と文法がありますが、最終的な機能の結果は同じです.一つ(私の例)を選べばいいです.官職-取引:http://docs.peewee-orm.com/en...
    雑用法
    ORM対応のオリジナルSQL文を表示するには、次の手順に従います.
    .....ORM  .sql()       #    .sql()       sql

    オリジナルSQLの実行:
    #   ,      ,        ( SQL  )
    for owner in Owner.raw('select * from owner where name=%s', 'Alice'):
        print(owner.name)
    

    よりネイティブな実行ネイティブSQL:
    print(mysql_db.execute_sql('select * from user').fetchall())
    # sql,       (   ),     pymysql  。

    表の名前変更:
     :              
    
           ,        ,   :    .alias('    ')
            , 2   :
          1:
              :   .alias('   ')
          2:
              :     =   .alias()

    未完語
    本編では、データベース、トランザクション、インデックスなど、入門的なモデルの構築について説明します.もちろんもっとよく使われる、もっと大切なCRUDなど、次の記事でご紹介します.次の転送ゲート:https://segmentfault.com/a/11...