
Mimesis — это библиотека для языка программирования Python, которая помогает генерировать фиктивные данные для различных целей. Библиотека написана с использованием средств, включенных в стандартную библиотеку языка Python, потому не имеет никаких сторонних зависимостей. На данный момент библиотека поддерживает 30 языковых стандартов (в числе которых и русский) и более 20 классов-провайдеров, предоставляющих разного рода данные.
Возможность генерировать фиктивные, но в то же время валидные данные бывает очень полезна при разработке приложений, которые подразумевают работу с базой данных. Ручное заполнение базы данных представляется довольно затратным по времени и трудоемким процессом, который выполняется как минимум в 3 этапа — это:
- Сбор необходимой информации.
- Постобработка собранных данных.
- Программирования генераторов данных.
Эта непростая задача по-настоящему усложняется в тот момент, когда требуется сгенерировать не 10-15 пользователей, а 100-150 тысяч пользователей (или иного рода данные). В этой и двух последующих статьях мы постараемся обратить ваше внимание на инструмент, который в разы упрощает процесс генерации тестовых данных, начальной загрузки базы данных и тестирования в целом.
Общая информация
Поддерживаемые языковые стандарты:
| № | Код | Название |
|---|---|---|
| 1 | cs |
Чешский |
| 2 | da |
Датский |
| 3 | de |
Немецкий |
| 4 | de-at |
Австрийский немецкий |
| 5 | de-ch |
Швейцарский немецкий |
| 6 | en |
Английский |
| 7 | en-au |
Австралийский английский |
| 8 | en-ca |
Канадский английский |
| 9 | en-gb |
Британский английский |
| 10 | es |
Испанский |
| 11 | es-mx |
Мексиканский испанский |
| 12 | fa |
Персидский (Фарси) |
| 13 | fi |
Финский |
| 14 | fr |
Французский |
| 15 | hu |
Венгерский |
| 16 | is |
Исландский |
| 17 | it |
Итальянский |
| 18 | ja |
Японский |
| 19 | ko |
Корейский |
| 20 | nl |
Нидерландский |
| 21 | nl-be |
Бельгийский нидерландский |
| 22 | no |
Норвежский |
| 23 | pl |
Польский |
| 24 | pt |
Португальский |
| 25 | pt-br |
Бразильский португальский |
| 26 | ru |
Русский |
| 27 | sv |
Шведский |
| 28 | tr |
Турецкий |
| 29 | uk |
Украинский |
| 30 | zh |
Китайский |
Список поддерживаемых классов-провайдеров постоянно расширяется. Все поддерживаемы поставщики данных перечислены тут.
Помимо перечисленных выше, поддерживаются так же специфичные для конкретных стран данные, которые можно импортировать из подпакета builtins:
| № | Провайдер | Методы |
|---|---|---|
| 1 | USASpecProvider | tracking_number(), ssn(), personality() |
| 2 | JapanSpecProvider | full_to_half(), half_to_full() |
| 2 | RussiaSpecProvider | patronymic(), passport_series(), passport_number(), snils() |
| 2 | BrazilSpecProvider | cpf(), cnpj() |
Установка
Установка Mimesis производится как обычно, т.е посредством пакетного менеджера pip. Чтобы установить последнюю свежую версию библиотеки выполните следующую команду:
➜ ~ pip install mimesis
Если по каким-то причинам у вас не получается установить пакет с помощью pip, то попробуйте установить его вручную, как показано ниже:
(venv) ➜ git clone https://github.com/lk-geimfari/mimesis.git (venv) ➜ cd mimesis/ (venv) ➜ python3 setup.py install # или (venv) ➜ make install
Обращаем ваше внимание, что библиотека работает только на Python 3.5 +. Никаких планов по добавлению поддержки Python 2.7 у разработчиков нет.
Генерация
Изначально мы планировали показать генерацию данных на примере небольшого веб-приложения на Flask, но решили отказаться от этой идеи, по той причине, что не все знакомы с Flask и не все горят желанием это исправлять. Потому мы будем показывать все на чистом Python. В случае, если вы захотите перенести все в свой проект на Flask или Django, то вам нужно всего лишь определить статический метод, выполняющий все манипуляции связанные с текущей моделью и вызывать его в тот момент, когда нужно выполнить начальную загрузку БД, как показано в примере ниже.
Модель для Flask (Flask-SQLAlchemy) будет выглядеть как-то так:
class Patient(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(120), unique=True) phone_number = db.Column(db.String(25)) full_name = db.Column(db.String(100)) weight = db.Column(db.String(64)) height = db.Column(db.String(64)) blood_type = db.Column(db.String(64)) def __init__(self, **kwargs): super(Patient, self).__init__(**kwargs) @staticmethod def _bootstrap(count=2000, locale='en'): from mimesis.providers import Personal person = Personal(locale) for _ in range(count): patient = Patient( email=person.email(), phone_number=person.telephone(), full_name=person.full_name(gender='female'), weight=person.weight(), height=person.height(), blood_type=person.blood_type() ) db.session.add(patient) try: db.session.commit() except Exception: db.session.rollback()
Переходим в shell-mode:
(venv) ➜ python3 manage.py shell
И генерируем данные, предварительно убедившись в том, что база данных и подопытная модель доступны.
>>> db <SQLAlchemy engine='sqlite:///db.sqlite'> >>> Patient <class 'app.models.Patient'> >>> Patient()._bootstrap(count=4000, locale='ru') # Сгенерировать 4к записей на русском языке.
Введение
Хотелось бы отметить, что мы будем приводить в примерах только базовые возможности библиотеки и, в основном, обойдемся несколькими наиболее часто встречающимися классами-провайдерами, ибо их слишком много, чтобы рассказывать обо всех в деталях. Если статья возбудит в вас интерес к библиотеке, то вы сможете найти полезные ссылки в самом конце статьи и самостоятельно все изучить.
Библиотека устроена довольно просто и все, что вам необходимо для того, чтобы начать работать с данным — это создать экземпляр класса-провайдера. Наиболее часто встречающиеся данные в веб-приложениях — это личные данные пользователя, такие как имя пользователя, имя, фамилия, возраст, кредитные данные и т.п. Для генерации таких данных существует специальный класс-провайдер — Personal(), который принимает код языкового стандарта в виде строки, как показано ниже:
>>> from mimesis import Personal # Создаем экземпляр класса-провайдера с данными для исландского языка. >>> person = Personal('is') # Выводим исландские мужские имена. >>> for _ in range(0, 3): ... person.full_name(gender='male') `Karl Brynjúlfsson` `Rögnvald Eiðsson` `Vésteinn Ríkharðsson`
Практически каждое веб-приложение требует ввода e-mail адреса при регистрации. Библиотека, разумеется поддерживает возможность генерировать e-mail адреса и делается это с помощью метода email() класса Personal(), как показано ниже:
# Женский: >>> person.email(gender='female') >>> 'lvana6108@gmail.com' # Мужской: >>> person.email(gender='male') 'john2454@yandex.com'
В способе, что был приведен выше кроется небольшая проблема, которая может несколько загрязнять код, если в приложении используется не один единственный класс-провайдер, а несколько. В таких случаях следует использовать объект Generic(), который дает доступ ко всем провайдерам из одного единственного объекта, как показано ниже:
>>> from mimesis import Generic >>> # Согласно стандарту ISO 639-1, pl - это код Польши. >>> g = Generic('pl') >>> g.personal.full_name() 'Lonisława Podsiadło' >>> g.datetime.birthday(readable=True) 'Listopad 11, 1997' >>> g.personal.blood_type() 'A−'
Комбинирование данных дает большой простор. К примеру можно создать фиктивных держателей (женского пола) карты Visa (или MasterCard, Maestro):
>>> user = Personal('en') >>> def get_card(sex='female'): ... owner = { ... 'owner': user.full_name(sex), ... 'exp_date': user.credit_card_expiration_date(maximum=21), ... 'number': user.credit_card_number(card_type='visa') ... } ... return owner >>> for _ in range(0, 3): ... get_card()
Вывод:
{'exp_date': '02/20', 'owner': 'Laverna Morrison', 'card_number': '4920 3598 2121 3328'} {'exp_date': '11/19', 'owner': 'Melany Martinez', 'card_number': '4980 9423 5464 1201'} {'exp_date': '01/19', 'owner': 'Cleora Mcfarland', 'card_number': '4085 8037 5801 9703'}
Как уже говорилось выше, библиотека поддерживает более 20 классов-провайдеров, которые содержат данные на все случаи жизни (если нет, то ждем PR с исправлением этого ужасного недоразумения). К примеру, если вы разрабатываете приложение ориентированное на грузоперевозки или на иную деятельность, связанную с транспортом и вам необходимо сгенерировать модели транспорта, то вы с легкостью сможете сделать это, воспользовавшись классом-провайдером Transport(), который содержит данные о транспорте:
>>> from mimesis import Transport >>> trans = Transport() >>> for _ in range(0, 5): ... trans.truck() 'Seddon-2537 IM' 'Karrier-7799 UN' 'Minerva-5567 YC' 'Hyundai-2808 XR' 'LIAZ-7174 RM'
Ну или можно указать маску модели транспорта:
>>> for _ in range(0, 5): ... trans.truck(model_mask="##@") # # - числа, @ - буквы
Henschel-16G Bean-44D Unic-82S Ford-05Q Kalmar-58C
Нередко при тестировании веб-приложений (тестирование блога — яркий пример) возникает необходимость сгенерировать текстовые данные (текст, предложение, тег и.т.п.). Вбивать вручную текст при тестировании — это долго и скучно и Mimesis позволяет этого избежать, благодаря классу-провайдеру Text():
>>> from mimesis import Text >>> text = Text('ru') >>> text.text(quantity=3) # quantity - показатель количества предложений. 'Язык включает в себя средства порождения параллельных легковесных процессов и их взаимодействия через обмен асинхронными сообщениями в соответствии с моделью акторов. Python поддерживает несколько парадигм программирования, в том числе структурное, объектно-ориентированное, функциональное, императивное и аспектно-ориентированное. Например, определение функции, которое использует сопоставление с образцом, для выбора одного из вариантов вычисления или извлечения элемента данных из составной структуры, напоминает уравнение.'
Можно получить список случайных слов:
>>> text = Text('pt-br') >>> text.words(quantity=5) ['poder', 'de', 'maior', 'só', 'cima']
Cгенерировать название улицы:
>>> from mimesis import Address >>> address = Address('ru') >>> address.address() 'ул. Хабаровская 651'
Получить название субъекта/штата/провинции странны, к которой относится выбранный языковой стандарт. В данном случае — это субъект Российской Федерации:
>>> address.state() 'Кировская область'
Сгенерировать координаты:
>>> address.coordinates() {'latitude': -28.362892454682246, 'longitude': 11.512065821275826}
В библиотеке так же есть средства для романизации кириллических языков (на момент написания статьи поддерживаются только русский и украинский):
>>> from mimesis.decorators import romanized >>> @romanized('ru') ... def name_ru(): ... return 'Вероника Денисова' ... >>> @romanized('uk') >>> def name_uk(): ... return 'Емілія Акуленко' ... >>> name_ru() 'Veronika Denisova' >>> name_uk() 'Emіlіja Akulenko'
На самом деле возможностей очень много и можно придумать огромное количество куда более наглядных примеров, в контексте которых данные будут выглядеть более ценными, чем выше. Мы ждем таких примеров от вас — читателей. Мы будем очень рады прочитать об успешном опыте применении библиотеки в ваших проектах.
Полезные ссылки:
Здесь вы можете найти вторую часть статьи.
Здесь вы сможете прочитать дополненный вариант этой статьи и много других интересных статей на разные темы.
Github: lk-geimfari/mimesis
Read the Docs: mimesis
Спасибо за внимание и удачных вам тестов!
