Генерация фиктивных данных с Mimesis: Часть I

Генерация фиктивных данных с Mimesis: Часть I

Nuances of programming

Автор статьи likid_ri

Mimesis — это библиотека для языка программирования Python, которая помогает генерировать фиктивные данные для различных целей. Библиотека написана с использованием средств, включенных в стандартную библиотеку языка Python, потому не имеет никаких сторонних зависимостей. На данный момент библиотека поддерживает 30 языковых стандартов (в числе которых и русский) и более 20 классов-провайдеров, предоставляющих разного рода данные.

Возможность генерировать фиктивные, но в то же время валидные данные бывает очень полезна при разработке приложений, которые подразумевают работу с базой данных. Ручное заполнение базы данных представляется довольно затратным по времени и трудоемким процессом, который выполняется как минимум в 3 этапа — это:

  1. Сбор необходимой информации.
  2. Постобработка собранных данных.
  3. Программирования генераторов данных.

Эта непростая задача по-настоящему усложняется в тот момент, когда требуется сгенерировать не 10-15 пользователей, а 100-150 тысяч пользователей (или иного рода данные). В этой и последующих статьях мы постараемся обратить ваше внимание на инструмент, который в разы упрощает процесс генерации тестовых данных, начальной загрузки базы данных и тестирования в целом.

Общая информация

Поддерживаемые языковые стандарты:

Список поддерживаемых классов-провайдеров постоянно расширяется. Все поддерживаемы поставщики данных перечислены тут.

Помимо перечисленных выше, поддерживаются так же специфичные для конкретных стран данные, которые можно импортировать из подпакета builtins:

Установка

Установка 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'

На самом деле возможностей очень много и можно придумать огромное количество куда более наглядных примеров, в контексте которых данные будут выглядеть более ценными, чем выше. Мы ждем таких примеров от вас — читателей. Мы будем очень рады прочитать об успешном опыте применении библиотеки в ваших проектах.





Report Page