def test_generate_config_explicit(self): res = generate_config( db_url='sqlite:///some/test.sqlite', app_modules={ 'models': [ 'one.models', 'two.models' ] }, connection_label='models', testing=True ) self.assertEqual(res, { 'connections': { 'models': { 'credentials': { 'file_path': '/some/test.sqlite', }, 'engine': 'tortoise.backends.sqlite' } }, 'apps': { 'models': { 'models': [ 'one.models', 'two.models' ], 'default_connection': 'models' } }, })
def getDBConfig(app_label: str, db_url: str, modules: List[str]) -> dict: return generate_config( db_url, app_modules={app_label: modules}, testing=True, connection_label=app_label, )
def test_generate_config_basic(self): res = generate_config( db_url='sqlite:///some/test.sqlite', app_modules={ 'models': [ 'one.models', 'two.models' ] } ) self.assertEqual(res, { 'connections': { 'default': { 'credentials': { 'file_path': '/some/test.sqlite' }, 'engine': 'tortoise.backends.sqlite' } }, 'apps': { 'models': { 'models': [ 'one.models', 'two.models' ], 'default_connection': 'default' } }, })
def test_generate_config_many_apps(self): res = generate_config( db_url="sqlite:///some/test.sqlite", app_modules={ "models": ["one.models", "two.models"], "peanuts": ["peanut.models"] }, ) self.assertEqual( res, { "connections": { "default": { "credentials": { "file_path": "/some/test.sqlite" }, "engine": "tortoise.backends.sqlite", } }, "apps": { "models": { "models": ["one.models", "two.models"], "default_connection": "default", }, "peanuts": { "models": ["peanut.models"], "default_connection": "default" }, }, }, )
def test_generate_config_explicit(self): res = generate_config( db_url="sqlite:///some/test.sqlite", app_modules={"models": ["one.models", "two.models"]}, connection_label="models", testing=True, ) self.assertEqual( res, { "connections": { "models": { "credentials": { "file_path": "/some/test.sqlite" }, "engine": "tortoise.backends.sqlite", } }, "apps": { "models": { "models": ["one.models", "two.models"], "default_connection": "models", } }, }, )
def test_generate_config_basic(self): res = generate_config( db_url="sqlite:///some/test.sqlite", app_modules={"models": ["one.models", "two.models"]}, ) self.assertEqual( res, { "connections": { "default": { "credentials": { "file_path": "/some/test.sqlite", "journal_mode": "WAL", "journal_size_limit": 16384, }, "engine": "tortoise.backends.sqlite", } }, "apps": { "models": { "models": ["one.models", "two.models"], "default_connection": "default", } }, }, )
async def _init_db(db_url=None): db_config = generate_config( db_url=db_url or config.DATABASE_URL, app_modules={'anon_talks': ['anon_talks.models']}, connection_label='anon_talks', ) await Tortoise.init(config=db_config) logging.info("Tortoise-ORM started.")
def get_db_config(cls, app_label="models") -> dict: """ DB Config factory, for use in testing. """ return generate_config( cls.tortoise_test_db, app_modules={app_label: cls.tortoise_test_modules}, testing=True, connection_label=app_label, )
async def init( cls, config: Optional[dict] = None, config_file: Optional[str] = None, _create_db: bool = False, db_url: Optional[str] = None, modules: Optional[Dict[str, Iterable[Union[str, ModuleType]]]] = None, use_tz: bool = False, timezone: str = "UTC", routers: Optional[List[Union[str, Type]]] = None, ) -> None: """ Sets up Tortoise-ORM. You can configure using only one of ``config``, ``config_file`` and ``(db_url, modules)``. :param config: Dict containing config: .. admonition:: Example .. code-block:: python3 { 'connections': { # Dict format for connection 'default': { 'engine': 'tortoise.backends.asyncpg', 'credentials': { 'host': 'localhost', 'port': '5432', 'user': '******', 'password': '******', 'database': 'test', } }, # Using a DB_URL string 'default': 'postgres://*****:*****@localhost:5432/test' }, 'apps': { 'my_app': { 'models': ['__main__'], # If no default_connection specified, defaults to 'default' 'default_connection': 'default', } }, 'routers': ['path.router1', 'path.router2'], 'use_tz': False, 'timezone': 'UTC' } :param config_file: Path to .json or .yml (if PyYAML installed) file containing config with same format as above. :param db_url: Use a DB_URL string. See :ref:`db_url` :param modules: Dictionary of ``key``: [``list_of_modules``] that defined "apps" and modules that should be discovered for models. :param _create_db: If ``True`` tries to create database for specified connections, could be used for testing purposes. :param use_tz: A boolean that specifies if datetime will be timezone-aware by default or not. :param timezone: Timezone to use, default is UTC. :param routers: A list of db routers str path or module. :raises ConfigurationError: For any configuration error """ if cls._inited: await cls.close_connections() await cls._reset_apps() if int(bool(config) + bool(config_file) + bool(db_url)) != 1: raise ConfigurationError( 'You should init either from "config", "config_file" or "db_url"' ) if config_file: config = cls._get_config_from_config_file(config_file) if db_url: if not modules: raise ConfigurationError('You must specify "db_url" and "modules" together') config = generate_config(db_url, modules) try: connections_config = config["connections"] # type: ignore except KeyError: raise ConfigurationError('Config must define "connections" section') try: apps_config = config["apps"] # type: ignore except KeyError: raise ConfigurationError('Config must define "apps" section') use_tz = config.get("use_tz", use_tz) # type: ignore timezone = config.get("timezone", timezone) # type: ignore routers = config.get("routers", routers) # type: ignore # Mask passwords in logs output passwords = [] for name, info in connections_config.items(): if isinstance(info, str): info = expand_db_url(info) password = info.get("credentials", {}).get("password") if password: passwords.append(password) str_connection_config = str(connections_config) for password in passwords: str_connection_config = str_connection_config.replace( password, # Show one third of the password at beginning (may be better for debugging purposes) f"{password[0:len(password) // 3]}***", ) logger.debug( "Tortoise-ORM startup\n connections: %s\n apps: %s", str_connection_config, str(apps_config), ) cls._init_timezone(use_tz, timezone) await cls._init_connections(connections_config, _create_db) cls._init_apps(apps_config) cls._init_routers(routers) cls._inited = True
async def init( cls, config: Optional[dict] = None, config_file: Optional[str] = None, _create_db: bool = False, db_url: Optional[str] = None, modules: Optional[Dict[str, List[str]]] = None, use_tz: bool = False, timezone: str = "UTC", ) -> None: """ Sets up Tortoise-ORM. You can configure using only one of ``config``, ``config_file`` and ``(db_url, modules)``. :param config: Dict containing config: .. admonition:: Example .. code-block:: python3 { 'connections': { # Dict format for connection 'default': { 'engine': 'tortoise.backends.asyncpg', 'credentials': { 'host': 'localhost', 'port': '5432', 'user': '******', 'password': '******', 'database': 'test', } }, # Using a DB_URL string 'default': 'postgres://*****:*****@localhost:5432/test' }, 'apps': { 'my_app': { 'models': ['__main__'], # If no default_connection specified, defaults to 'default' 'default_connection': 'default', } }, 'use_tz': False, 'timezone': UTC } :param config_file: Path to .json or .yml (if PyYAML installed) file containing config with same format as above. :param db_url: Use a DB_URL string. See :ref:`db_url` :param modules: Dictionary of ``key``: [``list_of_modules``] that defined "apps" and modules that should be discovered for models. :param _create_db: If ``True`` tries to create database for specified connections, could be used for testing purposes. :param use_tz: A boolean that specifies if datetime will be timezone-aware by default or not. :param timezone: Timezone to use, default is UTC. :raises ConfigurationError: For any configuration error """ if cls._inited: await cls.close_connections() await cls._reset_apps() if int(bool(config) + bool(config_file) + bool(db_url)) != 1: raise ConfigurationError( 'You should init either from "config", "config_file" or "db_url"' ) if config_file: config = cls._get_config_from_config_file(config_file) if db_url: if not modules: raise ConfigurationError('You must specify "db_url" and "modules" together') config = generate_config(db_url, modules) try: connections_config = config["connections"] # type: ignore except KeyError: raise ConfigurationError('Config must define "connections" section') try: apps_config = config["apps"] # type: ignore except KeyError: raise ConfigurationError('Config must define "apps" section') use_tz = config.get("use_tz", use_tz) # type: ignore timezone = config.get("timezone", timezone) # type: ignore logger.info( "Tortoise-ORM startup\n connections: %s\n apps: %s", str(connections_config), str(apps_config), ) cls._init_timezone(use_tz, timezone) await cls._init_connections(connections_config, _create_db) cls._init_apps(apps_config) cls._inited = True
async def init(cls, config: Optional[dict] = None, config_file: Optional[str] = None, _create_db: bool = False, db_url: Optional[str] = None, modules: Optional[Dict[str, List[str]]] = None) -> None: """ Sets up Tortoise-ORM. You can configure using only one of ``config``, ``config_file`` and ``(db_url, modules)``. Parameters ---------- config: Dict containing config: Example ------- .. code-block:: python3 { 'connections': { # Dict format for connection 'default': { 'engine': 'tortoise.backends.asyncpg', 'credentials': { 'host': 'localhost', 'port': '5432', 'user': '******', 'password': '******', 'database': 'test', } }, # Using a DB_URL string 'default': 'postgres://postgres:@qwerty123localhost:5432/events' }, 'apps': { 'models': { 'models': ['__main__'], # If no default_connection specified, defaults to 'default' 'default_connection': 'default', } } } config_file: Path to .json or .yml (if PyYAML installed) file containing config with same format as above. db_url: Use a DB_URL string. See :ref:`db_url` modules: Dictionary of ``key``: [``list_of_modules``] that defined "apps" and modules that should be discovered for models. _create_db: If ``True`` tries to create database for specified connections, could be used for testing purposes. Raises ------ ConfigurationError For any configuration error """ if cls._inited: await cls._reset_connections() if int(bool(config) + bool(config_file) + bool(db_url)) != 1: raise ConfigurationError( 'You should init either from "config", "config_file" or "db_url"' ) if config_file: config = cls._get_config_from_config_file(config_file) if db_url: if not modules: raise ConfigurationError( 'You must specify "db_url" and "modules" together') config = generate_config(db_url, modules) try: connections_config = config['connections'] # type: ignore except KeyError: raise ConfigurationError( 'Config must define "connections" section') await cls._init_connections(connections_config, _create_db) try: apps_config = config['apps'] # type: ignore except KeyError: raise ConfigurationError('Config must define "apps" section') cls._init_apps(apps_config) cls._init_relations() cls._inited = True
def init( self, config: Optional[Dict[str, Any]] = None, config_file: Optional[str] = None, db_url: Optional[str] = None, modules: Optional[Dict[str, List[str]]] = None, ) -> None: """ Sets up Tortoise-ORM. You can configure using only one of ``config``, ``config_file`` and ``(db_url, modules)``. Parameters ---------- :param config: Dict containing config: Example ------- .. code-block:: python3 { 'connections': { # Dict format for connection 'default': { 'engine': 'tortoise.backends.asyncpg', 'host': 'localhost', 'port': '5432', 'user': '******', 'password': '******', 'database': 'test', }, # Using a DB_URL string 'default': 'postgres://*****:*****@localhost:5432/events' }, 'apps': { 'models': { 'models': ['__main__'], # If no default_connection specified, defaults to 'default' 'default_connection': 'default', } } } :param config_file: Path to .json or .yml (if PyYAML installed) file containing config with same format as above. :param db_url: Use a DB_URL string. See :ref:`db_url` :param modules: Dictionary of ``key``: [``list_of_modules``] that defined "apps" and modules that should be discovered for models. Raises ------ ConfigurationError For any configuration error """ if int(bool(config) + bool(config_file) + bool(db_url)) != 1: raise ConfigurationError( 'You should init either from "config", "config_file" or "db_url"' ) if config_file: config = self._get_config_from_config_file(config_file) if db_url: if not modules: raise ConfigurationError( 'You must specify "db_url" and "modules" together') config = generate_config(db_url, modules) if "connections" not in config: raise ConfigurationError( 'Config must define "connections" section') if "apps" not in config: raise ConfigurationError('Config must define "apps" section') self._reset() connections_config = config["connections"] # type: ignore apps_config = config["apps"] # type: ignore self.logger.info( "Tortoise-ORM startup\n connections: %s\n apps: %s", str(obscure_password(connections_config)), str(apps_config), ) self._init_connections(connections_config) self._init_apps(apps_config) self._init_models() self._inited = True