繁体   English   中英

FastAPI 测试 否 ORM 数据库

[英]FastAPI testing No ORM Databases

我是无 ORM 用户,我更喜欢使用纯文本查询,我在 FastAPI 上的免费代码营上学习了该课程,但几乎整个课程都围绕 ORM,所以我很难实现该课程中的一些概念。

我的主要困难是当我为端点编写测试时,我需要使用测试数据库而不是我的开发数据库,我正在使用testing.postgres创建测试数据库,这是我正在使用的代码:

client = TestClient(app)

class TestUser:
    def setup_method(self, method):
        self.postgres = testing.postgresql.Postgresql(cache_initialized_db=True)
        self.db = psycopg2.connect(**self.postgres.dsn())

    def teardown_method(self, method):
        self.db.close()

    def test_get_users(self):
        res = client.get("/users")
        assert res.status_code == 200
        assert res.headers["content-type"] == "application/json"

我的问题是如何让我的测试和 cruds 将查询发送到测试数据库,而不是开发数据库。

我应该在这里添加的链接在哪里?

编辑:这是我用于连接数据库的代码,我没有使用它的依赖项:

while True:
    try:
        conn = psycopg2.connect(
            database=settings.database,
            user=settings.user,
            port=settings.port,
            password=settings.password,
            cursor_factory=RealDictCursor,
        )
        cr = conn.cursor()
        console.print(
            "[green bold]SUCCESS[/]:    Connection To Database Established successfuly"
        )
        break
    except psycopg2.OperationalError:
        console.print(
            "[red bold]FAILED[/]:    Connection To Database Failed , Trying Again"
        )
        time.sleep(2)

Edit2:这是设置部分:

load_dotenv()


class Settings(BaseSettings):
    database: str
    user: str
    port: int
    password: str
    expiray: int
    algorithm: str
    secret_key: str


settings = Settings()

如果您想使用测试数据库而不是开发数据库,您应该创建测试数据库并让后端应用程序能够找到并使用测试数据库。

Kareem,我建议您根据ENVIRONMENT变量从一个或另一个.env文件创建您的Settings实例:

import os
import sys

import pydantic


class Settings(pydantic.BaseSettings):
    database: str
    user: str
    port: int
    password: str
    expiray: int
    algorithm: str
    secret_key: str


try:
    ENVIRONMENT = os.environ['ENVIRONMENT']
except KeyError:
    print('make sure to set an "ENVIRONMENT" env var')
    sys.exit()

    
settings = Settings(_env_file=f'{ENVIRONMENT}.env', _env_file_encoding='utf-8')

这样,如果您想使用测试数据库,您可以执行$ export ENVIRONMENT=test ,它将从名为test.env的文件中加载设置。

那有意义吗? 这是pydantic 对pydantic子类的dotenv支持的BaseSettings

顺便说一句,由于您有兴趣在不使用 ORM 和其他依赖项的情况下尽可能多地做事,因此您真的不需要pydantic来实现您的目的:您可以简单地将上面的内容更改为:


import os
import sys
import types

import dotenv


try:
    ENVIRONMENT = os.environ['ENVIRONMENT']
except KeyError:
    print('make sure to set an "ENVIRONMENT" env var')
    sys.exit()


db_settings_dict = dotenv.dotenv_values(f"{ENVIRONMENT}.env")

# to get dot notation as in your example
settings = types.SimpleNamespace(**db_settings_dict)

其中test.env包含类似

database=hey.there.com:8768
user=kareem
...

下面是我为控制 .env 文件中的 ENV 变量而编写的脚本,在运行 unicorn 服务器之前,您将根据 ENV 模式加载 .env 文件以确定正在使用哪种模式,然后使用条件进行设置对应的数据库路径和名称。


import os
import sys
from colored import fg
from os import environ, path
from dotenv import load_dotenv, set_key
import dotenv


def unknown(option, args=None):
    color = fg('red')
    if args:
        print(color + f'Unknown arguments: -{args}')
    else:
        print(color + f'Unknown option: -{option}')
    print("usage: python3 config.py [option] [arguments]")
    print("Try `python3 config.py --help for more information")
    color = fg('white')
    print(color)


def version():
    basedir = path.abspath(path.dirname(__file__))
    load_dotenv(path.join(basedir, '.env'))
    color = fg('blue')
    print(color + '[VERSION]: ' + environ.get('VER'))
    color = fg('white')
    print(color)


def env():
    basedir = path.abspath(path.dirname(__file__))
    load_dotenv(path.join(basedir, '.env'))
    color = fg('blue')
    print(color + '[ENV]: ' + environ.get('ENV'))
    color = fg('white')
    print(color)


def set_env(env):
    dotenv_file = dotenv.find_dotenv()

    basedir = path.abspath(path.dirname(__file__))
    load_dotenv(path.join(basedir, '.env'))
    color = fg('blue')
    print(color + f"[Updating ENV] ... ... from {environ.get('ENV')} to {env}")
    os.environ["ENV"] = env
    set_key(dotenv_file, 'ENV', os.environ['ENV'])
    print("[Successfully Update the 'ENV' from .env]")
    color = fg('white')
    print(color)


def doc():
    color = fg('blue')
    print(color + "usage: python3 config.py [option] [arguments]")

    read_me = """
    -v                  : current project version
    -env                : current project environment
    -set ENV={env}      : set project env 'DEV' or 'PROD'
    """
    print(read_me)
    color = fg('white')
    print(color)


def action_handler(option, args):
    if option == '-set':
        args_list = args.split('=')
        if args_list[0] == 'ENV' and (args_list[1] == 'DEV' or args_list[1] == 'PROD'):
            set_env(args_list[1])
        else:
            unknown(option=option, args=args)
    else:
        unknown(option=option)


argvs = len(sys.argv)

if argvs == 1:
    doc()
elif argvs == 2:
    option = sys.argv[1]
    if option == '--help':
        doc()
    elif option == '-v':
        version()
    elif option == '-env':
        env()
    else:
        unknown(option)
elif argvs == 3:
    option, args = sys.argv[1], sys.argv[2]
    action_handler(option, args)
else:
    pass

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM