
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
Спасибо за внимание и удачных вам тестов!
