Sanicチュートリアル:5.データベース使用{{でーたべーす:しよう}}
8509 ワード
説明では、
操作Mysql
mysqlデータベースの非同期操作については、いくつかのスクリプトでしか使用したことがありません.aiomysqlを使用しています.公式ドキュメントでは、
次に、非同期文でデータベースを操作する具体的な例を作成します.まず、次のディレクトリを作成します.
テーブルの作成:
準備が整いました.次はコードを書きます.
python demoを実行します.py、次の出力が表示されます.
簡単ですね.具体的な例はaio_を参照してください.mysql、SQLAlchemyのような操作が好きな場合は、非同期ORM、ginoをお勧めします.
操作MongoDB
私のアマチュアの书く1つのプロジェクト、基本的に
私が最初に使用したのは、
MotorBaseインスタンスの重複作成を回避するために、リソースの有効利用を保証するための単一のモードを実現することができます.具体的なコードとdemoの実行はaio_を参照してください.mongo
操作Redis
Redisの非同期操作については、
redis接続プールを作成するには、次の手順に従います.
具体的にはaio_を参照redis、使うのは簡単で、多くの叙述をしません.
説明
他のタイプのデータベースを使用する場合も、実際には同じように使用されます.この章のコードアドレスはdemo 05を参照してください
Sanic
はasync/await
構文を使用してプロジェクトを記述できる非同期非ブロックフレームワークであり、非同期フレームワークである以上、使用中に使用されるサードパーティ製パッケージも非同期であることが望ましい.例えばhttpリクエストでは、aihttp
ではなくrequests
を使用することが望ましい.データベースへの接続についても同様である.次に、Sanicでデータベースに接続する方法をコード形式で説明します.操作Mysql
mysqlデータベースの非同期操作については、いくつかのスクリプトでしか使用したことがありません.aiomysqlを使用しています.公式ドキュメントでは、
sqlalchemy
を組み合わせてORM
を作成し、aiomysqlが独自に作成した非同期エンジンを提供しています.from aiomysql.sa import create_engine
#
次に、非同期文でデータベースを操作する具体的な例を作成します.まず、次のディレクトリを作成します.
aio_mysql
├── demo.py
├── model.py
└── requirements.txt
テーブルの作成:
create database test_mysql;
CREATE TABLE user
(
id INT AUTO_INCREMENT
PRIMARY KEY,
user_name VARCHAR(16) NOT NULL,
pwd VARCHAR(32) NOT NULL,
real_name VARCHAR(6) NOT NULL
);
準備が整いました.次はコードを書きます.
# script: model.py
import sqlalchemy as sa
metadata = sa.MetaData()
user = sa.Table(
'user',
metadata,
sa.Column('id', sa.Integer, autoincrement=True, primary_key=True),
sa.Column('user_name', sa.String(16), nullable=False),
sa.Column('pwd', sa.String(32), nullable=False),
sa.Column('real_name', sa.String(6), nullable=False),
)
# script: demo.py
import asyncio
from aiomysql.sa import create_engine
from model import user,metadata
async def go(loop):
"""
aiomysql :https://github.com/aio-libs/aiomysql
:param loop:
:return:
"""
engine = await create_engine(user='root', db='test_mysql',
host='127.0.0.1', password='123456', loop=loop)
async with engine.acquire() as conn:
await conn.execute(user.insert().values(user_name='user_name01', pwd='123456', real_name='real_name01'))
await conn.execute('commit')
async for row in conn.execute(user.select()):
print(row.user_name, row.pwd)
engine.close()
await engine.wait_closed()
loop = asyncio.get_event_loop()
loop.run_until_complete(go(loop))
python demoを実行します.py、次の出力が表示されます.
user_name01 123456
簡単ですね.具体的な例はaio_を参照してください.mysql、SQLAlchemyのような操作が好きな場合は、非同期ORM、ginoをお勧めします.
操作MongoDB
私のアマチュアの书く1つのプロジェクト、基本的に
MongoDB
を使ってデータを贮蔵して、非同期の操作MongoDB
に対して、现在Pythonは主にmotorを使って、使うのは依然としてとても简単で、しかし具体的な机能を结び付けて、异なる需要があって、最后に各种の接続方案を形成して、ここで私は主に自分がどのように使うのかを分かち合って、ディレクトリは次のとおりです.aio_mongo
├── demo.py
└── requirements.txt
MongoDB
は、リレーショナル・データベースと非リレーショナル・データベースの間にある分散ファイル・ベースのデータベースであるため、使用も柔軟であり、demo.py
を開きます.#!/usr/bin/env python
import os
from functools import wraps
from motor.motor_asyncio import AsyncIOMotorClient
MONGODB = dict(
MONGO_HOST=os.getenv('MONGO_HOST', ""),
MONGO_PORT=os.getenv('MONGO_PORT', 27017),
MONGO_USERNAME=os.getenv('MONGO_USERNAME', ""),
MONGO_PASSWORD=os.getenv('MONGO_PASSWORD', ""),
DATABASE='test_mongodb',
)
class MotorBaseOld:
"""
db ,
"""
_db = None
MONGODB = MONGODB
def client(self, db):
# motor
self.motor_uri = 'mongodb://{account}{host}:{port}/{database}'.format(
account='{username}:{password}@'.format(
username=self.MONGODB['MONGO_USERNAME'],
password=self.MONGODB['MONGO_PASSWORD']) if self.MONGODB['MONGO_USERNAME'] else '',
host=self.MONGODB['MONGO_HOST'] if self.MONGODB['MONGO_HOST'] else 'localhost',
port=self.MONGODB['MONGO_PORT'] if self.MONGODB['MONGO_PORT'] else 27017,
database=db)
return AsyncIOMotorClient(self.motor_uri)
@property
def db(self):
if self._db is None:
self._db = self.client(self.MONGODB['DATABASE'])[self.MONGODB['DATABASE']]
return self._db
私が最初に使用したのは、
MongoDB
を接続するために使用され、上のコードは集合中のdbが_dbメンテナンスは、一度しか作成されないことを保証します.プロジェクトで勝手にコレクションを変更しない場合は、大きな問題はありません.そうでない場合は、次のような接続方法で、コレクションとdbを自由に交換することをお勧めします.def singleton(cls):
"""
:https://github.com/howie6879/Sanic-For-Pythoneer/blob/master/docs/part2/%E9%99%84%E5%BD%95%EF%BC%9A%E5%85%B3%E4%BA%8E%E8%A3%85%E9%A5%B0%E5%99%A8.md
:param cls: cls
:return: instance
"""
_instances = {}
@wraps(cls)
def instance(*args, **kw):
if cls not in _instances:
_instances[cls] = cls(*args, **kw)
return _instances[cls]
return instance
@singleton
class MotorBase:
"""
mongodb
About motor's doc: https://github.com/mongodb/motor
"""
_db = {}
_collection = {}
MONGODB = MONGODB
def __init__(self):
self.motor_uri = ''
def client(self, db):
# motor
self.motor_uri = 'mongodb://{account}{host}:{port}/{database}'.format(
account='{username}:{password}@'.format(
username=self.MONGODB['MONGO_USERNAME'],
password=self.MONGODB['MONGO_PASSWORD']) if self.MONGODB['MONGO_USERNAME'] else '',
host=self.MONGODB['MONGO_HOST'] if self.MONGODB['MONGO_HOST'] else 'localhost',
port=self.MONGODB['MONGO_PORT'] if self.MONGODB['MONGO_PORT'] else 27017,
database=db)
return AsyncIOMotorClient(self.motor_uri)
def get_db(self, db=MONGODB['DATABASE']):
"""
db
:param db: database name
:return: the motor db instance
"""
if db not in self._db:
self._db[db] = self.client(db)[db]
return self._db[db]
def get_collection(self, db_name, collection):
"""
:param db_name: database name
:param collection: collection name
:return: the motor collection instance
"""
collection_key = db_name + collection
if collection_key not in self._collection:
self._collection[collection_key] = self.get_db(db_name)[collection]
return self._collection[collection_key]
MotorBaseインスタンスの重複作成を回避するために、リソースの有効利用を保証するための単一のモードを実現することができます.具体的なコードとdemoの実行はaio_を参照してください.mongo
操作Redis
Redisの非同期操作については、
asyncio_redis
を選択しました.これを使用する必要はありません.他のライブラリがより良いかもしれません.私はこの例を挙げて、次のディレクトリを作成します.aio_redis
├── demo.py
└── requirements.txt
redis接続プールを作成するには、次の手順に従います.
#!/usr/bin/env python
import os
import asyncio_redis
REDIS_DICT = dict(
IS_CACHE=True,
REDIS_ENDPOINT=os.getenv('REDIS_ENDPOINT', "localhost"),
REDIS_PORT=os.getenv('REDIS_PORT', 6379),
REDIS_PASSWORD=os.getenv('REDIS_PASSWORD', None),
DB=0,
POOLSIZE=10,
)
class RedisSession:
"""
redis
"""
_pool = None
async def get_redis_pool(self):
if not self._pool:
self._pool = await asyncio_redis.Pool.create(
host=str(REDIS_DICT.get('REDIS_ENDPOINT', "localhost")), port=int(REDIS_DICT.get('REDIS_PORT', 6379)),
poolsize=int(REDIS_DICT.get('POOLSIZE', 10)), password=REDIS_DICT.get('REDIS_PASSWORD', None),
db=REDIS_DICT.get('DB', None)
)
return self._pool
具体的にはaio_を参照redis、使うのは簡単で、多くの叙述をしません.
説明
他のタイプのデータベースを使用する場合も、実際には同じように使用されます.この章のコードアドレスはdemo 05を参照してください