Возможность генерировать фейковые, но достоверные данные очень выручает при разработке приложений, когда вам нужно работать с базами данных. Заполнение базы данных вручную – это поедающий время, утомительный процесс, который может быть выполнен в три этапа:
- Добыча необходимой информации
- Публикация данных
- Создание самого генератора данных
Становится очень тяжко, когда вам нужно сгенерировать не 10-15 пользователей, а 100-150 тысяч юзеров (или других типов данных). В данной статье мы рассмотрим инструмент, который невероятно упрощает генерацию фейковых данных, первоначальное наполнение базы данных и её тестирование в целом.
Elizabeth – это библиотека Python, которая помогает генерировать макетные данные для различных целей. Эта библиотека была написана с использованием инструментов из стандартной библиотеки Python, и, следовательно, в ней нет никаких сторонних зависимостей. На данный момент, библиотека поддерживает 30 языков и 19 классовых провайдеров, а также различные виды данных.
Установка
Нормальный способ установки Elizabeth – через pip:
1 |
pip install elizabeth |
Если по какой-то причине вы не можете установить пакет при помощи pip, вы можете попробовать установить его вручную, вот так:
1 2 3 |
git clone https://github.com/lk-geimfari/elizabeth.git cd elizabeth/ python3 setup.py install # или "make install" |
Обратите внимание на то, что данная библиотека запускается только на Python 3.4+. Разработчики не планируют добавлять поддержку Python 2.7
Генерация данных
Сначала я думал показать, как это делается на примере небольшого веб-приложения под названием Flask, но решил этого не делать, так как не каждый знаком с Flask, и не у каждого может возникнуть объективное желание изменить в нем что-либо. Следовательно, мы будем работать непосредственно в Python. В случае, если вам нужно перенести весь свой проект на Flask или Django, вам просто нужно определить статический метод, который запустит все манипуляции, связанные с предоставленной моделью, и вызвать его когда вам будет нужна начальная загрузка базы данных, как показано в примере ниже:
Модель под Flask будет выглядеть вот так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
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)) age = db.Column(db.Integer) def __init__(self, **kwargs): super(Patient, self).__init__(**kwargs) @staticmethod def _bootstrap(count=500, locale='en', gender): from elizabeth import Personal person = Personal(locale) for _ in range(count): patient = Patient( email=person.email(), phone_number=person.telephone(), full_name=person.full_name(gender=gender), age=person.age(minimum=18, maximum=45), weight=person.weight(), height=person.height(), blood_type=person.blood_type() ) db.session.add(patient) try: db.session.commit() except IntegrityError: db.session.rollback() |
Теперь перейдем в shell-mode:
1 |
python3 manage.py shell |
И сгенерируем данные. Нам нужно заранее убедиться в том, что база database и model являются доступными.
1 2 3 4 5 6 7 |
>>> db <SQLAlchemy engine='sqlite:///db.sqlite'> >>> Patient <class 'app.models.Patient'> >>> Patient()._bootstrap(count=40000, locale='en') # generate 40к entries in English. |
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Введение
Стоит отметить, что мы рассмотрим основные возможности библиотеки и используем несколько наиболее распространенных классовых провайдеров, так как на самом деле их слишком много, чтобы рассматривать все по отдельности. Если по прочтению данной статьи у вас возникнет яркий интерес к данной библиотеке, вы можете найти великое множество информации о ней в интернете. Эта библиотека очень простая. Все что вам нужно для начала работы с данными – это создать классовый провайдер. Самый распространенный тип данных в приложениях – это персональные данные пользователя, такие как имя, фамилия, информация о кредитных картах, и т.д. Существует специальный классовый провайдер для таких данных, под названием Personal(), который использует код из стандартного языка в виде строки, как показано ниже:
1 2 3 4 5 6 |
from elizabeth import Personal person = Personal('is') for _ in range(0, 3): person.full_name(gender='male') |
Результат:
1 2 3 |
'Karl Brynjúlfsson' 'Rögnvald Eiðsson' 'Vésteinn Ríkharðsson' |
Практически каждое веб-приложение запрашивает адрес электронной почты для регистрации. Естественно, что библиотека поддерживает возможность генерации электронных адресов при помощи метода email() класса Personal(), как показано ниже:
1 2 3 4 5 6 7 8 9 |
from elizabeth import Personal person = Personal('is') female = person.email(gender='female') print(female) # 'lvana6108@gmail.com' male = person.email(gender='male') print(male) # 'john2454@yandex.com' |
Однако есть небольшая проблема с указанным выше методом, которая может сделать код слегка «грязным» в случае, если приложение использует более одного классового провайдера. В данном случае вам нужно использовать объект Generic(), который предоставляет доступ ко всем провайдерам из одного объекта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from elizabeth import Generic g = Generic('pl') # Poland (ISO 639-1). full_name = g.personal.full_name() print(full_name) # 'Lonisława Podsiadło' date = g.datetime.birthday(readable=True) print(data) # 'Listopad 11, 1997' imei = g.code.imei() print(imei) # '011948003071013' fruit = g.food.fruit() print(fruit) # 'Cytryna' method = g.internet.http_method() print(method) # 'PUT' math_form = g.science.math_formula() print(math_form) # 'A = (h * (a + b)) / 2' |
Объединенные данные – это обширное поле для экспериментов. Например, вы можете создать фейковых владельцев кредитных карт Visa (Maestro, MasterCard):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from elizabeth import Personal 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() |
Результат:
1 2 3 |
{'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'} |
Как было упомянуто выше, библиотека поддерживает более 19 классовых провайдеров с данными для всех возможных ситуаций (если нет, то ваш PR с исправлением такой ужасной несправедливости окажется более чем полезным). Например, если вы работаете с приложением, ориентированным на транспортировку и логистику и вам нужно создать модели транспортировок, вы можете легко выполнить эту задачу при помощи провайдера Transport(), который содержит необходимые данные, связанные с транспортировкой:
1 2 3 4 5 |
from elizabeth import Transport trans = Transport() for _ in range(0, 5): print(trans.truck()) |
Результат:
1 2 3 4 5 |
'Seddon-2537 IM' 'Karrier-7799 UN' 'Minerva-5567 YC' 'Hyundai-2808 XR' 'LIAZ-7174 RM' |
Также вы можете указать модель транспортной маски:
1 2 3 4 5 6 |
from elizabeth import Transport trans = Transport() for _ in range(0, 5): # Шаблон вывода данных, # - для номеров, @ - для букв. print(trans.truck(model_mask="##@")) |
Результат:
1 2 3 4 5 |
'Henschel-16G' 'Bean-44D' 'Unic-82S' 'Ford-05Q' 'Kalmar-58C' |
При тестировании веб приложений (блог – хороший тому пример), довольно часто вам нужно будет генерировать текстовые данные (текст, предложения, теги, и т.д.). Делать это вручную довольно скучно, к счастью Elizabeth дает возможность вам избежать этого, благодаря классу Text():
1 2 3 4 5 6 |
from elizabeth import Text text = Text('en') result = text.text(quantity=3) print(result) |
Результат:
1 2 3 4 5 6 7 |
'Language includes means for creating light parallel processes and their interactions via exchanging asynchronous messages according to the actors’ model. Python supports several programming paradigms, including structural, object-oriented, functional, imperative and aspect-oriented. For instance, some functions that use comparison of examples to choose one calculating option or extracting data points looks similar to an equation.' |
Вы можете получить список случайных слов:
1 2 3 4 5 6 |
from elizabeth import Text text = Text('pt-br') result = text.words(quantity=5) print(result) |
Результат:
1 |
['poder', 'de', 'maior', 'só', 'cima'] |
Генерировать названия улиц:
1 2 3 4 5 6 |
from elizabeth import Address address = Address('en') result = address.address() print(result) |
Результат:
1 |
'77 Shephard Trace' |
Получить название штата\района\провинции, связанной с выбранным языком, в данном случае, это один из штатов США:
1 2 3 4 5 |
from elizabeth import Address address = Address('en') print(address.state()) # 'Texas' |
Наша библиотека также поддерживает кириллицу (на данный момент поддерживаются только Украинский и Русский языки):
1 2 3 4 5 6 7 8 9 10 11 12 |
from elizabeth.decorators import romanized @romanized('ru') def name_ru(): return 'Вероника Денисова' @romanized('uk') def name_uk(): return 'Емілія Акуленко' print(name_ru()) # 'Veronika Denisova' print(name_uk()) # 'Emіlіja Akulenko' |
Подведем итоги
На практике существует большое количество возможностей, и вы можете придумать огромное количество эффективных способов использования, в которых данные будут выглядеть более полезными, чем в наших примерах.
Документация: http://elizabeth.readthedocs.io/en/latest/
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»