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