Пви это: Папилломавирусная инфекция. Диагностика и лечение папилломавирусной инфекции в Москве – клиника гинекологии Гинеко

Содержание

Папилломавирусная инфекция. Диагностика и лечение папилломавирусной инфекции в Москве – клиника гинекологии Гинеко

Современной женщине, ведущей здоровый образ жизни, пунктуально следящей за состоянием своего здоровья, все чаще приходится быть озадаченной вопросом: есть или нет у неё в организме этот «страшной» вирус.

Как и большинство вирусов, папилломавирусная инфекция однажды поселившись в организме, вряд ли может навсегда из него исчезнуть. В связи с большим разнообразием типов ВПЧ, принято обозначать их номерами. Основополагающим же критерием  опасности вируса является его деление на группы, которые связаны с высоким, умеренным или низким риском развития злокачественного заболевания.

Чем же опасен этот вирус в организме женщины?

Основной зоной активности ВПЧ является шейка матки, а точнее граница между её внутренней и наружной частью. Именно здесь располагаются клетки, которые имеют свойство трансформироваться (превращаться) в клетки различных зон шейки матки.

Поэтому при высокой активности ВПЧ эта область становиться зоной риска по развитию патологии с высоким риском озлокачествления.

Достоверно доказано, что заражение ВПЧ 16 и 18 типа связаны с высоким риском развития рака шейки матки. Против этих вирусов даже создана эффективная вакцина, которая рекомендуется вводить девочкам до начала половой жизни при отсутствии у них в организме этих вирусов, т.е. до заражения.

Диагностика

Диагностика ВПЧ основана на лабораторных исследованиях, забор для которых, доступно выполнить при обычном гинекологическом осмотре женщин. По результатам этого анализа (ПЦР) возможно оценить наличие вируса, его разновидность и активность на данный момент времени.

Другим косвенным, но крайне важным методом диагностики активности ВПЧ,  является осмотр гинеколога.  Гинекологический осмотр позволяющий не только диагностировать такие распространённые вирусные проявления, в как кондиломы и папиллома половых органов женщины (половых губ, стенок влагалища и шейки матки), но и провести осмотр шейки матки под специальным микроскопом ( кольпоскопом ).

Это позволяет не только выявить и оценить разнообразную патологию шейки матки (эрозию, лейкоплакию, эктропион), но и заподозрить признаки вирусной активности.

Лечение

Существует большое количество лекарственных противовирусных препаратов призванных лечить заболевание. К сожалению, ни один из них не способен избавить пациентку от этого вируса. Назначение этих лекарств может лишь уменьшить вирусную активность и повысить эффективность проведённого  лечения шейки матки.

Кроме того, использование радиоволновой хирургии, помогает быстро и эффективно избавиться от проявлений этого вируса (генитальных кондилом и папиллом) непосредственно на приеме гинеколога.

Профилактика

В современной медицинской практике применяется вакцинирование детей для предотвращения заболевания наиболее опасными видами ВПЧ. Для взрослых же пациенток основным направлениям в профилактики ВПЧ является регулярное посещение гинеколога с ежегодным осмотром шейки матки (кольпоскопией) и выполнением лабораторных тестов (жидкостная цитология или PAP-test, ПЦР на папилломавирусную инфекцию высокого риска).

врач акушер-гинеколог Старостина Антонина Викторовна.

Папилломавирусная инфекция, которую в зависимости от проявлений могут называть вирусными бородавками, папилломами, остроконечными кондиломами или кондиломатозом, вызывается вирусом. Возбудителем инфекции является вирус из семейства Papavaviridae. Вирус называют вирусом папилломы человека или сокращенно ВПЧ или HPV (сокращение английского human papilloma virus). Вирус относится к ДНК — содержащим вирусам. И это означает его умение встраиваться в ДНК клеток человека и менять ее свойства.

Сегодня открыто более 100 его видов. Но только некоторые из них особо вредны для человека и могут вызывать следующие заболевания:

• остроконечные кондиломы половых органов у мужчин и женщин (6 и 11 тип)

• генитальные бородавки и папилломатоз

гортани (8, 11, 16, 18, 31, 35 типа)

• контагиозный моллюск (6, 8, 11, 16 типа)

• рак шейки матки и влагалища — у женщин и рак полового члена и простаты — у

мужчин (16 и 18 тип)

Заражение вирусом не есть заболевание.

По статистике, только один из трех носителей папилломавируса по-настоящему заболевает. Попадая в клетку, вирус папилломы

человека изменяет ее генетический аппарат,

что в свою очередь приводит к ненормальному темпу ее деления, изменению внешнего вида клетки. Длительно, а иногда и недлительно существуя, папилломавирусы настолько изменяют генетический аппарат клетки, что та даёт начало росту раковой опухоли. Носители папилломавируса человека болеют раком половых органов в 3-5 раз чаще, чем не носители! Для того, чтобы болезнь проявилась в «злой» форме, нужно сочетание многих неблагоприятных факторов:

  • раннее начало половой жизни
  • частая смена или наличие нескольких половых партнеров
  • воспалительные процессы женской половой системы
  • травмы шейки матки в родах или абортах
  • сопутствующие инфекции, передающиеся половым путем: хламидиоз, уреаплазмоз, микоплазмоз, генитальный герпес, гонорея и др
  • применение противозачаточных таблеток
  • курение
  • недостаточность клеточного иммунитета (анемия, патология щитовидной железы, наличие хронических очагов кокковой инфекции — тонзиллит, гайморит, кариес)
  • беременность
  • искусственное ограничение питания, снижение веса.

Кстати многие из этих факторов риска имеют социальный характер, то есть от самого человека зависит, заболеет он или нет. Инфекция передается между взрослыми половым путем или при прямом или косвенном контакте в парикмахерских, бассейнах, залах маникюра-педикюра при нарушении кожного покрова. Также вирус может передаваться от матери к ребенку при прохождении через родовые пути во время родов.

Есть данные за внутриутробное (через плаценту) заражение плода ВПЧ 6 и 11 типа. Человек опасен для окружающих как источник возможного заражения только при наличии разрастаний на коже и слизистых. В скрытом периоде болезни перенос практически невозможен. То есть, если у пациентки обнаружен ВПЧ в результате обследования, а жалоб никаких нет, то женщина не заразна для своего полового партнера членов своей семьи и т.д. Проявляется инфекция после заражения не сразу. Лишь через 1-2 недели , а нередко и 3 месяца на месте, встретившемся с зараженной поверхностью, возникают первые признаки болезни.

Основным проявлением во всех случаях является папиллома — образование на поверхности кожи или слизистой оболочки. На ощупь папилломы мягкие, на вид могут быть дольчатыми, цвет имеют розовый или же телесный. В ответ на раздражение, бородавка может увеличиваться в размерах и достигать 5-7 см в диаметре, состоят они из измененных клеток кожи или слизистой оболочки. Появляются жалобы на зуд во влагалище, дискомфорт во время половой жизни, появляются мелкие разрастания и бородавки в области входа во влагалище и на коже половых органов. Часто при папилломатозе долго не заживают или повторно возникают эрозии шейки матки, даже если их правильно лечили и прижигали.

Диагностика пилломавирусной инфекции, особенно когда речь идет о локализации поражений на видимых участках тела, не сложна. Иногда достаточно лишь осмотра, чтобы поставить диагноз. В случае же сомнений, а также при поражении внутренних половых органов, прежде всего шейки матки, мочеиспускательного канала требуется проведение анализа. Сегодня наиболее достоверным методом диагностики является полимеразная цепная реакция (ПЦР).

Как лечить?

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

  • Деструктивные методы — физические (криодеструкция, лазеротерапия, радиоволновой метод, диатермокоагуляция, электрохирургическое иссечение), химические (трихлоруксуевая кислота, ферезол. солкодерм, кондилин)
  • Иммунологические методы.
  • Комбинированные методы — сочетание применения различных методов лечения (криотерапия, лазерное иссечение, электрокоагуляция, диатермокоагуляция, озонотерапия).

Как уберечь себя от инфекции и рака шейки матки (РШМ)? Признание инфекционной природы РШМ открыло возможности его первичной профилактики путем создания вакцин, предупреждающих заражение ВПЧ. В настоящее время уже существуют вакцины, эффективность которых достигает 99-100%.

Вакцинироваться желательно девушкам до начала половой жизни, а также молодым женщинам в начале их активной сексуальной жизни. В настоящее время уже получены данные об эффективности вакцинации у женщин старшего возраста. Вакцина защищает от наиболее опасных типов вируса. Курс прививок состоит из трех внутримышечных инъекций, которые пациентка должна получить с определенным интервалом в течение 6 месяцев. Как и при любой другой вакцинации, пациентка не должна иметь серьезных соматических и неврологических заболеваний, заболеваний крови. Противопоказаниями также являются: беременность и непереносимость компонентов вакцины. Переносится вакцина хорошо.

Что делать с партнером?

Развитие онкологических заболеваний половых органов у женщин тесно связано с ВПЧ инфекцией гениталий у мужчин, являющихся их сексуальными партнерами. В результате исследования связи рака шейки матки у женщин с инфицированным ВПЧ их сексуальных парнеров были обнаружены остроконечные кондиломы у 64,4% мужчин! Отсюда следует, что вопрос о профилактике, своевременной диагностике и лечении стоит очень остро. Тактика лечения будет определена Вашим врачом после тщательного обследования и постановки диагноза.

Папилломавирусная инфекция – самая распространенная инфекция половых путей

Вакцина Цена
ГардасилMerck Sharp & Dohme (MSD), США 14500 ₽
ЦервариксGlaxoSmithKline Biologicals S.A., Бельгия нет в наличии

ВПЧ (вирус папилломы человека) является наиболее распространенной вирусной инфекцией половых путей. Существует 40 различных типов этого вируса, которые могут инфицировать область гениталий мужчин и женщин, включая кожу пениса, вульву (область вне влагалища) и анус, а также шейку матки и прямую кишку.

Некоторые типы ВПЧ безвредны, тогда как другие (в том числе типы 16, 18, 6, 11) могут вызывать различные онкологические заболевания, прежде всего генитальной области:

  • Рак шейки матки (рак нижнего отдела матки) у женщин,
  • Патологические и предраковые изменения шейки матки (т. е. такие изменения клеток шейки матки, при которых существует риск их трансформации в опухолевые),
  • Рак влагалища и вульвы (рак наружных половых органов) у женщин,
  • Генитальные бородавки (кондиломы) у женщин и мужчин.

Рак шейки матки– это тяжелое заболевание, представляющее угрозу для жизни. Практически все случаи рака шейки матки (99%) связаны с заражением гениталий женщины некоторыми типами ВПЧ. Эти типы вируса могут способствовать изменению клеток поверхностного слоя шейки матки, вызывая трансформацию их из нормальных в предраковые. Если такие изменения не лечить, они могут перейти в рак. Рак шейки матки занимает второе место в мире среди видов рака, наиболее распространенных у женщин. По данным Всемирной организации здравоохранения (ВОЗ) ежегодно отмечается около 500000 новых случаев заболевания и 250 000 смертельных исходов.

Генитальные кондиломы вызываются определенными типами ВПЧ. Они, как правило, появляются в виде телесного цвета разрастаний неправильной формы. Обнаруживаются они на внутренней или внешней поверхности наружных гениталий как у женщин, так и у мужчин. Генитальные кондиломы могут причинять боль, вызывать зуд, кровотечение и дискомфорт. Иногда после удаления они могут возникать вновь.

ВПЧ может передаваться от человека к человеку воздушно-капельным или бытовым путем, но прежде всего половым. Риску заражения подвергаются мужчины и женщины любого возраста, участвующие в любых формах сексуального поведения, при которых имеет место генитальный контакт. У многих людей, заразившихся ВПЧ, нет никаких признаков или симптомов, и поэтому они непреднамеренно могут передавать вирус другим людям.

Пик заболеваемости ВПЧ, как правило, приходится на возраст от 16 до 20 лет. ВПЧ-инфекция может излечиваться спонтанно, однако при хроническом течении она может привести к предраковым состояниям, а через 20-30 лет перейти в рак.

В настоящее время эффективных и доказанных методов лечения инфекции, вызванной ВПЧ, нет.

КАК МОЖНО ЗАЩИТИТЬ СЕБЯ ОТ ЗАБОЛЕВАНИЙ, СВЯЗАННЫХ С ВПЧ

В настоящее время в мире и на территории Российской Федерации лицензированы две инактивированные вакцины для профилактики инфекций, вызванных ВПЧ – Гардасил и Церварикс.

Вакцины против ВПЧ содержат главные капсидные капсидные белки L1, которые сами собираются в вирусоподобные частицы (VLP). Эти частицы не содержат вирусный генетический материал, а потому не являются инфекционными.

Обе вакцины направлены против ВПЧ 16 и 18 типов, являющихся причиной не менее 70% случаев рака шейки матки в мире. Кроме того, вакцина Гардасил также направлена против ВПЧ типов 6 и 11, которые вызывают слабо выраженные цервикальные патологии и подавляющее большинство остроконечных кондилом.

Результаты масштабных исследований воздействия вакцин против ВПЧ с последующим многолетним наблюдением показали почти 100 процентную защиту от предшествующих раку состояний шейки матки, связанных с данными генотипами вируса.

Какой опыт применения вакцин против ВПЧ?

В настоящее время вакцины против ВПЧ активно применяются во многих странах мира. В ряде зарубежных стран прививка против ВПЧ включена в Национальные программы иммунизации. В США вакцинация проводится среди всех девочек в возрасте 11-12 лет, во Франции — в 14 лет, в Германии — в 12-17 лет, в Австрии — в возрасте 9-17 лет.

Мировой опыт применения этих вакцин в течение нескольких лет показал их безопасность и высокую профилактическую эффективность.

Для кого предназначены вакцины против ВПЧ?

В настоящее время вакцины против ВПЧ применяются главным образом среди молодых женщин и девочек — подростков:

Вакцина Кому разрешена?
Гардасил

— дети 9-17 лет (девочки и мальчики),

— молодые женщины 18-26 лет

Церварикс — девочки и молодые женщины 10-25 лет

Вместе с тем, продолжаются исследования по применению вакцин против ВПЧ в других возрастных группах, поэтому со временем возрастные показания к применению этих вакцин будут расширяться.

С 2009 года в целях реализации Городской программы профилактики заболеваний раком шейки матки у женщин вакцинация против ВПЧ была включена в Региональный календарь профилактических прививок г. Москвы. При этом вакцинация проводится бесплатно среди девочек-подростков в возрасте 12-13 лет в поликлинике по месту жительства или школе.

Схема вакцинации против ВПЧ

Стандартный курс вакцинации состоит из трех прививок:
Вакцина Стандартная схема Ускоренная схема
Гардасил

0 — 2 — 6 мес

1-я – выбранный день,

2-я – через 2 месяца после первой дозы,

3-я – через6 месяцев после первой дозы.

0 — 1 — 3 мес

1-я – выбранный день,

2-я – через 1 месяц после первой дозы,

3-я – через3 месяца после первой дозы.

Церварикс

0 -1— 6 мес

1-я – выбранный день,

2-я – через 1 месяц после первой дозы,

3-я – через6 месяцев после первой дозы.

Вакцина вводится внутримышечно (в виде инъекции) в дозе 0,5 мл для всех возрастных групп.

Необходимость ревакцинации к настоящему времени не установлена.

Противопоказания к вакцинации против ВПЧ

Инфицированность одним из типов ВПЧ, входящих в состав вакцин, не является противопоказанием к вакцинации! Но следует посоветоваться с врачом и гинекологом о необходимости такой прививки.

Вакцины против ВПЧ противопоказаны при:

  • Аллергии на любой компонент вакцины
  • Сильных аллергических реакциях на предыдущее введение этого препарата
  • Беременности

Как и для любой прививки, временными противопоказаниями к вакцинации являются острые заболевания и обострения хронических болезней. В таких случаях прививка откладывается до выздоровления.

Кормление грудью не является противопоказанием к введению вакцин против ВПЧ.

Возможны ли побочные реакции на введение вакцин против ВПЧ?

Вакцины против ВПЧ переносятся хорошо.

Как и на любую другую инактивированную вакцину возможны следующие реакции в первые 2-3 дня после введения: болезненность в месте укола, припухлость, покраснение, зуд, а также общие реакции – недомогание, повышение температуры тела.

Существующая система мониторинга безопасности применяемых вакцин в США (VAERS) не зарегистрировала каких-либо осложнений за все время использования вакцины Гардасил в стране (более 12 млн. доз).

Насколько эффективны вакцины против ВПЧ?

После проведенного полного курса вакцинации защитные антитела определяются у более чем 99% привитых. Результаты масштабных исследований воздействия этих вакцин с последующим наблюдением в течение 2-5 лет показали почти 100 процентную защиту от предшествующих раку состояний шейки матки. Защита от остроконечных кондилом составляла 95-99%.

Более того, наличие в составе вакцины Церварикс адъюванта AS04 (вещества, усиливающего иммунный ответ на вакцинацию), приводит к выработке более длительного и стойкого иммунитета у вакцинированных.

Важно помнить!

Данные вакцины предназначены для профилактики заболеваний, вызванных ВПЧ, но не для их лечения!

Вакцины против ВПЧ не защищают от заболеваний, причиной которых не является ВПЧ.

Данная публикация подготовлена специалистами в области иммунопрофилактики, сотрудниками Кафедры инфекционных болезней у детей (Ассоциация педиатров-инфекционистов) ГБОУ ВПО РНИМУ имени Н.И. Пирогова Минздравсоцразвития России с использованием материалов Федеральной службы по надзору в сфере защиты прав потребителей и благополучия человека, Территориального управления Роспотребнадзора по городу Москве, данных и рекомендаций Всемирной организации здравоохранения, а также других международных организаций.

Папилломавирусная инфекция — сделать прививку в Москве в ЦКБ РАН

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

Пути передачи — половой, оральный, контактный и заражение младенца при родах.

Обязательным условием проникновения вируса в организм является травма слизистой или эпителия, даже самая незначительная.

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

Неонкогенные папилломавирусы, вызывающие формирование различного рода кондилом на половых органах, папилломатоз гортани у детей, относятся к 6 и 11 типу ВПЧ. Вирусы папилломы человека с высоким онкогенным риском, чаще всего 16 и 18 типа, становятся причиной опухолевых заболеваний у женщин и мужчин, таких как рак шейки матки, влагалища, вульвы, анального отверстия, полового члена, орофарингеальный рак.

Самый надежный способ защитить себя и своих близких от этой коварной инфекции — вакцинация.

Прививки введены в нацкалендарь на государственном уровне в более чем в 80! странах мира.

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

Наиболее широкой степенью защиты обладает 4-хвалентная вакцина Гардасил, которая содержит рекомбинантные антигены вирусов папиллом человека 6, 11, 16, 18 типов и потому обеспечивает иммунную защиту против и доброкачественных, и злокачественных поражений. Прививка применяется у детей с 9-летнего возраста. Подросткам до 14 лет вводится дважды, старше 14 лет – трижды на протяжении 6 месяцев, равно как и взрослым. Актуальна иммунизация и женщин, а также мужчин 26 лет.

Лучшая защита — это профилактика!!! Будьте здоровы!!!!

Персистирующая папилломавирусная инфекция в генезе репродуктивных потерь. Перспективы терапии

Раздел только для специалистов в сфере медицины, фармации и здравоохранения!

Н.И. Тапильская1,2, К.В. Объедкова1, И.О. Крихели1, Л.Ш. Цечоева3Р.И. Глушаков2,4; 1 Научно-исследовательский институт акушерства, гинекологии и репродуктологии им. Д.О. Отта, Санкт-Петербургский государственный педиатрический медицинский университет, 3 Санкт-Петербургский научно-исследовательский институт скорой помощи им. И. И. Джанелидзе

Вирусные пандемии продемонстрировали, что инфицированные беременные женщины находятся в группе риска по неблагоприятному течению беременности. Современные данные подтверждают, что иммунная система беременной претерпевает трансформацию, необходимую для поддержания беременности и роста плода. Вирус папилломы человека (ВПЧ) отличается высокой распространенностью, при этом его роль в неблагоприятных исходах беременности и репродуктивных потерях является крайне противоречивой. Около 90% случаев персистирующей папилломавирусной инфекции (ПВИ) элиминирует в течение одного-двух лет. Роль иммунной системы в элиминации и персистенции ПВИ является доказанной, однако до настоящего времени нет четкого понимания механизмов ускользания ВПЧ от иммунного надзора. При этом иммунные механизмы, лежащие в основе персистенции ПВИ, являются патогенетическим базисом для формирования механизмов бесплодия, невынашивания и патологии беременности. Генетический полиморфизм матери и развивающегося плода, персистирующие типы ВПЧ и микробный пейзаж являются модулирующими факторами с невыясненным вкладом при переходе количества привносимых влияний на качественное изменение биологического состояния. Проанализированные авторами данные зарубежных и российских научных исследований свидетельствуют, что своевременная и адекватная терапия ПВИ может быть вкладом в сохранение репродуктивного потенциала и предотвращение акушерских потерь. Современный подход к лечению персистирующей ПВИ предполагает применение противовирусной и иммуномодулирующей терапии. Инозин пранобекс благодаря своим иммуномодулирующим и противовирусным свойствам используется для лечения вирусных заболеваний, таких как ВПЧ, вирусы простого герпеса, цитомегалии, вирус Эпштейна – Барр и грипп.

Полный текст статьи доступен только для зарегистрированных пользователей. Пожалуйста, авторизуйтесь или зарегистрируйтесь на сайте.

Папилломавирусная инфекция у женщин — что делать, если поставлен такой диагноз?

Папилломавирусная инфекция у женщин – это инфекционное вирусное заболевание, которое передаётся половым путём и проявляется в виде специфических образований на коже и слизистых оболочках – папиллом.

Пути заражения

Инфицирование кожи и слизистых оболочек наружных половых органов вирусом папилломы человека (ВПЧ) происходит во время половых контактах. Причем, контакты могут носить разный характер:

  • генитальные;
  • орально-генитальные;
  • анально-генитальные.

Согласно статистике, на данный момент вирусом инфицировано около 15% женщин, вступавших в связь с одним партнёром, 30% — вступавших в связи с 2-мя и более партнёрами, 50% — имевших 5 и более партнёров.

В ЦЭЛТ вы можете получить консультацию специалиста-гинеколога.

  • Первичная консультация — 3 000
  • Повторная консультация — 2 000
Записаться на прием

Симптомы

Папилломавирусная инфекция у женщин может проявляться в виде папиллом, кондилом, генитальных бородавок. После заражения проходит инкубационный период, который может продолжаться в течение 1 – 8 (в среднем – 3 – 5 недель).

Всё заболевание может протекать бессимптомно: женщина не испытывает ни болей, ни зуда, ни какого-либо дискомфорта.

Кондиломы, папилломы и генитальные бородавки появляются на коже в районе половых органов и ануса, на слизистой оболочке влагалища, шейки матки. Они могут иметь различные размеры, от пятна с шероховатостью до больших опухолевидных образований.

Генитальные бородавки нередко появляются впервые или рецидивируют при снижении иммунитета. Например, во время беременности.

Возбудитель вызывает мутации в геноме, поэтому он представляет потенциальную опасность в плане развития рака половых органов у женщины.

Известно более 100 типов ВПЧ, к онкогенным относят 13 типов. Онкоопасные вирусы могут вызвать рак шейки матки, влагалища и вульвы.

Диагностика

При подозрении на папилломавирусную инфекцию проводят следующие исследования:
  • Внешний осмотр. Если папилломы находятся на коже в области половых органов, то их диагностика не представляет сложностей.
  • Кольпоскопия и вульвоскопия – исследования шейки матки, влагалища и вульвы (наружной части влагалища) под микроскопом. При этом можно обнаружить папилломы на слизистой оболочке.
  • Цитологическое исследование мазков (изучение под микроскопом). Удается точно поставить диагноз в 80% случаев.
  • ПЦР – полимеразная цепная реакция. Позволяет обнаружить ДНК вируса.

Наши врачи

Врач-гинеколог, заведующий отделением гинекологии, кандидат медицинских наук, врач высшей категории

Стаж 32 года

Записаться на прием

Лечение

Лечение папилломавирусной инфекции слагается обычно из следующих направлений:

  • Воздействие непосредственно на самого возбудителя – применение противовирусных препаратов.
  • Укрепление иммунных сил – применение иммуномодуляторов.
  • Удаление образований (папиллом) при помощи современных методик.
  • Хирургическое лечение и мониторинг состояния шейки матки.

В многопрофильной клинике ЦЭЛТ работают опытные специалисты, которые после всесторонней диагностики назначат комплекс наиболее эффективных мероприятий. В своей работе мы придерживаемся высоких стандартов и предоставляем пациентам качественную медицинскую помощь.


Областной центр диагностики и лечения патологии шейки матки

Руководитель Областного центра областного центра диагностики и лечения патологии шейки матки, врач-акушер-гинеколог высшей квалификационной категории, онколог, д.м.н. — Димитриади Татьяна Александровна

Областной центр диагностики и лечения патологии шейки матки

В 2008 году  на базе ОКДЦ организован  Областной центр патологии шейки матки, где наблюдаются и лечатся пациентки города и области.

Шейкой матки называется нижний отдел матки. В теле матки растет и развивается плод. Шейка матки соединяет тело матки с родовым каналом — влагалищем. Участок шейки, расположенный ближе всего к телу матки, носит название эндоцервикс ( или цервикальный канал). Влагалищная часть шейки матки называется экзоцервикс (самая близкая к влагалищу часть), эти отделы покрывают различные типы клеток.

В структуре онкологических заболеваний у женщин рак шейки матки занимает стабильное второе место после рака молочной железы, за последние десятилетия отмечен рост заболеваемости у пациенток моложе 40 лет. К сожалению, каждая пятая женщина умирает от рака шейки матки в течение года только потому, что диагноз был поставлен слишком поздно. Гинекологи во всем мире говорят о необходимости своевременной диагностики, которая могла бы предотвратить столь плачевный исход для многих женщин и их семей. В настоящее время все больше данных о том, что программы скрининга способствуют снижению заболеваемости раком шейки матки. Подобных программ существует множество, но все они включают ежегодный осмотр гинеколога и мазок на онкоцитологию.

Обратим внимание на некоторые ФАКТОРЫ РИСКА, часть из которых мы в состоянии изменить или исключить, например, отказаться от курения или вылечить папилломавирусную инфекцию. Риск развития рака шейки матки у курящих женщин почти в два раза выше, чем у некурящих.

Папилломавирусная инфекция (ПВИ) — это причина и главный фактор риска развития рака шейки матки.

Вирус папилломы человека (ВПЧ) — это группа из более чем 100 родственных вирусов, некоторые из них вызывают обыкновенные бородавки (вирусы ВПЧ 6 типа и ВПЧ 11 типа) и относятся к так называемым вирусам низкого онкогенного риска, поскольку редко вызывают рак.

Отдельные типы ВПЧ называются вирусами высокого онкогенного риска, поскольку тесно связаны с развитием рака, включая рак шейки матки. К вирусам высокого риска относятся ВПЧ 16, ВПЧ 18, ВПЧ 31, ВПЧ 33 и ВПЧ 45 и другие типы. Около 2/3 случаев рака шейки матки связаны с ВПЧ 16 и ВПЧ 18.

Известно, что рак шейки матки является полностью предотвратимым заболеванием и при регулярных профилактических визитах к гинекологу заболевание можно предотвратить, либо диагностировать на самых ранних стадиях. Своевременная диагностика  и лечение фоновых и предраковых заболеваний шейки матки, мониторинг женщин групп риска, скринговые методы обследования и информирование женщин так же являются  профилактикой рака шейки матки.

Первичная профилактика РШМ стала возможна лишь с конца 2005г, когда в России были зарегистрированы вакцины от онкогенных типов папилломовирусной инфекции (ПВИ). Вакцинация у женщин не имевших ранее заражение этим типом вируса, эффективно предотвращает развитие атипичных цервикальных клеток, обусловленных типами ВПЧ. Поэтому вакцинация снижает риск необходимости лечения патологических цервикальных процессов и уменьшает риск развития рака шейки матки. В ОКДЦ успешно ведет работу кабинет вакцинопрофилактики, где могут прививаться пациентки  с 8 – 26 лет двумя зарегистрированными в России вакцинами против ВПЧ.

Гинекологическая служба ОКДЦ имеет 10-летний опыт успешной работы по выявлению, лечению и мониторингу пациенток с патологией шейки матки. Консультативный прием  ведут высококвалифицированные врачи-гинекологи, постоянно повышающие свой профессиональный уровень на базах ведущих  научных центров.

Проанализировав мировой опыт скрининга рака шейки матки и приобретя собственный,  в  ОКДЦ  в программу обследования женщин при первичном обращении, помимо традиционного цитологического контроля и расширенной видеокольпоскопии,  включен ВПЧ-тест. ВПЧ-тест выявляет инфицирование и количественную вирусную нагрузку 13  типов ПВИ высокого онкогенного риска. Выявление  ДНК вирусов папилломы человека высоко онкогенного риска, говорит, о том,  что клетки эпителия могут подвергнуться  злокачественному перерождению. При раннем выявлении клеточных изменений лечение является успешным на 100%.

Лечение заболеваний шейки матки, в особенности у  пациенток планирующих беременность в дальнейшем, должно быть обоснованным, непродолжительным по времени, радикальным и по возможности бережным.    

Диагностические мероприятия проводимые гинекологической службой :

  • консультация гинеколога;
  • видеокольпоскопия — осмотр шейки матки в кольпоскоп (микроскоп) с печатью снимков;
  • жидкостная цитология
  • ВПЧ тестирование – определение высокогоонкогенных типов ВПЧ и количественной вирусной нагрузки
  • прицельная биопсия шейки матки;
  • цервикоскопия
  • гистероскопия;
  • гистологическое исследование экспертного уровня
  • диагностика инфекций передающихся половым путем
  • бактериологический посев на дисбиоз влагалища и микоплазмы
  • культуральная диагностика хламидий
  • ИФА с определением титра антител к хламидиям, вирусу герпеса, цитомегаловирусу и т.д.;
  • Определение уровня половых гормонов
  • УЗИ органов малого таза на оборудовании экспертного класса;
  • исследование гормонального статуса и протромбогенного риска приема гормональных препаратов
  • УЗИ молочных желез и маммография

Кто нуждается в обследовании в Областном центре патологии шейки матки?

Женщины, у которых по данным гинекологического осмотра, цитологического исследования или ВПЧ тестирования выявлены следующие изменения:

  • ВПЧ
  • остроконечные кондиломы влагалища и наружных половых органов
  • папилломы наружных половых органов
  • эктопия цилиндрического эпителия
  • эрозия шейки матки
  • зона трансформации
  • рубцовая деформация шейки матки
  • L-SIL, H-SIL, (плоскоклеточные интаэпителиальные поражения), ASCUS (плоскоклеточная атипия неопределенной значимости)
  • эндометриоз шейки матки
  • хронический цервицит

А так же в случаи выявления при гистологическом исследовании:

  • CIN 1,2,3( цервикальная интраэпителиальная неоплазия)
  • кондиломы шейки матки

Лечебные возможности Областного центра патологии шейки матки:

  • лазервапоризация СО2 -лазер
  • радиоволновая терапия на аппарате «Сургитрон»
  • электроконизация шейки матки
  • удаление папиллом с наружных половых органов

Быстрый старт — документация peewee 3.14.9

В этом документе представлен краткий высокоуровневый обзор основного Особенности. Это руководство охватывает:

Примечание

Если вы хотите что-то более мясистое, есть подробное руководство по создание веб-приложения в стиле «твиттера» с использованием peewee и Каркас фляги. В папке проектов примеров/ вы можете найти больше автономные примеры Peewee, такие как приложение для блога.

Я настоятельно рекомендую открыть сеанс интерактивной оболочки и запустить код.Таким образом, вы можете почувствовать, как вводить запросы.

Определение модели

Классы моделей, поля и экземпляры моделей сопоставляются с понятиями базы данных:

Объект Соответствует…
Модельный класс Таблица базы данных
Экземпляр поля Столбец на стол
Экземпляр модели Строка в таблице базы данных

При запуске проекта с peewee, как правило, лучше всего начать с вашего модель данных путем определения одного или нескольких классов модели :

 из импорта пиуи *

db = SqliteDatabase('люди.дБ')

класс Человек(Модель):
    имя = CharField()
    день рождения = DateField ()

    Мета класса:
        database = db # Эта модель использует базу данных "people.db".
 

Примечание

Peewee автоматически выведет имя таблицы базы данных из имени класс. Вы можете переопределить имя по умолчанию, указав table_name атрибут во внутреннем классе «Мета» (наряду с атрибутом базы данных ). Чтобы узнать больше о том, как Peewee генерирует имена таблиц, см. обратитесь к разделу Имена таблиц.

Также обратите внимание, что мы назвали нашу модель Person вместо People . Это соглашение, которому вы должны следовать, даже если таблица будет содержать несколько человек, мы всегда называем класс в форме единственного числа.

Существует множество типов полей, подходящих для хранения различных типы данных. Peewee обрабатывает преобразование между значениями pythonic и теми, используемые базой данных, поэтому вы можете использовать типы Python в своем коде, не волноваться.

Все становится интереснее, когда мы устанавливаем отношения между моделями, используя отношения внешнего ключа.Это просто с peewee:

 класс домашних животных (модель):
    владелец = ForeignKeyField(Person, backref='домашние животные')
    имя = CharField()
    animal_type = CharField()

    Мета класса:
        database = db # эта модель использует базу данных "people.db"
 

Теперь, когда у нас есть модели, давайте подключимся к базе данных. Хотя это не необходимо открыть соединение явно, это хорошая практика, так как немедленно выявить любые ошибки с подключением к базе данных, в отличие от некоторых произвольное время спустя, когда выполняется первый запрос.Также хорошо закрыть соединение, когда вы закончите — например, веб-приложение может открыть соединение, когда он получает запрос, и закрывает соединение, когда он отправляет ответ.

Начнем с создания таблиц в базе данных, в которых будут храниться наши данные. Это создаст таблицы с соответствующими столбцами, индексами, последовательностями, и ограничения внешнего ключа:

 db.create_tables([Человек, Домашнее животное])
 

Сохранение данных

Давайте начнем с заполнения базы данных некоторыми людьми.Мы будем использовать save() и create() методов для добавления и обновления рекорды людей.

 с даты импорта даты и времени
uncle_bob = Человек (имя = 'Боб', день рождения = дата (1960, 1, 15))
uncle_bob.save() # боб теперь хранится в базе данных
# Возвращает: 1
 

Примечание

При вызове save() количество измененных строк равно вернулся.

Вы также можете добавить человека, вызвав метод create() , который возвращает экземпляр модели:

 бабушка = Человек.создать (имя = 'Бабушка', день рождения = дата (1935, 3, 1))
herb = Person.create(name='Herb', Birthday=date(1950, 5, 5))
 

Чтобы обновить строку, измените экземпляр модели и вызовите save() для сохранить изменения. Здесь мы изменим имя бабушки, а затем сохраним изменений в базе:

 grandma.name = 'Бабушка Л.'
grandma.save() # Обновить имя бабушки в базе данных.
# Возвращает: 1
 

Теперь мы сохранили в базе 3 человека. Давайте подарим им домашних животных.Бабушка не любит животных в доме, поэтому у нее их не будет, но Херб — животное любовник:

 bob_kitty = Pet.create(владелец=uncle_bob, name='Kitty', animal_type='cat')
herb_fido = Pet.create (владелец = трава, имя = 'Фидо', animal_type = 'собака')
herb_mittens = Pet.create (владелец = трава, имя = 'Варежки', animal_type = 'кошка')
herb_mittens_jr = Pet.create(owner=herb, name='Варежки-младший', animal_type='cat')
 

После долгой полноценной жизни Варежки заболевают и умирают. Нам нужно убрать его из база данных:

 травяные_рукавицы.delete_instance() # у него была отличная жизнь
# Возвращает: 1
 

Примечание

Возвращаемое значение delete_instance() — это количество строк удалены из базы данных.

Дядя Боб решает, что в доме Херба умирает слишком много животных, поэтому он принимает Фидо:

 herb_fido.owner = дядя_боб
herb_fido.save()
 

Получение данных

Настоящая сила нашей базы данных в том, как она позволяет нам извлекать данные через запросов .Реляционные базы данных отлично подходят для создания запросы.

Получение отдельных записей

Давайте извлечем запись бабушки из базы данных. Чтобы получить одну запись из базу данных, используйте Select.get() :

 бабушка = Person.select().where(Person.name == 'Бабушка Л.').get()
 

Мы также можем использовать эквивалентное сокращение Model.get() :

 бабушка = Person.get(Person.name == 'Бабушка Л.')
 

Списки записей

Давайте перечислим всех людей в базе данных:

 для человека в лицо.Выбрать():
    печать(человек.имя)

# отпечатки:
# Боб
# бабушка Л.
# Трава
 

Давайте перечислим всех кошек и имя их владельца:

 запрос = Pet.select().where(Pet.animal_type == 'кошка')
для питомца в запросе:
    print(pet.name, pet.owner.name)

# отпечатки:
# Китти Боб
# Варежки Jr Herb
 

Внимание

Существует большая проблема с предыдущим запросом: поскольку мы обращаемся pet.owner.name и мы не выбрали это отношение в нашем исходном запрос, peewee должен будет выполнить дополнительный запрос, чтобы получить хозяин питомца.Это поведение называется N+1, и оно вообще следует избегать.

Подробное руководство по работе со связями и соединениями см. Документация по отношениям и соединениям.

Мы можем избежать дополнительных запросов, выбрав оба Pet и Person и добавив присоединиться к .

 запрос = (домашнее животное
         .select(домашнее животное, человек)
         .присоединиться(Человек)
         .где(Pet.animal_type == 'кошка'))

для питомца в запросе:
    print(pet.name, pet.имя владельца)

# отпечатки:
# Китти Боб
# Варежки Jr Herb
 

Соберем всех питомцев Боба:

 для питомца в Pet.select().join(Person).where(Person.name == 'Bob'):
    печать (имя животного)

# отпечатки:
# Китти
# Фидо
 

Здесь мы можем сделать еще одну интересную вещь, чтобы получить питомцев Боба. Поскольку у нас уже есть объект для представления Боба, вместо этого мы можем сделать это:

 для питомца в Pet.select().where(Pet.owner == uncle_bob):
    печать (имя животного)
 

Сортировка

Давайте удостоверимся, что они отсортированы по алфавиту, добавив order_by() пункт:

 для питомца в пет.select().where(Pet.owner == uncle_bob).order_by(Pet.name):
    печать (имя животного)

# отпечатки:
# Фидо
# Китти
 

Теперь перечислим всех людей, от младшего к старшему:

 для человека в Person.select().order_by(Person.birthday.desc()):
    print(человек.имя, человек.день рождения)

# отпечатки:
# Боб 1960-01-15
# Херб 1950-05-05
# Бабушка Л. 1935-03-01
 

Объединение выражений фильтра

Peewee поддерживает произвольно вложенные выражения. Давайте соберём всех людей, чьи день рождения был либо:

  • до 1940 г. (бабушка)
  • после 1959 г. (б)
 d1940 = дата (1940, 1, 1)
d1960 = дата (1960, 1, 1)
запрос = (человек
         .Выбрать()
         .where((Person.birthday < d1940) | (Person.birthday > d1960)))

для лица в запросе:
    print(человек.имя, человек.день рождения)

# отпечатки:
# Боб 1960-01-15
# Бабушка Л. 1935-03-01
 

Теперь сделаем наоборот. Люди, чей день рождения приходится на период с 1940 по 1960 год:

.
 запрос = (Человек
         .Выбрать()
         .где(Человек.день рождения.между(д1940, д1960)))

для лица в запросе:
    print(человек.имя, человек.день рождения)

# отпечатки:
# Херб 1950-05-05
 

Агрегаты и предварительная выборка

Теперь давайте перечислим всех людей и , сколько у них домашних животных:

 для человека в лицо.Выбрать():
    print(person.name, person.pets.count(), 'домашние животные')

# отпечатки:
# Боб 2 питомца
# Бабушка Л. 0 питомцев
# Трава 1 питомца
 

Мы снова столкнулись с классическим примером запроса N+1 поведение. В этом случае мы выполняем дополнительный запрос для каждого Лицо возвращено исходным ВЫБЕРИТЕ ! Мы можем избежать этого, выполнив a JOIN и использование функции SQL для агрегирования результатов.

 запрос = (Человек
         .select(Person, fn.COUNT(Pet.идентификатор).псевдоним('pet_count'))
         .join(Pet, JOIN.LEFT_OUTER) # включить людей без домашних животных.
         .group_by(человек)
         .order_by(Person.name))

для лица в запросе:
    # "pet_count" становится атрибутом возвращаемых экземпляров модели.
    print(person.name, person.pet_count, 'домашние животные')

# отпечатки:
# Боб 2 питомца
# Бабушка Л. 0 питомцев
# Трава 1 питомца
 

Примечание

Peewee предоставляет волшебного помощника fn() , который можно использовать для вызова любая функция SQL. В приведенном выше примере фн.COUNT(Pet.id).псевдоним('pet_count') будет преобразовано в COUNT(pet.id) AS pet_count .

Теперь перечислим всех людей и имена всех их питомцев. Как у вас может быть догадались, это может легко превратиться в очередную ситуацию N+1, если мы не осторожны.

Прежде чем углубляться в код, подумайте, чем этот пример отличается от предыдущий пример, где мы перечислили всех домашних животных и имя их владельца. Домашнее животное может только один владелец, поэтому, когда мы выполнили объединение от Pet до Person , всегда должен был быть одиночный матч.Иная ситуация, когда мы присоединяются от Person к Pet , потому что у человека может не быть домашних животных или у них может быть несколько домашних животных. Поскольку мы используем реляционные базы данных, если мы должны были выполнить соединение от Person до Pet , тогда каждый человек с несколькими домашние животные будут повторяться, один раз для каждого домашнего животного.

Это будет выглядеть так:

 запрос = (Человек
         .select(Человек, Домашнее животное)
         .join(Домашнее животное, JOIN.LEFT_OUTER)
         .order_by(Человек.имя, пет.имя))
для лица в запросе:
    # Нам нужно проверить, есть ли у них экземпляр питомца, так как не все
    # у людей есть домашние животные.
    если hasattr(человек, 'домашнее животное'):
        print(person.name, person.pet.name)
    еще:
        print(person.name, 'без домашних животных')

# отпечатки:
# Боб Фидо
# Боб Китти
# Бабушка Л. без домашних животных
# Херб Варежки-младший
 

Обычно такое дублирование нежелательно. Для размещения более распространенных (и интуитивно понятный) рабочий процесс перечисления человека и прикрепления списка этого домашних животных человека, мы можем использовать специальный метод, называемый предварительная выборка() :

 запрос = Человек.select().order_by(Person.name).prefetch(Pet)
для лица в запросе:
    печать(человек.имя)
    для домашних животных лично.
        print('*', pet.name)

# отпечатки:
# Боб
# * Китти
# * Фидо
# бабушка Л.
# Трава
# * Варежки младший
 

Функции SQL

Последний запрос. Это будет использовать функцию SQL, чтобы найти всех людей, чьи имена начинаться с верхнего или нижнего регистра G :

 выражение = fn.Lower(fn.Substr(Person.name, 1, 1)) == 'g'
для человека в Person.select().где (выражение):
    печать(человек.имя)

# отпечатки:
# бабушка Л.
 

Это только основы! Вы можете сделать ваши запросы настолько сложными, насколько вам нравится. Обратитесь к документации по запросам для получения дополнительной информации.

База данных

Мы закончили с нашей базой данных, давайте закроем соединение:

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

Чтобы узнать о настройке базы данных, см. документацию по базе данных, что дает множество примеров. Peewee также поддерживает настройку базы данных во время выполнения. а также настройку или изменение базы данных в любое время.

Работа с существующими базами данных

Если у вас уже есть база данных, вы можете автоматически генерировать модели peewee, используя pwiz, генератор моделей. Например, если у меня есть база данных postgresql с именем charles_blog , я мог бы запустить:

 python -m pwiz -e postgresql charles_blog > blog_models.пи
 

Что дальше?

Это краткое руководство. Если вы хотите посмотреть на полное веб-приложение, проверьте Приложение Пример.

База данных — документация peewee 3.14.9

Объект Peewee Database представляет собой соединение с базой данных. Создан экземпляр класса базы данных со всей необходимой информацией. для открытия соединения с базой данных, а затем может использоваться для:

  • Открытие и закрытие соединений.
  • Выполнение запросов.
  • Управление транзакциями (и точками сохранения).
  • Самоанализ таблиц, столбцов, индексов и ограничений.

Peewee поставляется с поддержкой SQLite, MySQL и Postgres. Каждый класс базы данных предоставляет некоторые основные, специфичные для базы данных параметры конфигурации.

 из импорта пиуи *

# База данных SQLite с использованием режима журнала WAL и кэшем 64 МБ.
sqlite_db = SqliteDatabase('/path/to/app.db', pragmas={
    'journal_mode': 'wal',
    'cache_size': -1024 * 64})

# Подключиться к базе данных MySQL по сети.mysql_db = MySQLDatabase('my_app', user='app', password='db_password',
                         хост='10.1.0.8', порт=3306)

# Подключиться к базе данных Postgres.
pg_db = PostgresqlDatabase('my_app', пользователь='postgres', пароль='секрет',
                           хост='10.1.0.9', порт=5432)
 

Peewee обеспечивает расширенную поддержку SQLite, Postgres и CockroachDB через модули расширения для конкретных баз данных. Чтобы использовать расширенную функциональность, импортируйте соответствующий модуль базы данных и используйте предоставленный класс базы данных:

 из театра.sqlite_ext импортировать базу данных SQLiteExt

# Используйте SQLite (зарегистрирует функцию REGEXP и установит тайм-аут занятости на 3 с).
db = SqliteExtDatabase('/path/to/app.db', regexp_function=True, timeout=3,
                       pragmas={'journal_mode': 'wal'})


из playhouse.postgres_ext импортировать PostgresqlExtDatabase

# Используйте Postgres (и зарегистрируйте расширение hstore).
db = PostgresqlExtDatabase('my_app', user='postgres', register_hstore=True)


из playhouse.cockroachdb импортировать CockroachDatabase

# Используйте базу данных тараканов.
db = CockroachDatabase('my_app', user='root', port=26257, host='10.1.0.8')

# Для соединений CockroachDB может потребоваться ряд параметров, которые могут
# в качестве альтернативы можно указать с помощью строки подключения.
db = CockroachDatabase('postgresql://...')
 

Для получения дополнительной информации о расширениях базы данных см.:

Инициализация базы данных

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

Например, в Postgresql часто требуется указывать хост , пользователя и пароль при создании подключения. это не стандарт Параметры Peewee Database , поэтому они будут переданы непосредственно обратно в psycopg2 при создании соединений:

 дб = PostgresqlDatabase(
    'database_name', # Требуется для Peewee.
    user='postgres', # Будет передано напрямую в psycopg2.
    password='secret', # То же самое.host='db.mysite.com') # То же самое.
 

Другой пример: драйвер pymysql принимает параметр charset . который не является стандартным параметром Peewee Database . Чтобы установить это значение, просто передайте кодировку вместе с другими вашими значениями:

 дб = MySQLDatabase('database_name', user='www-data', charset='utf8mb4')
 

Доступные параметры см. в документации драйвера базы данных:

Использование PostgreSQL

Для подключения к базе данных Postgresql мы будем использовать PostgresqlDatabase .Первым параметром всегда является имя базу данных, после чего можно указать произвольные параметры psycopg2.

 psql_db = PostgresqlDatabase('my_database', пользователь='postgres')

класс Базовая модель (модель):
    """Базовая модель, которая будет использовать нашу базу данных Postgresql"""
    Мета класса:
        база данных = psql_db

Пользователь класса (BaseModel):
    имя пользователя = CharField()
 

Расширения Playhouse для Peewee содержат модуль расширения Postgresql, который предоставляет множество специфичных для Postgres функций, таких как:

Если вы хотите использовать эти потрясающие функции, используйте PostgresqlExtDatabase из игрового дома .модуль postgres_ext :

 из playhouse.postgres_ext импортировать PostgresqlExtDatabase

psql_db = PostgresqlExtDatabase('my_database', пользователь='postgres')
 

Уровень изоляции

Начиная с Peewee 3.9.7, уровень изоляции может быть указан как инициализация. параметр, используя символические константы в psycopg2.extensions :

 из импорта psycopg2.extensions ISOLATION_LEVEL_SERIALIZABLE

db = PostgresqlDatabase('my_app', user='postgres', host='db-host',
                        isolation_level=ISOLATION_LEVEL_SERIALIZABLE)
 

Примечание

В более старых версиях можно вручную установить уровень изоляции на базовое соединение psycopg2.Это можно сделать одноразовым способом:

 дб = PostgresqlDatabase(...)
conn = db.connection() # возвращает текущее соединение.

из psycopg2.extensions импортировать ISOLATION_LEVEL_SERIALIZABLE
conn.set_isolation_level (ISOLATION_LEVEL_SERIALIZABLE)
 

Чтобы запускать это каждый раз при создании соединения, создайте подкласс и реализуйте хук _initialize_database() , который предназначен для этой цели:

 класс SerializedPostgresqlDatabase (PostgresqlDatabase):
    def _initialize_connection (я, соединение):
        конн.set_isolation_level (ISOLATION_LEVEL_SERIALIZABLE)
 

Использование CockroachDB

Подключение к CockroachDB (CRDB) с использованием базы данных CockroachDatabase класс, определенный в playhouse.cockroachdb :

 из playhouse.cockroachdb импортировать CockroachDatabase

db = CockroachDatabase('my_app', user='root', port=26257, host='localhost')
 

Если вы используете Тараканье облако, вы можете проще указать параметры подключения с помощью строки подключения:

 db = CockroachDatabase('postgresql://root:[email protected]:26257/defaultdb...')
 

Примечание

Для

CockroachDB требуется драйвер Python psycopg2 (postgres).

CRDB обеспечивает повторные попытки транзакции на стороне клиента, которые доступны с помощью специальный CockroachDatabase.run_transaction() вспомогательный метод. Этот метод принимает вызываемый объект, который отвечает за выполнение любой транзакции заявления, которые, возможно, потребуется повторить.

Простейший пример run_transaction() :

 по умолчанию create_user (электронная почта):
    # Вызываемый, который принимает один аргумент (экземпляр базы данных) и
    # который отвечает за выполнение транзакционного SQL.Обратный вызов защиты (db_ref):
        вернуть User.create(email=email)

    вернуть db.run_transaction (обратный вызов, max_attempts = 10)

huey = create_user('[email protected]')
 

Примечание

Исключение cockroachdb.ExceededMaxAttempts будет вызвано, если транзакция не может быть зафиксирована после заданного количества попыток. Если SQL неправильно сформирован, нарушает ограничение и т. д., тогда функция вызовите исключение для вызывающего абонента.

Для получения дополнительной информации см.:

Использование SQLite

Для подключения к базе данных SQLite мы будем использовать SqliteDatabase .То первый параметр — это имя файла, содержащего базу данных, или строка ':memory:' для создания базы данных в памяти. После имени файла базы данных вы можете указать список или прагмы или любые другие произвольные параметры sqlite3.

 sqlite_db = SqliteDatabase('my_app.db', pragmas={'journal_mode': 'wal'})

класс Базовая модель (модель):
    """Базовая модель, которая будет использовать нашу базу данных Sqlite."""
    Мета класса:
        база данных = sqlite_db

Пользователь класса (BaseModel):
    имя пользователя = Текстовое поле()
    # и т. д. и т. д.
 

Peewee включает в себя модуль расширения SQLite, который обеспечивает многие специфичные для SQLite функции, такие как полнотекстовый поиск, поддержка расширений json и многое, многое другое.Если бы ты хотите использовать эти замечательные функции, используйте SqliteExtDatabase из модуль playhouse.sqlite_ext :

 из playhouse.sqlite_ext импорт SqliteExtDatabase

sqlite_db = SqliteExtDatabase('my_app.db', pragmas={
    'journal_mode': 'wal', # WAL-режим.
    'cache_size': -64 * 1000, # кэш 64 МБ.
    'synchronous': 0}) # Разрешить ОС управлять синхронизацией.
 

Утверждения PRAGMA

SQLite позволяет настраивать ряд параметров во время выполнения через Операторы PRAGMA (документация SQLite).Эти операторы обычно запускаются при создании нового подключения к базе данных. Чтобы запустить одну или несколько инструкций PRAGMA для новых подключений, вы можете укажите их как словарь или список из двух кортежей, содержащих имя прагмы и значение:

 дб = SqliteDatabase('my_app.db', pragmas={
    'journal_mode': 'wal',
    'cache_size': 10000, # 10000 страниц или ~40 МБ
    'foreign_keys': 1, # Применить ограничения внешнего ключа
})
 

PRAGMA также можно настроить динамически с помощью метод pragma() или специальные свойства, представленные в объект SqliteDatabase :

 # Установите размер кеша на 64 МБ для *текущего подключения*.db.pragma('cache_size', -1024 * 64)

# То же, что и выше.
db.cache_size = -1024 * 64

# Прочитать значение нескольких прагм:
печать ('размер_кэша:', db.размер_кэша)
печать('внешние_ключи:', db.внешние_ключи)
print('journal_mode:', db.journal_mode)
печать('размер_страницы:', db.размер_страницы)

# Установить директиву external_keys для текущего соединения *И* для всех
# подключений, открытых впоследствии.
db.pragma («внешние_ключи», 1, постоянный = Истина)
 

Внимание

Прагмы, установленные с помощью метода pragma() , по умолчанию, не сохраняются после закрытия соединения.Чтобы настроить прагму для запускать при каждом открытии соединения, укажите Permanent=True .

Рекомендуемые настройки

Следующие настройки — это то, что я использую с SQLite для типичного веб-сайта. базу данных приложения.

прагма рекомендуемая настройка объяснение
журнал_режим стена разрешить сосуществование читателей и писателей
размер_кэша -1 * data_size_kb установить размер страничного кэша в КиБ, т.е.грамм. -32000 = 32 МБ
иностранные ключи 1 принудительное применение ограничений внешнего ключа
ignore_check_constraints 0 применять ограничения CHECK
синхронный 0 пусть ОС обрабатывает fsync (используйте с осторожностью)

Пример базы данных с использованием вышеуказанных параметров:

 дб = SqliteDatabase('my_app.db', pragmas={
    'journal_mode': 'wal',
    'cache_size': -1 * 64000, # 64 МБ
    'внешние_ключи': 1,
    'игнорировать_check_constraints': 0,
    'синхронный': 0})
 

Пользовательские функции

SQLite можно расширить с помощью определяемого пользователем кода Python.То Класс SqliteDatabase поддерживает три типа определяемых пользователем расширения:

  • Функции, которые принимают любое количество параметров и возвращают одно значение.
  • Агрегаты — которые агрегируют параметры из нескольких строк и возвращают единственное значение.
  • Сопоставления — описывают, как сортировать какое-либо значение.

Примечание

Для получения дополнительной поддержки расширений см. SqliteExtDatabase , который находится в модуле playhouse.sqlite_ext .

Пример определяемой пользователем функции:

 дб = SqliteDatabase('analytics.db')

из urllib.parse импортировать urlparse

@db.func('имя хоста')
имя хоста по определению (url):
    если URL-адрес не None:
        вернуть urlparse(url).netloc

# Вызвать эту функцию в нашем коде:
# Следующее находит наиболее распространенные имена хостов рефереров по количеству:
запрос = (просмотр страницы
         .select(fn.hostname(PageView.referrer), fn.COUNT(PageView.id))
         .group_by(fn.hostname(PageView.referrer))
         .order_by (фн.COUNT(PageView.id).desc()))
 

Пример пользовательского агрегата:

 из hashlib импорта md5

@db.aggregate('md5')
класс MD5Checksum (объект):
    защита __init__(сам):
        self.checksum = md5()

    шаг определения (я, значение):
        self.checksum.update(value.encode('utf-8'))

    деф финализировать (самостоятельно):
        вернуть self.checksum.hexdigest()

# Применение:
# Далее вычисляется совокупная контрольная сумма MD5 для поврежденных файлов
# разбивается на куски и сохраняется в базе данных.
запрос = (FileChunk
         .select(FileChunk.filename, fn.MD5(FileChunk.data))
         .group_by(FileChunk.имя файла)
         .order_by(FileChunk.имя файла, FileChunk.sequence))
 

Пример сопоставления:

 @db.collation('обратное')
определение collate_reverse (s1, s2):
    # Реверс без учета регистра.
    s1, s2 = s1.нижний(), s2.нижний()
    return (s1 < s2) - (s1 > s2) # Эквивалентно -cmp(s1, s2)

# Чтобы использовать эту сортировку для сортировки книг в обратном порядке...
Book.select().order_by(collate_reverse.collation(Book.заглавие))

# Или...
Book.select().order_by(Book.title.asc(collation='reverse'))
 

Пример определяемой пользователем функции табличного значения (см. TableFunction и table_function ) для дополнительных сведений:

 из playhouse.sqlite_ext импортировать TableFunction

БД = SqliteDatabase('my_app.db')

@db.table_function («серия»)
Серия классов (Табличная функция):
    столбцы = ['значение']
    params = ['старт', 'стоп', 'шаг']

    def initialize(self, start=0, stop=None, step=1):
        """
        Табличные функции объявляют метод initialize(), который
        вызывается с любыми аргументами, которые пользователь вызвал
        функция с."""
        self.start = self.current = начало
        self.stop = остановить или плавать ('Inf')
        сам.шаг = шаг

    итерация по определению (я, idx):
        """
        Iterate неоднократно вызывается механизмом базы данных SQLite.
        пока не будет прочитано требуемое количество строк **или**
        функция вызывает `StopIteration`, сигнализирующий об отсутствии строк
        доступны.
        """
        если self.current > self.stop:
            поднять StopIteration

        рет, self.current = self.текущий, self.current + self.step
        вернуться (рет.)

# Применение:
курсор = db.execute_sql('SELECT * FROM series(?,?,?)', (0, 5, 2))
для значения в курсоре:
    печать (значение)

# Печать:
# 0
№ 2
№ 4
 

Для получения дополнительной информации см.:

Установить режим блокировки для транзакции

транзакции SQLite можно открывать в трех разных режимах:

  • Отложенный ( по умолчанию ) — получает блокировку только при чтении или записи. выполнено. При первом чтении создается общая блокировка. и первая запись создает зарезервированную блокировку.Поскольку получение блокировки откладывается до тех пор, пока она действительно не понадобится, возможно, что другой поток или процесс может создать отдельную транзакцию и записать в базу данных после выполнения BEGIN в текущем потоке.
  • Немедленная - зарезервированная блокировка усваивается сразу. В этом режиме никакая другая база данных не может записывать данные в базу данных или открыть немедленную или эксклюзивную транзакцию. Другие процессы однако может продолжать чтение из базы данных.
  • Эксклюзив - открывает эксклюзивный замок который предотвращает доступ ко всем (кроме незафиксированных для чтения) соединениям базе данных, пока транзакция не будет завершена.

Пример указания режима блокировки:

 дБ = SqliteDatabase('app.db')

с db.atomic('ЭКСКЛЮЗИВ'):
    сделай что-нибудь()


@db.atomic('НЕМЕДЛЕННО')
определить некоторую_другую_функцию():
    # Эта функция включена в "НЕМЕДЛЕННУЮ" транзакцию.
    do_something_else()
 

Дополнительные сведения см. в документации по блокировке SQLite.Чтобы узнать больше о транзакциях в Peewee, см. Управление транзакциями документация.

APSW, расширенный драйвер SQLite

Peewee также поставляется с альтернативной базой данных SQLite, которая использует apsw, расширенный драйвер sqlite, расширенный драйвер Python SQLite. Дополнительную информацию об APSW можно получить на Сайт проекта APSW. APSW предоставляет специальные функции, такие как:

  • Виртуальные таблицы, виртуальные файловые системы, ввод-вывод больших двоичных объектов, резервное копирование и управление файлами.
  • Соединения могут быть разделены между потоками без какой-либо дополнительной блокировки.
  • Транзакции явно управляются вашим кодом.
  • Unicode обрабатывается правильно .
  • APSW быстрее, чем стандартный модуль библиотеки sqlite3.
  • Предоставляет практически весь SQLite C API вашему приложению Python.

Если вы хотите использовать APSW, используйте APSWDatabase из модуль apsw_ext :

 из playhouse.apsw_ext импортировать APSWDatabase

apsw_db = База данных APSW('my_app.db')
 

Использование MySQL

Для подключения к базе данных MySQL мы будем использовать MySQLDatabase .После имя базы данных, вы можете указать произвольные параметры подключения, которые будут передается обратно драйверу (либо MySQLdb, либо pymysql).

 mysql_db = MySQLDatabase('my_database')

класс Базовая модель (модель):
    """Базовая модель, которая будет использовать нашу базу данных MySQL"""
    Мета класса:
        база данных = mysql_db

Пользователь класса (BaseModel):
    имя пользователя = CharField()
    # и т. д. и т. д.
 

Ошибка 2006: сервер MySQL исчез

Эта конкретная ошибка может произойти, когда MySQL уничтожает бездействующее соединение с базой данных.Обычно это происходит с веб-приложениями, которые явно не управляют базой данных. соединения. Что происходит, когда ваше приложение запускается, открывается соединение с обрабатывать первый выполняемый запрос, и, поскольку это соединение никогда не закрытый, он остается открытым, ожидая новых запросов.

Чтобы исправить это, убедитесь, что вы явно подключаетесь к базе данных, когда необходимо выполнить запросы и закрыть соединение, когда вы закончите. В веб-приложение, это обычно означает, что вы откроете соединение, когда запрос приходит и закрывает соединение, когда вы возвращаете ответ.

См. раздел «Интеграция с платформой» для примеров настройки общих веб-фреймворки для управления соединениями с базами данных.

Подключение с использованием URL-адреса базы данных

URL-адрес базы данных модуля playhouse предоставляет помощника connect() функция, которая принимает URL-адрес базы данных и возвращает базу данных пример.

Пример кода:

 импорт ОС

из импорта пиуи *
из playhouse.db_url импортировать подключиться

# Подключиться к базе данных по URL-адресу, определенному в среде,
# вернуться к локальной базе данных Sqlite, если URL базы данных не указан.db = connect(os.environ.get('DATABASE') или 'sqlite:///default.db')

класс Базовая модель (модель):
    Мета класса:
        база данных = БД
 

Пример URL базы данных:

  • sqlite:///my_database.db создаст экземпляр SqliteDatabase для файла my_database.db в текущем каталоге.
  • sqlite:///:memory: создаст в памяти экземпляр SqliteDatabase .
  • postgresql://postgres:[email protected]:5432/my_database создаст экземпляр PostgresqlDatabase .Предоставляются имя пользователя и пароль, а также хост и порт для подключения.
  • mysql://user:[email protected]:port/my_db создаст экземпляр MySQLDatabase для локальной базы данных MySQL my_db .
  • Дополнительные примеры см. в документации по db_url.

Конфигурация базы данных во время выполнения

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

 database = PostgresqlDatabase(None) # Неинициализированная база данных.

класс SomeModel (модель):
    Мета класса:
        база данных = база данных
 

Если вы попытаетесь подключиться или выполнить какие-либо запросы, пока ваша база данных не инициализирована вы получите исключение:

 >>> база данных.connect()
Исключение: ошибка, база данных неправильно инициализирована перед открытием соединения.
 

Чтобы инициализировать базу данных, вызовите метод init() с параметром имя базы данных и любые дополнительные аргументы ключевого слова:

 имя_базы_данных = input('Как называется база данных?')
база данных.инициализация (имя_базы_данных, хост = 'localhost', пользователь = 'postgres')
 

Дополнительные возможности управления инициализацией базы данных см. в следующем разделе. Динамическое определение базы данных.

Динамическое определение базы данных

Для еще большего контроля над определением/инициализацией вашей базы данных вы можете используйте помощник DatabaseProxy . DatabaseProxy объектов действуют в качестве заполнителя, а затем во время выполнения вы можете заменить его на другой объект. В приведенном ниже примере мы заменим базу данных в зависимости от того, как приложение настроено:

 database_proxy = DatabaseProxy() # Создаем прокси для нашей базы данных.класс Базовая модель (модель):
    Мета класса:
        database = database_proxy # Использовать прокси для нашей БД.

Пользователь класса (BaseModel):
    имя пользователя = CharField()

# В зависимости от конфигурации используйте другую базу данных.
если app.config['DEBUG']:
    база данных = SqliteDatabase('local.db')
Элиф app.config['ТЕСТИРОВАНИЕ']:
    база данных = SqliteDatabase (': память:')
еще:
    база данных = PostgresqlDatabase('mega_production_db')

# Настройте наш прокси для использования базы данных, которую мы указали в config.
database_proxy.initialize (база данных)
 

Предупреждение

Используйте этот метод, только если ваш фактический драйвер базы данных изменяется во время выполнения.Для например, если ваши тесты и локальная среда разработки работают на SQLite, но ваш развернутое приложение использует PostgreSQL, вы можете использовать DatabaseProxy для менять двигатели во время работы.

Однако, если во время выполнения изменяются только значения соединений, например путь к файлу базы данных или хосту базы данных, вместо этого вы должны использовать База данных.init() . Дополнительные сведения см. в разделе Конфигурация базы данных во время выполнения. подробности.

Настройка базы данных во время выполнения

Мы рассмотрели три способа настройки баз данных с помощью Peewee:

 # Обычный способ:
db = SqliteDatabase('my_app.db', pragmas={'journal_mode': 'wal'})


# Укажите детали во время выполнения:
БД = SqliteDatabase (Нет)
...
db.init(db_filename, pragmas={'journal_mode': 'wal'})


# Или используйте заполнитель:
db = прокси базы данных ()
...
db.initialize (SqliteDatabase ('my_app.db', pragmas = {'journal_mode': 'wal'}))
 

Peewee также может установить или изменить базу данных для ваших классов моделей. Этот Этот метод используется набором тестов Peewee для привязки классов тестовых моделей к различные экземпляры базы данных при запуске тестов.

Существует два набора дополнительных методов:

В качестве примера объявим две модели без указания базы данных :

Пользователь класса
 (модель):
    имя пользователя = Текстовое поле()

Класс Твит(Модель):
    user = ForeignKeyField(Пользователь, обратная ссылка='твиты')
    содержимое = текстовое поле ()
    метка времени = поле метки времени ()
 

Привязать модели к базе данных во время выполнения:

 postgres_db = PostgresqlDatabase('my_app', user='postgres')
sqlite_db = SqliteDatabase('my_app.дБ')

# На данный момент модели User и Tweet НЕ привязаны к какой-либо базе данных.

# Привяжем их к базе данных Postgres:
postgres_db.bind([Пользователь, твит])

# Теперь временно привяжем их к базе данных sqlite:
с sqlite_db.bind_ctx([Пользователь, твит]):
    # Пользователь и твит теперь привязаны к базе данных sqlite.
    утверждать, что User._meta.database является sqlite_db

# Пользователь и твит снова привязаны к базе данных Postgres.
утверждать, что User._meta.database — это postgres_db
 

Модель .Методы bind() и Model.bind_ctx() работают одинаково для привязки данного класса модели:

 # Привязать модель пользователя к базе данных sqlite. По умолчанию Peewee также
# привязать любые модели, которые связаны с пользователем через внешний ключ.
User.bind(sqlite_db)

утверждать, что User._meta.database является sqlite_db
assert Tweet._meta.database is sqlite_db # Связанные модели также привязаны.

# Здесь мы временно привяжем *просто* модель пользователя к базе данных postgres.
с User.bind_ctx(postgres_db, bind_backrefs=False):
    утверждать пользователя._meta.database — это postgres_db
    assert Tweet._meta.database is sqlite_db # Не изменилось.

# И теперь пользователь снова привязан к sqlite_db.
утверждать, что User._meta.database является sqlite_db
 

Раздел этого документа, посвященный тестированию приложений Peewee, также содержит несколько примеров используя методы bind() .

Потокобезопасность и несколько баз данных

Если вы планируете изменять базу данных во время выполнения в многопоточном приложении, хранение базы данных модели в локальном потоке предотвратит состояние гонки.Этого можно добиться с помощью пользовательского класса метаданных модели (см. ThreadSafeDatabaseMetadata , включены в playhouse.shortcuts ):

 из импорта пиуи *
из playhouse.shortcuts импортировать ThreadSafeDatabaseMetadata

класс Базовая модель (модель):
    Мета класса:
        # Дайте указание peewee использовать нашу реализацию метаданных, ориентированную на многопотоковое исполнение.
        model_metadata_class = ThreadSafeDatabaseMetadata
 

Базу данных теперь можно безопасно подкачивать при работе в многопоточном режиме. среды с использованием знакомой базы данных .привязать() или Database.bind_ctx() методов.

Управление соединением

Чтобы открыть соединение с базой данных, используйте метод Database.connect() :

 >>> db = SqliteDatabase(':memory:') # База данных SQLite в памяти.
>>> db.connect()
Истинный
 

Если мы попытаемся вызвать connect() для уже открытой базы данных, мы получим Операционная ошибка :

 >>> db.connect()
Traceback (последний последний вызов):
  Файл "", строка 1, в 
  Файл "/home/charles/pypath/peewee.ру", строка 2390, в соединении
    поднять OperationalError('Соединение уже открыто.')
peewee.OperationalError: соединение уже открыто.
 

Чтобы предотвратить возникновение этого исключения, мы можем вызвать connect() с дополнительный аргумент, reuse_if_open :

 >>> db.close() # Закрыть соединение.
Истинный
>>> db.connect()
Истинный
>>> db.connect(reuse_if_open=True)
Ложь
 

Обратите внимание, что вызов connect() возвращает False , если база данных соединение уже было открыто.

Чтобы закрыть соединение, используйте метод Database.close() :

Вызов close() для уже закрытого соединения не приведет к исключение, но вернет False :

 >>> db.connect() # Открыть соединение.
Истинный
>>> db.close() # Закрыть соединение.
Истинный
>>> db.close() # Соединение уже закрыто, возвращает False.
Ложь
 

Вы можете проверить, закрыта ли база данных, используя База данных.is_closed() метод:

Использование автоподключения

Нет необходимости явно подключаться к базе данных перед использованием это если база данных инициализирована с autoconnect=True (по умолчанию). Явное управление соединениями считается лучшей практикой , поэтому вы можете рассмотреть возможность отключения поведения autoconnect .

Очень полезно четко указывать время жизни соединения. Если соединение не удается, например, исключение будет перехвачено, когда соединение открывается, а не какое-то произвольное время спустя, когда запрос выполняется.Кроме того, при использовании пула соединений необходимо вызвать connect() и close() чтобы обеспечить правильное повторное использование соединений.

Для лучшей гарантии правильности отключите autoconnect :

 дб = PostgresqlDatabase('my_app', user='postgres', autoconnect=False)
 

Безопасность резьбы

Peewee отслеживает состояние соединения, используя локальную память потока, что делает Объект Peewee Database безопасен для использования с несколькими потоками.Каждый поток будет иметь свое собственное соединение, и в результате любой данный поток будет иметь только одно открытое соединение в данный момент времени.

Менеджеры контекста

Сам объект базы данных может использоваться как менеджер контекста, который открывает соединение на время обернутого блока кода. Кроме того, транзакция открывается в начале обернутого блока и фиксируется до соединение закрывается (если не произойдет ошибка, в этом случае транзакция откатывается).

 >>> db.is_closed()
Истинный
>>> с БД:
... print(db.is_closed()) # БД открыта внутри контекстного менеджера.
...
Ложь
>>> db.is_closed() # БД закрыта.
Истинный
 

Если вы хотите управлять транзакциями отдельно, вы можете использовать Менеджер контекста Database.connection_context() .

 >>> с db.connection_context():
... # соединение с базой данных открыто.
...     проходить
...
>>> db.is_closed() # соединение с базой данных закрыто.
Истинный
 

Метод connection_context() также можно использовать в качестве декоратора:

 @дб.connection_context()
защита prepare_database():
    # Соединение с БД будет управляться декоратором, который открывает
    # соединение, вызывает функцию и закрывается при возвращении.
    db.create_tables(MODELS) # Создать схему.
    load_fixture_data (дБ)
 

Объект соединения DB-API

Чтобы получить ссылку на базовое соединение DB-API 2.0, используйте Метод Database.connection() . Этот метод вернет текущий открытый объект подключения, если он существует, в противном случае он откроет новый связь.

 >>> db.connection()
<объект sqlite3.Connection по адресу 0x7f94e9362f10>
 

Пул соединений

Пул соединений обеспечивается модулем пула, включенным в библиотека расширений playhouse. Пул поддерживает:

  • Тайм-аут, по истечении которого соединения будут перезапущены.
  • Верхняя граница количества открытых соединений.
 из импорта playhouse.pool PooledPostgresqlExtDatabase

db = PooledPostgresqlExtDatabase(
    'моя_база данных',
    макс_подключения = 8,
    stale_timeout=300,
    пользователь='postgres')

класс Базовая модель (модель):
    Мета класса:
        база данных = БД
 

Доступны следующие объединенные классы баз данных:

Подробное обсуждение пула соединений peewee см. в разделе Пул соединений. раздел документации игрового дома.

Тестирование приложений Peewee

При написании тестов для приложения, использующего Peewee, может быть желательно использовать специальную базу данных для тестов. Другой распространенной практикой является запуск тестов против чистой базы данных, что означает, что таблицы пусты в начале каждый тест.

Чтобы связать ваши модели с базой данных во время выполнения, вы можете использовать следующее методы:

  • Database.bind_ctx() , который возвращает диспетчер контекста, который будет выполнять привязку данные модели в экземпляр базы данных на время завернутого блокировать.
  • Model.bind_ctx() , который также возвращает диспетчер контекста, привязывает модель (и, возможно, ее зависимости) к данной базе данных для продолжительность обернутого блока.
  • Database.bind() — одноразовая операция, связывающая модели (и, возможно, его зависимости) к данной базе данных.
  • Model.bind() , одноразовая операция, которая связывает модель (и, возможно, его зависимости) к данной базе данных.

В зависимости от вашего варианта использования один из этих вариантов может иметь больше смысла. Для примеры ниже, я буду использовать Model.bind() .

Пример настройки тестового примера:

 #tests.py
импортировать модульный тест
из my_app.models импортировать EventLog, Relationship, Tweet, User

МОДЕЛИ = [Пользователь, Твит, Журнал событий, Отношения]

# использовать SQLite в памяти для тестов.
test_db = SqliteDatabase (': память:')

класс BaseTestCase (unittest.TestCase):
    деф setUp(я):
        # Привязать классы моделей к тесту db.Так как у нас есть полный список
        # все модели, нам не нужно рекурсивно связывать зависимости.
        test_db.bind(МОДЕЛИ, bind_refs=False, bind_backrefs=False)

        test_db.connect()
        test_db.create_tables (МОДЕЛИ)

    деф слеза вниз (сам):
        # Строго не обязательно, так как базы данных SQLite в памяти работают только в режиме реального времени.
        # на время подключения, а на следующем шаге закрываем
        # соединение... но, тем не менее, хорошая практика.
        test_db.drop_tables (МОДЕЛИ)

        # Закрыть соединение с БД.test_db.close()

        # Если бы мы захотели, мы могли бы повторно привязать модели к их первоначальным
        # база данных здесь. Но для тестов это, наверное, не нужно.
 

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

Если вы хотите увидеть еще несколько примеров того, как запускать тесты с помощью Peewee, проверьте из собственного набора тестов Peewee.

Асинхронный с Gevent

gevent рекомендуется для асинхронного ввода-вывода с Postgresql или MySQL.Причины, по которым я предпочитаю gevent:

  • Нет необходимости в специальных повторных реализациях с учетом циклов всего . Сторонним библиотекам, использующим asyncio, обычно приходится заново реализовывать слои и слоев кода, а также повторная реализация самих протоколов.
  • Gevent позволяет вам написать ваше приложение в обычном, чистом, идиоматичном Питон. Не нужно захламлять каждую строку «async», «await» и прочим шумом. Никаких обратных вызовов, фьючерсов, задач, обещаний. Никакого хлама.
  • Gevent работает как с Python 2 , так и с Python 3.
  • Gevent — это Pythonic . Асинкио — непитоновская мерзость.

Помимо сокета с обезьяньим патчем, никаких специальных шагов не требуется, если вы используете MySQL с чистым драйвером Python, таким как pymysql или используете mysql-коннектор в режиме чистого питона. Драйверы MySQL, написанные на C, потребуют специальных конфигурации, которая выходит за рамки этого документа.

Для Postgres и psycopg2, который является C расширение, вы можете использовать следующий фрагмент кода для регистрации обработчиков событий, которые сделает ваше соединение асинхронным:

 от гевента.импорт сокетов wait_read, wait_write
из расширений импорта psycopg2

# Вызовите эту функцию после исправления сокета (и т.д.).
защита patch_psycopg2():
    extensions.set_wait_callback(_psycopg2_gevent_callback)

def _psycopg2_gevent_callback (подключение, тайм-аут = нет):
    пока верно:
        состояние = соединение.опрос()
        если состояние == extensions.POLL_OK:
            перерыв
        elif state == extensions.POLL_READ:
            wait_read(conn.fileno(), timeout=timeout)
        elif state == extensions.POLL_WRITE:
            ожидание_записи (соед.fileno(), тайм-аут=тайм-аут)
        еще:
            поднять ValueError («опрос () вернул неожиданный результат»)
 

SQLite , поскольку он встроен в само приложение Python, не выполнять любые операции с сокетами, которые могут быть кандидатами на неблокировку. Асинхронный никак не влияет так или иначе на базы данных SQLite.

Интеграция с инфраструктурой

Для веб-приложений обычно открывается соединение, когда запрос получено, и закрыть соединение после доставки ответа.В этом В разделе я опишу, как добавить хуки в ваше веб-приложение, чтобы убедиться, что база данных соединение обрабатывается правильно.

Эти шаги гарантируют, что независимо от того, используете ли вы простой SQLite базу данных или пул из нескольких соединений Postgres, peewee будет обрабатывать соединения правильно.

Примечание

Приложения, которые получают много трафика, могут выиграть от использования пул подключений для снижения затрат на настройку и разрывая соединение по каждому запросу.

Колба

Flask и peewee — отличная комбинация, которую я использую для проектов любого размера. Колба предоставляет два хука, которые мы будем использовать для открытия и закрытия нашего соединения с БД. Хорошо открыть соединение, когда получен запрос, а затем закрыть его, когда ответ возвращается.

 из фляги импорта Фляга
из импорта пиуи *

база данных = SqliteDatabase('my_app.db')
приложение = фляга (__имя__)

# Этот хук гарантирует, что соединение открыто для обработки любых запросов
# генерируется по запросу[email protected]_request
защита _db_connect():
    база данных.connect()

# Этот хук гарантирует, что соединение будет закрыто, когда мы закончим
# обработка запроса.
@app.teardown_request
деф _db_close (отл):
    если не база данных.is_closed():
        база данных.close()
 

Джанго

Хотя использование peewee с Django встречается реже, на самом деле это очень просто использовать два. Чтобы управлять соединениями с базой данных peewee с помощью Django, Самый простой способ, на мой взгляд, - добавить промежуточное программное обеспечение в ваше приложение.Промежуточное ПО должен быть самым первым в списке промежуточных программ, чтобы гарантировать, что он запускается первым когда запрос обрабатывается, и последний, когда возвращается ответ.

Если у вас есть проект django с именем my_blog и ваша база данных peewee определенный в модуле my_blog.db , вы можете добавить следующее промежуточное ПО класс:

 # промежуточное программное обеспечение.py
from my_blog.db import database # Импорт экземпляра базы данных peewee.


Def PeeweeConnectionMiddleware (get_response):
    промежуточное ПО (запрос):
        база данных.соединять()
        пытаться:
            ответ = получить_ответ (запрос)
        наконец:
            если не база данных.is_closed():
                база данных.close()
        вернуть ответ
    вернуть промежуточное ПО


# Старое промежуточное ПО Django < 1.10.
класс PeeweeConnectionMiddleware (объект):
    def process_request (я, запрос):
        база данных.connect()

    def process_response (я, запрос, ответ):
        если не база данных.is_closed():
            база данных.close()
        вернуть ответ
 

Чтобы обеспечить выполнение этого промежуточного программного обеспечения, добавьте его в свой модуль настроек :

 # настройки.пи
MIDDLEWARE_CLASSES = (
    # Наше промежуточное ПО появляется первым в списке.
    'my_blog.middleware.PeeweeConnectionMiddleware',

    # Это промежуточное программное обеспечение Django 1.7 по умолчанию. Ваш может отличаться,
    # но важно то, что наше промежуточное ПО Peewee стоит на первом месте.
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    Джанго.contrib.messages.middleware.MessageMiddleware',
)

# ... другие настройки Django ...
 

Бутылка

Я сам не пользовался бутылкой, но, глядя на документацию, я думаю, что следующий код должен обеспечить правильное управление подключениями к базе данных:

 # app.py
из хука импорта бутылки #, маршрут и т. д. и т. д.
из импорта пиуи *

db = SqliteDatabase('my-bottle-app.db')

@hook('before_request')
защита _connect_db():
    db.connect()

@hook('после_запроса')
защита _close_db():
    если не дб.закрыто():
        db.close()

# Остальная часть вашего приложения для бутылок находится здесь.
 

Web.py

См. документацию по процессоры приложений.

 дб = SqliteDatabase('my_webpy_app.db')

def connection_processor (обработчик):
    db.connect()
    пытаться:
        обработчик возврата()
    наконец:
        если не db.is_closed():
            db.close()

app.add_processor(connection_processor)
 

Торнадо

Похоже, что класс Tornado RequestHandler реализует два хука, которые могут использоваться для открытия и закрытия соединений при обработке запроса.

 из tornado.web import RequestHandler

БД = SqliteDatabase('my_db.db')

класс PeeweeRequestHandler (RequestHandler):
    деф подготовить (самостоятельно):
        db.connect()
        вернуть super(PeeweeRequestHandler, self).prepare()

    защита on_finish (я):
        если не db.is_closed():
            db.close()
        вернуть super(PeeweeRequestHandler, self).on_finish()
 

В вашем приложении вместо расширения стандартного RequestHandler теперь вы можете расширить PeeweeRequestHandler .

Обратите внимание, что это не относится к асинхронному использованию peewee с Tornado. или другой цикл событий.

Wheezy.web

Код обработки соединения можно разместить в промежуточном программном обеспечении.

 def peewee_middleware (запрос, следующий):
    db.connect()
    пытаться:
        ответ = следующий (запрос)
    наконец:
        если не db.is_closed():
            db.close()
    вернуть ответ

приложение = WSGIApplication (промежуточное ПО = [
    лямбда х: peewee_middleware,
    # ... другие промежуточные программы ...
])
 

Спасибо пользователю GitHub @tuukkamustonen за отправку этого кода.

Сокол

Код обработки соединения можно поместить в промежуточный компонент.

 импортный сокол
из импорта пиуи *

база данных = SqliteDatabase('my_app.db')

класс PeeweeConnectionMiddleware (объект):
    def process_request (я, запрос, соотв.):
        база данных.connect()

    def process_response(self, req, resp, resource, req_succeeded):
        если не база данных.закрыто():
            база данных.close()

приложение = falcon.API ​​(промежуточное ПО = [
    Промежуточное ПО PeeweeConnection(),
    # ... другие промежуточные программы ...
])
 

Пирамида

Настройте фабрику запросов, которая обрабатывает время жизни соединения с базой данных следующим образом:

 из пирамиды.запрос на импорт

db = SqliteDatabase('pyramidapp.db')

класс MyRequest (запрос):
    def __init__(я, *args, **kwargs):
        super().__init__(*args, **kwargs)
        db.connect()
        себя.add_finished_callback(self.finish)

    деф финиш(сам, запрос):
        если не db.is_closed():
            db.close()
 

В вашем приложении main() убедитесь, что MyRequest используется как request_factory :

 по умолчанию main(global_settings, **settings):
    config = Конфигуратор(настройки=настройки, ...)
    config.set_request_factory(МойЗапрос)
 

CherryPy

См. Шаблон публикации/подписки.

 определение _db_connect():
    дБ.соединять()

защита _db_close():
    если не db.is_closed():
        db.close()

cherrypy.engine.subscribe('before_request', _db_connect)
cherrypy.engine.subscribe('after_request', _db_close)
 

Саник

В Sanic код обработки соединения можно поместить в запрос и ПО промежуточного слоя ответа Sanic Middleware.

 # app.py
@app.middleware('запрос')
асинхронный запрос handle_request (запрос):
    db.connect()

@app.middleware('ответ')
async def handle_response (запрос, ответ):
    если не дб.закрыто():
        db.close()
 

FastAPI

Подобно Flask, FastAPI предоставляет два хука на основе событий, которые мы будем использовать для открытия и закрыть наше соединение с БД. Откроем соединение при получении запроса, затем закройте его, когда ответ будет возвращен.

 из fastapi импортировать FastAPI
из импорта пиуи *

БД = SqliteDatabase('my_app.db')
приложение = FastAPI()

# Этот хук гарантирует, что соединение открыто для обработки любых запросов
# генерируется по запросу.
@app.on_event("запуск")
определение запуска():
    дБ.соединять()


# Этот хук гарантирует, что соединение будет закрыто, когда мы закончим
# обработка запроса.
@app.on_event("выключение")
деф отключение():
    если не db.is_closed():
        db.close()
 

Другие каркасы

Не видите здесь свой фреймворк? Пожалуйста, откройте тикет GitHub, и я посмотрю, как добавить раздел или, что еще лучше, отправьте запрос на получение документации.

Выполнение запросов

SQL-запросы обычно выполняются путем вызова execute() для запроса. созданный с использованием API-интерфейсов построителя запросов (или путем простого повторения запроса объекта в случае запроса Select ).Для случаев, когда вы хотите выполнить SQL напрямую, вы можете использовать метод Database.execute_sql() .

 дб = SqliteDatabase('my_app.db')
db.connect()

# Пример выполнения простого запроса и игнорирования результатов.
db.execute_sql("ПОДКЛЮЧИТЬ БАЗУ ДАННЫХ ':memory:' AS cache;")

# Пример перебора результатов запроса с помощью курсора.
курсор = db.execute_sql('SELECT * FROM users WHERE status = ?', (ACTIVE,))
для строки в cursor.fetchall():
    # Сделайте что-нибудь со строкой, которая представляет собой кортеж, содержащий данные столбца.проходить
 

Управление транзакциями

Peewee предоставляет несколько интерфейсов для работы с транзакциями. Большинство общим является метод Database.atomic() , который также поддерживает вложенные транзакции. atomic() блоков будут запущены в транзакции или точки сохранения, в зависимости от уровня вложенности.

Если в обернутом блоке возникает исключение, текущая транзакция/точка сохранения будет откатываться. В противном случае операторы будут зафиксированы в конце завернутый блок.

Примечание

Находясь внутри блока, обернутого контекстом atomic() менеджер, вы можете явно откатить или зафиксировать в любой момент, вызвав Transaction.rollback() или Transaction.commit() . Когда ты сделайте это внутри обернутого блока кода, будет запущена новая транзакция автоматически.

 с db.atomic() в качестве транзакции: # Открывает новую транзакцию.
    пытаться:
        save_some_objects()
    кроме ErrorSavingData:
        # Так как этот блок кода заключен в "atomic",
        # новая транзакция начнется автоматически после звонка
        # для отката().транзакция.откат()
        error_saving = Истина

    create_report (error_saving = error_saving)
    # Примечание: нет необходимости вызывать commit. Поскольку это знаменует собой конец
    # обернутый блок кода, менеджер контекста `atomic`
    # автоматически вызываем коммит для нас.
 

Примечание

atomic() может использоваться как менеджер контекста или декоратор .

Диспетчер контекста

Использование atomic в качестве менеджера контекста:

 дб = SqliteDatabase (': память:')

с дб.атомный () как txn:
    # Это самый внешний уровень, поэтому этот блок соответствует
    # транзакция.
    User.create (имя пользователя = 'Чарли')

    с db.atomic() как вложенный_txn:
        # Этот блок соответствует точке сохранения.
        User.create (имя пользователя = 'хуи')

        # Это приведет к откату предыдущего запроса create().
        вложенный_txn.rollback ()

    User.create (имя пользователя = 'Микки')

# Когда блок заканчивается, транзакция фиксируется (при условии отсутствия ошибок).
# имеет место). В этот момент будет два пользователя, «charlie» и «mickey».

Вы можете использовать метод atomic для выполнения операций получения или создания как хорошо:

 попробуйте:
    с db.atomic():
        пользователь = User.create (имя пользователя = имя пользователя)
    вернуть "Успех"
кроме peewee.IntegrityError:
    return 'Ошибка: %s уже используется.' % имя пользователя
 

Декоратор

Использование atomic в качестве декоратора:

 @db.atomic()
def create_user (имя пользователя):
    # Этот оператор будет выполняться в транзакции. Если звонящий уже
    # выполняется в блоке `atomic`, вместо этого будет использоваться точка сохранения.вернуть User.create (имя пользователя = имя пользователя)

create_user («Чарли»)
 

Вложенные транзакции

atomic() обеспечивает прозрачную вложенность транзакций. Когда используя atomic() , самый внешний вызов будет заключен в транзакция, и любые вложенные вызовы будут использовать точки сохранения.

 с db.atomic() в качестве txn:
    выполнить_операцию()

    с db.atomic() как вложенный_txn:
        выполнить_другую_операцию()
 

Peewee поддерживает вложенные транзакции за счет использования точек сохранения (подробнее информацию см. в savepoint() ).

Явная транзакция

Если вы хотите явно запустить код в транзакции, вы можете использовать транзакция() . Как atomic() , transaction() можно использовать как менеджер контекста или как декоратор.

Если в обернутом блоке возникает исключение, транзакция будет отменена. В противном случае операторы будут зафиксированы в конце обернутого блока.

 дб = SqliteDatabase (': память:')

с db.transaction() как txn:
    # Удалить пользователя и связанные с ним твиты.user.delete_instance (рекурсивный = Истина)
 

Транзакции могут быть явно зафиксированы или отменены внутри обернутого блокировать. Когда это произойдет, будет запущена новая транзакция.

 с db.transaction() как txn:
    User.create (имя пользователя = 'Микки')
    txn.commit() # Изменения сохраняются и начинается новая транзакция.
    User.create (имя пользователя = 'хуи')

    # Откатиться. "хьюи" не спасется, но так как "микки" уже был
    # зафиксировано, эта строка останется в базе данных.txn.rollback()

с db.transaction() как txn:
    User.create(имя пользователя='бакенбарды')
    # Откат изменений, который удаляет "усы".
    txn.rollback()

    # Создадим новую строку для "mr. усики", которая будет неявно зафиксирована
    # в конце блока with.
    User.create(username='мистер бакенбарды')
 

Примечание

Если вы попытаетесь вложить транзакции с помощью peewee, используя transaction() менеджер контекста, только самый внешний транзакция будет использована. Однако, если исключение возникает во вложенном блоке, это может привести к непредсказуемому поведению, поэтому настоятельно рекомендуется вы используете atomic() .

Явные точки сохранения

Точно так же, как вы можете явно создавать транзакции, вы также можете явно создавать точки сохранения с помощью метода savepoint() . Точки сохранения должны происходят внутри транзакции, но могут быть вложены сколь угодно глубоко.

 с db.transaction() как txn:
    с db.savepoint() как sp:
        User.create (имя пользователя = 'Микки')

    с db.savepoint() как sp2:
        User.create(имя пользователя='zaizee')
        sp2.rollback() # "zaizee" не будет сохранен, а "mickey" будет.

Предупреждение

Если вы вручную фиксируете или откатываете точку сохранения, новая точка сохранения будет не автоматически создаваться. Это отличается от поведения транзакция , которая автоматически откроет новую транзакцию после ручной фиксации/отката.

Режим автоматической фиксации

По умолчанию Peewee работает в режиме автоматической фиксации , так что любые операторы выполняемые вне транзакции, выполняются в собственной транзакции. Сгруппировать несколько операторов в транзакцию, Peewee предоставляет atomic() контекстный менеджер/декоратор.Это должно охватывать все случаев использования, но в маловероятном случае вы захотите временно отключить Peewee. полностью управлять транзакциями, вы можете использовать Database.manual_commit() менеджер контекста/декоратор.

Вот как вы можете эмулировать поведение транзакция() диспетчер контекста:

 с db.manual_commit():
    db.begin() # Необходимо явно начать транзакцию.
    пытаться:
        user.delete_instance (рекурсивный = Истина)
    Кроме:
        db.rollback() # Откат! Произошла ошибка.поднимать
    еще:
        пытаться:
            db.commit() # Зафиксировать изменения.
        Кроме:
            db.rollback()
            поднимать
 

Еще раз — я не думаю, что это кому-то понадобится, но на всякий случай оно здесь.

Ошибки базы данных

Спецификация Python DB-API 2.0 описывает несколько типов исключений. Поскольку большинство драйверов баз данных имеют свои собственные реализации этих исключений, Peewee упрощает работу, предоставляя собственные оболочки для любых классов исключений, специфичных для реализации.Таким образом, вам не нужно беспокоиться об импорте каких-либо специальных классов исключений, вы можете просто использовать классы из peewee:

.
  • Ошибка базы данных
  • Ошибка данных
  • Ошибка целостности
  • Ошибка интерфейса
  • Внутренняя ошибка
  • Неподдерживаемая ошибка
  • Операционная ошибка
  • Ошибка программирования

Примечание

Все эти классы ошибок расширяют PeeweeException .

Регистрация запросов

Все запросы регистрируются в пространстве имен peewee с использованием стандартной библиотеки. Модуль регистрации . Запросы регистрируются с использованием уровня DEBUG . Если ты заинтересованы в том, чтобы что-то делать с запросами, вы можете просто зарегистрировать обработчик.

 # Вывести все запросы в stderr.
журнал импорта
logger = logging.getLogger('пиуи')
logger.addHandler(регистрация.StreamHandler())
logger.setLevel(регистрация.DEBUG)
 

Добавление нового драйвера базы данных

Peewee поставляется со встроенной поддержкой Postgres, MySQL и SQLite.Эти базы данных очень популярны и охватывают диапазон от быстрых встраиваемых баз данных до тяжелые серверы, подходящие для крупномасштабных развертываний. Что, как говорится, есть масса крутых баз данных и добавление поддержки для ваших выбор базы данных должен быть очень простым, при условии, что драйвер поддерживает Спецификация DB-API 2.0.

Спецификация DB-API 2.0 должна быть вам знакома, если вы использовали стандартную библиотека драйверов sqlite3, psycopg2 и т.п. В настоящее время Peewee полагается на горстка деталей:

  • Соединение.зафиксировать
  • Соединение.выполнить
  • Соединение.откат
  • Описание курсора
  • Cursor.fetchone

Эти методы обычно заключены в абстракции более высокого уровня и доступны по базе данных , так что даже если ваш драйвер не делает именно это Вы все еще можете получить много пробега от крошки. Примером является apsw. sqlite в модуле «playhouse».

Прежде всего, необходимо предоставить подкласс База данных , которая откроет связь.

 из базы данных импорта peewee
import foodb # Наш вымышленный драйвер DB-API 2.0.


класс FooDatabase (база данных):
    def _connect(я, база данных, **kwargs):
        вернуть foodb.connect(база данных, **kwargs)
 

База данных предоставляет высокоуровневый API и отвечает за выполнение запросов, создание таблиц и индексов, а также самоанализ базы данных чтобы получить списки таблиц. Приведенная выше реализация является абсолютным минимумом необходимо, хотя некоторые функции не будут работать — для достижения наилучших результатов вам потребуется дополнительно добавить метод извлечения списка таблиц и индексов для таблицу из базы данных.Мы представим, что FooDB очень похож на MySQL и имеет специальные операторы «SHOW»:

 класс FooDatabase (база данных):
    деф _connect(я):
        вернуть foodb.connect(self.database, **self.connect_params)

    определение get_tables (я):
        res = self.execute('ПОКАЖИТЕ ТАБЛИЦЫ;')
        вернуть [r[0] для r в res.fetchall()]
 

Другие вещи, которые обрабатывает база данных, которые здесь не рассматриваются, включают:

  • last_insert_id() и rows_affected()
  • param и цитируют , которые сообщают Код, генерирующий SQL, как добавить заполнители параметров и имена сущностей в кавычках.
  • field_types для сопоставления типов данных, таких как INT или TEXT, с их имена типов, зависящие от поставщика.
  • операции для сопоставления операций, таких как «LIKE/ILIKE», с их эквивалентом в базе данных

См. справочник по API Database или исходный код. для деталей.

Примечание

Если ваш драйвер соответствует спецификации DB-API 2.0, не должно быть много работа, необходимая для того, чтобы встать и работать.

Наша новая база данных может использоваться так же, как и любой другой подкласс базы данных:

 из импорта пиуи *
из foodb_ext импортировать FooDatabase

db = FooDatabase('my_database', пользователь='foo', пароль='секрет')

класс Базовая модель (модель):
    Мета класса:
        база данных = БД

Блог класса (BaseModel):
    название = CharField ()
    содержимое = Текстовое поле()
    pub_date = DateTimeField ()
 

Быстрый старт — пиуи 3.14.9 документация

В этом документе представлен краткий высокоуровневый обзор основного Особенности. Это руководство охватывает:

Примечание

Если вы хотите что-то более мясистое, есть подробное руководство по создание веб-приложения в стиле «твиттера» с использованием peewee и Каркас фляги. В папке проектов примеров/ вы можете найти больше автономные примеры Peewee, такие как приложение для блога.

Я настоятельно рекомендую открыть сеанс интерактивной оболочки и запустить код.Таким образом, вы можете почувствовать, как вводить запросы.

Определение модели

Классы моделей, поля и экземпляры моделей сопоставляются с понятиями базы данных:

Объект Соответствует…
Модельный класс Таблица базы данных
Экземпляр поля Столбец на стол
Экземпляр модели Строка в таблице базы данных

При запуске проекта с peewee, как правило, лучше всего начать с вашего модель данных путем определения одного или нескольких классов модели :

 из импорта пиуи *

db = SqliteDatabase('люди.дБ')

класс Человек(Модель):
    имя = CharField()
    день рождения = DateField ()

    Мета класса:
        database = db # Эта модель использует базу данных "people.db".
 

Примечание

Peewee автоматически выведет имя таблицы базы данных из имени класс. Вы можете переопределить имя по умолчанию, указав table_name атрибут во внутреннем классе «Мета» (наряду с атрибутом базы данных ). Чтобы узнать больше о том, как Peewee генерирует имена таблиц, см. обратитесь к разделу Имена таблиц.

Также обратите внимание, что мы назвали нашу модель Person вместо People . Это соглашение, которому вы должны следовать, даже если таблица будет содержать несколько человек, мы всегда называем класс в форме единственного числа.

Существует множество типов полей, подходящих для хранения различных типы данных. Peewee обрабатывает преобразование между значениями pythonic и теми, используемые базой данных, поэтому вы можете использовать типы Python в своем коде, не волноваться.

Все становится интереснее, когда мы устанавливаем отношения между моделями, используя отношения внешнего ключа.Это просто с peewee:

 класс домашних животных (модель):
    владелец = ForeignKeyField(Person, backref='домашние животные')
    имя = CharField()
    animal_type = CharField()

    Мета класса:
        database = db # эта модель использует базу данных "people.db"
 

Теперь, когда у нас есть модели, давайте подключимся к базе данных. Хотя это не необходимо открыть соединение явно, это хорошая практика, так как немедленно выявить любые ошибки с подключением к базе данных, в отличие от некоторых произвольное время спустя, когда выполняется первый запрос.Также хорошо закрыть соединение, когда вы закончите — например, веб-приложение может открыть соединение, когда он получает запрос, и закрывает соединение, когда он отправляет ответ.

Начнем с создания таблиц в базе данных, в которых будут храниться наши данные. Это создаст таблицы с соответствующими столбцами, индексами, последовательностями, и ограничения внешнего ключа:

 db.create_tables([Человек, Домашнее животное])
 

Сохранение данных

Давайте начнем с заполнения базы данных некоторыми людьми.Мы будем использовать save() и create() методов для добавления и обновления рекорды людей.

 с даты импорта даты и времени
uncle_bob = Человек (имя = 'Боб', день рождения = дата (1960, 1, 15))
uncle_bob.save() # боб теперь хранится в базе данных
# Возвращает: 1
 

Примечание

При вызове save() количество измененных строк равно вернулся.

Вы также можете добавить человека, вызвав метод create() , который возвращает экземпляр модели:

 бабушка = Человек.создать (имя = 'Бабушка', день рождения = дата (1935, 3, 1))
herb = Person.create(name='Herb', Birthday=date(1950, 5, 5))
 

Чтобы обновить строку, измените экземпляр модели и вызовите save() для сохранить изменения. Здесь мы изменим имя бабушки, а затем сохраним изменений в базе:

 grandma.name = 'Бабушка Л.'
grandma.save() # Обновить имя бабушки в базе данных.
# Возвращает: 1
 

Теперь мы сохранили в базе 3 человека. Давайте подарим им домашних животных.Бабушка не любит животных в доме, поэтому у нее их не будет, но Херб — животное любовник:

 bob_kitty = Pet.create(владелец=uncle_bob, name='Kitty', animal_type='cat')
herb_fido = Pet.create (владелец = трава, имя = 'Фидо', animal_type = 'собака')
herb_mittens = Pet.create (владелец = трава, имя = 'Варежки', animal_type = 'кошка')
herb_mittens_jr = Pet.create(owner=herb, name='Варежки-младший', animal_type='cat')
 

После долгой полноценной жизни Варежки заболевают и умирают. Нам нужно убрать его из база данных:

 травяные_рукавицы.delete_instance() # у него была отличная жизнь
# Возвращает: 1
 

Примечание

Возвращаемое значение delete_instance() — это количество строк удалены из базы данных.

Дядя Боб решает, что в доме Херба умирает слишком много животных, поэтому он принимает Фидо:

 herb_fido.owner = дядя_боб
herb_fido.save()
 

Получение данных

Настоящая сила нашей базы данных в том, как она позволяет нам извлекать данные через запросов .Реляционные базы данных отлично подходят для создания запросы.

Получение отдельных записей

Давайте извлечем запись бабушки из базы данных. Чтобы получить одну запись из базу данных, используйте Select.get() :

 бабушка = Person.select().where(Person.name == 'Бабушка Л.').get()
 

Мы также можем использовать эквивалентное сокращение Model.get() :

 бабушка = Person.get(Person.name == 'Бабушка Л.')
 

Списки записей

Давайте перечислим всех людей в базе данных:

 для человека в лицо.Выбрать():
    печать(человек.имя)

# отпечатки:
# Боб
# бабушка Л.
# Трава
 

Давайте перечислим всех кошек и имя их владельца:

 запрос = Pet.select().where(Pet.animal_type == 'кошка')
для питомца в запросе:
    print(pet.name, pet.owner.name)

# отпечатки:
# Китти Боб
# Варежки Jr Herb
 

Внимание

Существует большая проблема с предыдущим запросом: поскольку мы обращаемся pet.owner.name и мы не выбрали это отношение в нашем исходном запрос, peewee должен будет выполнить дополнительный запрос, чтобы получить хозяин питомца.Это поведение называется N+1, и оно вообще следует избегать.

Подробное руководство по работе со связями и соединениями см. Документация по отношениям и соединениям.

Мы можем избежать дополнительных запросов, выбрав оба Pet и Person и добавив присоединиться к .

 запрос = (домашнее животное
         .select(домашнее животное, человек)
         .присоединиться(Человек)
         .где(Pet.animal_type == 'кошка'))

для питомца в запросе:
    print(pet.name, pet.имя владельца)

# отпечатки:
# Китти Боб
# Варежки Jr Herb
 

Соберем всех питомцев Боба:

 для питомца в Pet.select().join(Person).where(Person.name == 'Bob'):
    печать (имя животного)

# отпечатки:
# Китти
# Фидо
 

Здесь мы можем сделать еще одну интересную вещь, чтобы получить питомцев Боба. Поскольку у нас уже есть объект для представления Боба, вместо этого мы можем сделать это:

 для питомца в Pet.select().where(Pet.owner == uncle_bob):
    печать (имя животного)
 

Сортировка

Давайте удостоверимся, что они отсортированы по алфавиту, добавив order_by() пункт:

 для питомца в пет.select().where(Pet.owner == uncle_bob).order_by(Pet.name):
    печать (имя животного)

# отпечатки:
# Фидо
# Китти
 

Теперь перечислим всех людей, от младшего к старшему:

 для человека в Person.select().order_by(Person.birthday.desc()):
    print(человек.имя, человек.день рождения)

# отпечатки:
# Боб 1960-01-15
# Херб 1950-05-05
# Бабушка Л. 1935-03-01
 

Объединение выражений фильтра

Peewee поддерживает произвольно вложенные выражения. Давайте соберём всех людей, чьи день рождения был либо:

  • до 1940 г. (бабушка)
  • после 1959 г. (б)
 d1940 = дата (1940, 1, 1)
d1960 = дата (1960, 1, 1)
запрос = (человек
         .Выбрать()
         .where((Person.birthday < d1940) | (Person.birthday > d1960)))

для лица в запросе:
    print(человек.имя, человек.день рождения)

# отпечатки:
# Боб 1960-01-15
# Бабушка Л. 1935-03-01
 

Теперь сделаем наоборот. Люди, чей день рождения приходится на период с 1940 по 1960 год:

.
 запрос = (Человек
         .Выбрать()
         .где(Человек.день рождения.между(д1940, д1960)))

для лица в запросе:
    print(человек.имя, человек.день рождения)

# отпечатки:
# Херб 1950-05-05
 

Агрегаты и предварительная выборка

Теперь давайте перечислим всех людей и , сколько у них домашних животных:

 для человека в лицо.Выбрать():
    print(person.name, person.pets.count(), 'домашние животные')

# отпечатки:
# Боб 2 питомца
# Бабушка Л. 0 питомцев
# Трава 1 питомца
 

Мы снова столкнулись с классическим примером запроса N+1 поведение. В этом случае мы выполняем дополнительный запрос для каждого Лицо возвращено исходным ВЫБЕРИТЕ ! Мы можем избежать этого, выполнив a JOIN и использование функции SQL для агрегирования результатов.

 запрос = (Человек
         .select(Person, fn.COUNT(Pet.идентификатор).псевдоним('pet_count'))
         .join(Pet, JOIN.LEFT_OUTER) # включить людей без домашних животных.
         .group_by(человек)
         .order_by(Person.name))

для лица в запросе:
    # "pet_count" становится атрибутом возвращаемых экземпляров модели.
    print(person.name, person.pet_count, 'домашние животные')

# отпечатки:
# Боб 2 питомца
# Бабушка Л. 0 питомцев
# Трава 1 питомца
 

Примечание

Peewee предоставляет волшебного помощника fn() , который можно использовать для вызова любая функция SQL. В приведенном выше примере фн.COUNT(Pet.id).псевдоним('pet_count') будет преобразовано в COUNT(pet.id) AS pet_count .

Теперь перечислим всех людей и имена всех их питомцев. Как у вас может быть догадались, это может легко превратиться в очередную ситуацию N+1, если мы не осторожны.

Прежде чем углубляться в код, подумайте, чем этот пример отличается от предыдущий пример, где мы перечислили всех домашних животных и имя их владельца. Домашнее животное может только один владелец, поэтому, когда мы выполнили объединение от Pet до Person , всегда должен был быть одиночный матч.Иная ситуация, когда мы присоединяются от Person к Pet , потому что у человека может не быть домашних животных или у них может быть несколько домашних животных. Поскольку мы используем реляционные базы данных, если мы должны были выполнить соединение от Person до Pet , тогда каждый человек с несколькими домашние животные будут повторяться, один раз для каждого домашнего животного.

Это будет выглядеть так:

 запрос = (Человек
         .select(Человек, Домашнее животное)
         .join(Домашнее животное, JOIN.LEFT_OUTER)
         .order_by(Человек.имя, пет.имя))
для лица в запросе:
    # Нам нужно проверить, есть ли у них экземпляр питомца, так как не все
    # у людей есть домашние животные.
    если hasattr(человек, 'домашнее животное'):
        print(person.name, person.pet.name)
    еще:
        print(person.name, 'без домашних животных')

# отпечатки:
# Боб Фидо
# Боб Китти
# Бабушка Л. без домашних животных
# Херб Варежки-младший
 

Обычно такое дублирование нежелательно. Для размещения более распространенных (и интуитивно понятный) рабочий процесс перечисления человека и прикрепления списка этого домашних животных человека, мы можем использовать специальный метод, называемый предварительная выборка() :

 запрос = Человек.select().order_by(Person.name).prefetch(Pet)
для лица в запросе:
    печать(человек.имя)
    для домашних животных лично.
        print('*', pet.name)

# отпечатки:
# Боб
# * Китти
# * Фидо
# бабушка Л.
# Трава
# * Варежки младший
 

Функции SQL

Последний запрос. Это будет использовать функцию SQL, чтобы найти всех людей, чьи имена начинаться с верхнего или нижнего регистра G :

 выражение = fn.Lower(fn.Substr(Person.name, 1, 1)) == 'g'
для человека в Person.select().где (выражение):
    печать(человек.имя)

# отпечатки:
# бабушка Л.
 

Это только основы! Вы можете сделать ваши запросы настолько сложными, насколько вам нравится. Обратитесь к документации по запросам для получения дополнительной информации.

База данных

Мы закончили с нашей базой данных, давайте закроем соединение:

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

Чтобы узнать о настройке базы данных, см. документацию по базе данных, что дает множество примеров. Peewee также поддерживает настройку базы данных во время выполнения. а также настройку или изменение базы данных в любое время.

Работа с существующими базами данных

Если у вас уже есть база данных, вы можете автоматически генерировать модели peewee, используя pwiz, генератор моделей. Например, если у меня есть база данных postgresql с именем charles_blog , я мог бы запустить:

 python -m pwiz -e postgresql charles_blog > blog_models.пи
 

Что дальше?

Это краткое руководство. Если вы хотите посмотреть на полное веб-приложение, проверьте Приложение Пример.

Блог Пи-Ви - Я, Пи-Ви Герман

/ Пи-Ви Герман

Крайний срок: HBO не привыкать проливать свет на некоторых из самых очаровательных людей Голливуда, и теперь он нацеливается на человека, который помог создать одного из самых любимых персонажей в мире.…

Подробнее

/ Пи-Ви Герман

2-22-22 - это второй день!! Каково значение? У меня нет двойки!!…

Подробнее

/ Пи-Ви Герман

🧷♥⛓🤘🏻 Панк-театр!! Чикагскими Кобанесами!!…

Подробнее

/ Пи-Ви Герман

В этот день в 1958 году был запатентован первый кубик LEGO!! LEGO назван в честь датской фразы «leg godt», что означает «хорошо играть»!…

Подробнее

/ Пи-Ви Герман

Как же мне грустно, что мой друг Луи Андерсон покинул землю.…

Подробнее

/ Пи-Ви Герман

«В эту самую ночь, 48 лет назад, по этому же отрезку дороги в густом тумане вот так…

Подробнее

/ Пи-Ви Герман

Рождественский специальный выпуск Театра Пи-Ви дебютировал на телевидении 21 декабря 1988 года!!…

Подробнее

/ Пи-Ви Герман

Рождество просто не Рождество без причудливого рождественского альбома!!…

Подробнее

/ Пи-Ви Герман

ПОСКОЛЬКУ ВЫ СПРАШИВАЛИ: Рождественский выпуск Pee-wee's Playhouse во всем своем обновленном великолепии доступен для потоковой передачи!!…

Подробнее

/ Пи-Ви Герман

В этот день в 1937 году родилась «Большая Мардж»!…

Подробнее

/ Пи-Ви Герман

Меня зовут Пи-Ви.Пи-пи Герман. KCRW воплощает в жизнь мою мечту стать радио-диджеем!…

Подробнее

/ Пи-Ви Герман

С ПРАЗДНИКОМ БЛАГОДАРИМ каждого из вас!! Я так благодарна всем своим друзьям и поклонникам!! …

Подробнее

/ Пи-Ви Герман

Лу Кателл, актер, сыгравший Удивительного Ларри в «Большом приключении Пи-Ви», скончался в воскресенье.…

Подробнее

Большое приключение Пи-Ви (1985) - Пол Рубенс в роли Пи-Ви Германа

мистер Бакстон : [после того, как Пи-Ви и Фрэнсис борются в ванне, а Пи-Ви пытается открыть окно] Пи-пи, Пи-пи! Что здесь происходит?

Пи-Ви Герман : Он вор! Он украл мой велосипед!

Фрэнсис : Ты - лжец! Клянусь, я этого не делал, папа!

Г-н.Бакстон : Пи-пи, это серьезное обвинение. У вас есть доказательства?

Пи-Ви Герман : Ну, не совсем так.

мистер Бакстон : Пи-пи, Бакстоны не воры. Просто посмотри на него.

[Фрэнсис делает грустное щенячье лицо]

Г-н.Бакстон : Он не мог украсть твой велосипед. Он не выходил из этого дома со вчерашнего дня. Мы готовили планы на день рождения Фрэнсиса весь день.

Пи-Ви Герман : Гы, я думаю, я был неправ.Мы не обязаны вовлекать в это дело власти, не так ли, мистер Бакстон? Это была честная ошибка, и я очень сожалею.

мистер Бакстон : Хорошо... Я все еще думаю, что вы должны извиниться перед Фрэнсисом, а затем я хочу увидеть, как вы двое обменяетесь рукопожатием.

Пи-Ви Герман : Прости, Фрэнсис.

[Пожимает ему руку и тянется за жевательной резинкой]

Пи-Ви Герман : Вот, не хочешь немного жвачки?

[Фрэнсис берет кусок жевательной резинки]

Пи-Ви Герман : Не хотите ли немного, мистер?Бакстон?

мистер Бакстон : О, спасибо.

Пи-Ви Герман : Мята или фрукты?

Г-н.Бакстон : О, фрукты, пожалуйста.

[Берет кусок жевательной резинки]

Пи-Ви Герман : [уход] Хорошо... до свидания!

мистер Бакстон : До свидания.

Фрэнсис : Ты ведь веришь мне, не так ли, папа?

[когда Фрэнсис жует мятную жевательную резинку, слюна у него во рту становится черной.Мистер Бакстон кричит, когда понимает, что его жевательная резинка с фруктами острая]

Магия Пи-Ви Германа в темный год

В тот день, когда Всемирная организация здравоохранения назвала Омикрон «вариантом, вызывающим озабоченность», я чувствовал себя так же тяжело, как и в любой другой день с начала пандемии, и я слушал, как Пи-Ви Герман трещит по швам. шутки с говорящим стулом. На одну ночь его кукольные друзья из Театр Пи-Ви , популярного детского телешоу 80-х, воссоединились на радио, чтобы в течение часа подшучивать под старые соул-записи.Их шутки были напыщенными, но удобными — из тех, что заставляют закатывать глаза и одновременно хихикать. Но этот эпизод ощущался почти как передача с другой планеты или, по крайней мере, из более простого времени. Для меня, сидящего на диване в гостиной и пытающегося отогнать страх перед этим загадочным новым штаммом коронавируса, это был свет, сияющий во тьме.

Я учился в средней школе, когда вышел Театр Пи-Ви . Шоу представляло собой ликующую, хаотичную смесь живого действия, кукольного искусства и анимации, что совсем не походило на типичные, дешево нарисованные субботними утренними мультфильмами того времени.В наборе в стиле поп-арт была говорящая мебель и холодильник, полный живой еды, и его часто посещали персонажи, которых играл Фил Хартман, и Лоуренс Фишберн, существовавший до «Матрица ». Тон смешал банальную невинность детского телевидения 50-х с эстетикой зеркала и лазерного луча Новой волны 80-х. За штурвалом стоял худощавый Пи-Ви Герман, одетый в облегающий серый костюм, красный галстук-бабочку и белые кожаные мокасины. Он был взрослым мужчиной, который вел себя как пятилетний ребенок, который только что выпил коробку замороженных хлопьев. У Смурфиков не было шансов.

Я был слишком стар, чтобы смотреть детское телевидение, но Playhouse казался секретной, удивительно зрелой комнатой, которая была открыта только для меня. Яркие цвета и контрастные узоры (дизайном руководил панк-художник Гэри Пантер) соответствовали другой странной культуре, которую я любил в то время: карикатуристке Линде Бэрри, авангардистской группе The Residents, фолк-артисту Говарду Финстеру. Все это перевернуло однообразие пригорода на ухо.Это было сделано не поднятием среднего пальца, как это делала панк-музыка, а преломлением клише — идеальных лужаек, церковных обедов и всего прекрасного — через зеркало дома смеха.

Из-за того, что я был напуган и отличался от других, Театр был местом, где я хотел жить какое-то время. Там был Джамби, плавающая голова в коробке, исполняющая желания; Конки, заикающийся робот, который снабжал каждую серию «секретным словом»; и Король мультфильмов, игравший пыльные черно-белые клипы. Ничто из этого не имело смысла, и все это имело смысл.Те из нас, кто думал, что мы не имеют смысла, имели свое место. Итак, каждые выходные я регулировал фольгу, прикрепленную к антенне нашего маленького телевизора. В 1986 году, когда я был семиклассником, у меня не было друзей, так что мне особо нечего было делать. За последние 21 месяц пандемии мне тоже особо нечего было делать. В моем доме тесно, и я, моя жена, двое наших детей и наша собака переживают это безнадежное время вместе. Кто не искал место, куда можно сбежать?


Возможно, Пи-Ви резонировал с моим юношеским «я», потому что его обращение к Питеру Пэну противоречило более взрослому происхождению.Персонаж родился из импровизаций Пола Рубенса, когда он был членом влиятельной комедийной труппы Лос-Анджелеса Groundlings. Это привело к живому выступлению The Pee-wee Herman Show в 1981 году в Roxy Theater. Слегка развратная пародия на детские шоу 50-х годов, проходившие в печально известном рок-клубе Лос-Анджелеса, она шла в течение пяти месяцев, прежде чем закончилась специальным выпуском HBO. Его успех в конечном итоге привел к появлению в 1985 году фильма Большое приключение Пи-Ви , в котором персонаж отправился в сюрреалистический поиск своего украденного велосипеда.Фильм представил миру причудливый юмор Рубенса, а также галлюцинаторное видение не совсем готического режиссера по имени Тим Бертон. Театр Пи-Ви дебютировал на канале CBS в 1986 году и быстро стал одним из самых популярных утренних субботних телешоу своего времени, регулярно собирая около 10 миллионов зрителей. Были фигурки Пи-Ви в Toys «R» Us, партнерство по одежде с JCPenney и коллекционные карточки от Topps.

Пять лет спустя Рубенс был арестован за непристойное разоблачение в порнокинотеатре Флориды; он не оспаривал обвинение, хотя он и его адвокаты настаивали на своей невиновности.Широко распространено мнение, что арест Рубенса привел к закрытию Playhouse , но на самом деле шоу было отменено несколькими месяцами ранее (однако это событие, по-видимому, повлияло на решение сети прекратить повторы). Тем не менее, Пи-Ви не было в эфире. Рубенс построил новую актерскую карьеру до очередного ареста в 2002 году, когда ему было предъявлено обвинение в хранении детской порнографии, в котором он не признал себя виновным. Позже это было сведено к обвинению в непристойном поведении, в котором Рубенс признал себя виновным, настаивая на том, что полиция конфисковала старинные произведения искусства, которые он купил у коллекционера.Рубенс отсидел три года условно, зарегистрировался на этот период как сексуальный преступник и снова скрылся от глаз общественности. Эти происшествия теперь для меня такой же неотъемлемой частью Пи-Ви, как марионеточный ансамбль Театра. Их трудно примирить, если не считать того, что Пи-Ви — персонаж, а Рубенс — смертный и склонный к ошибкам человек.

Но с тех пор Пи-Ви вновь появлялся время от времени и в разных средах. Playhouse был повторно показан на Adult Swim в 2006 году, после чего в 2010 году последовала переработка живого Pee-wee Herman Show .В 2016 году Netflix выпустил Большой праздник Пи-Ви . Пять лет спустя Пи-Ви крутил записи по общественному радио в течение одной ночи. В этот момент его периодические появления кажутся частью мистики персонажа.

Прочтите: Злоключения Пи-Ви

В конце концов, Пи-Ви всегда существовал вне линейного времени. В его мире жестяные игрушки соседствуют с ретро-футуристическими видеофонами, которые мы могли бы признать идеальными для Zoom сегодня. Театр Обычная мисс Ивонн, «самая красивая женщина в мире марионеток», одетая как украшение для торта из 1950-х годов, а Реба, почтальонша, одета как обычный работник USPS.Одежда Пи-Ви, которую он носил на сцене в 1981 году, такая же, как и на Netflix в 2016 году; его фирменный смешок и насмешки на школьном дворе: «Я знаю, что ты есть, но кто я?» и «Заставил тебя выглядеть» тоже идентичны. Пи-Ви существует как память: смесь прошлого и настоящего, знакомая, но не слишком знакомая.

Находясь вне времени, Пи-Ви предлагает вам взглянуть на мир по-новому, увидеть чудесное в обыденном. Самыми волшебными персонажами в театре были не динозавры, живущие в мышиной норе, и не джинны, исполняющие желания, а говорящее кресло, окно и пол.Когда вы следовали за Пи-Ви, вы никогда не знали, где окажетесь. Пропавший велосипед может привести к грандиозному путешествию. Танцем можно победить кровожадную банду мотоциклистов. Все было наполнено возможностью.


По мере того, как мы приближаемся к третьему году пандемии, я перешел от выгорания к пространству, которое кажется абсолютно лишенным радости. Все серое. Каждая надежда на конец этой ситуации встречает новую букву греческого алфавита. Иногда мне кажется, что я потерял что-то важное в своем существе.Что такое мои отчаянные ночные просмотры через Zillow, как не поиск чуда? Что такое пролистывать бесконечную прокрутку TikTok, как не охота за мельчайшими кусочками сюрприза? Я отчаянно пытаюсь найти благоговение в сегодняшней монотонности. Я отчаянно хочу вернуться в Playhouse.

Вот почему в пятницу после Дня Благодарения я слушал, как Пи-Ви играет мелодии, отпускает шутки и принимает пару странных гостей (постоянная приглашенная звезда Love Boat Чаро играла на гитаре фламенко) на KCRW, в Санта-Монике. – на базе общественно-радиостанции.Робот Конки сообщил Пи-Ви секретное слово ( микрофон ), и через час все было кончено. Не было никаких ссылок на темную реальность, в которой мы сейчас живем. Но невинность шоу казалась удивительно подрывной.

Пи-Ви может быть вечным, но Рубенс — нет. В следующем году ему исполнится 70 лет. Его голос по радио был заметно глубже и гуще, чем несколько десятилетий назад. В интервью, посвященном выпуску Big Holiday , Рубенс признал, что Пи-Ви была омоложена в цифровом виде.Театр тоже пустеет. Джон Парагон, актер, сыгравший джинна Джамби, а также сценарист и режиссёр многих эпизодов Playhouse вместе с Рубенсом, умер в апреле. Рубенс оплакивал смерть Лу Кателла, сыгравшего Удивительного Ларри в «Большое приключение », за несколько дней до того, как его радиошоу вышло в эфир.

Теперь мы все знаем горе. Мы скорбим о людях, которых любили, а также о людях, которыми мы были до начала этой пандемии. Если ты достаточно взрослый, ты добавляешь его к горю, накопившемуся за эти годы: о детях, которыми мы были, о надеждах, которые у нас были, о людях, которыми мы хотели быть.Но если вам повезет, искусство, которое вам нужно, все равно найдет вас. Это напоминает вам о том, кто вы есть, когда вы забыли, и дает вам возможность представить себе жизнь за пределами этой. Это позволяет вам верить, что то, что у вас украли, будет найдено, что ваш дом оживет.

В этом году мы решили осветить наш двор перед Рождеством. Мы с женой пронеслись по праздничному проходу в Home Depot, как будто мы были одержимы — все, что угодно, лишь бы отогнать темноту. Недавно стоял снаружи в 16:30.м., я понял, что наш дом, сверкающий рождественскими огнями и надувными животными, выглядит знакомым. Он был похож на Театральный дом.

Пи Ви Холселл - тренер по легкой атлетике

Самый продолжительный главный тренер в истории WWU, поскольку 2020-21 годы - это его 34-й год во главе программ WWU по легкой атлетике и кроссу ... Получил 38 наград «Тренер года», 28 раз выбирался лигой, шесть регионов, Первый район и район один ... Тренер года Великой Северо-Западной спортивной конференции 21 раз (мужская беговая дорожка в помещении в 2005, 2006, 2013, 2014, 2019, 2020 годах; мужская беговая дорожка на открытом воздухе 2005, 2010, 2012, 2013, 2014, 2015 и 2019; женский открытый трек 2009, мужской кросс 2003, 2006, 2007, 2010, 2019, женский кросс 2015, 2019)... Тренировал 10 национальных чемпионов по легкой атлетике ... Под его руководством 101 викинг получил всеамериканские награды по легкой атлетике и 30 по пересеченной местности, в общей сложности 160 всеамериканских наград ... Также имеет множество ученых. Спортсмены по легкой атлетике и кроссу ... Его команды 32 раза финишировали в топ-20 национальных соревнований по кроссу и 16 на треке.

10

Индивидуальные чемпионы страны

 

16

Ученые-спортсмены WWU года

 

27

Спортсмены года WWU

 

28

CoSIDA Округ 8 Общеакадемический

 

33

Командные чемпионаты

 

38

Премия «Тренер года»

 

88

Все звезды конференции (XC)

 

160

Все американцы

 

209

Академические всеамериканцы

 

227

Чемпионы конференции (T&F)

 

357

Все звезды Западного региона

 

553

Национальные участники

 

580

Конференция академических звезд


В 2019 году как мужская, так и женская программы по пересеченной местности выиграли титул GNAC и вышли на чемпионат NCAA II в Сакраменто, а мужская команда снова стала чемпионом GNAC в помещении.

В 2018 году и мужская, и женская беговые программы прошли на чемпионат NCAA II в Питтсбурге, а в 2019 году мужская беговая программа в помещении и на открытом воздухе выиграла командный титул GNAC.

В 2015 году женская команда по кроссу заняла 6-е место на чемпионате NCAA II, что стало самым высоким результатом в истории программы. В 2011 году его женская команда заняла шестое место на Национальном чемпионате по легкой атлетике на открытом воздухе NCAA Division II, что стало самым высоким результатом в школе и истории GNAC ... В 2009 году его мужская команда по кроссу заняла четвертое место на национальных соревнованиях, что стало самым высоким результатом в истории школы... Направлял женскую команду по кроссу на четвертое место на национальном чемпионате NAIA в 1992 году, а женскую команду по легкой атлетике - на восьмое место на национальном чемпионате в 1997 году. За время пребывания в WBU Pioneers трижды занимали второе место в мужском дивизионе и дважды в женском дивизионе на соревнованиях NAIA National Outdoor, а также выиграли три мужских титула (1985-87) и одну корону среди женщин (1986) на NAIA National Indoor. Тренировал 43 американца NAIA в WBU... Получил степень бакалавра в 1981 году и степень магистра в 1985 году, обе в WBU ... Также учился в колледже Саут-Плейнс (Техас) в качестве студента-помощника тренера в команде техасцев, занявшей четвертое место на соревнованиях National Junior College Outdoor в 1979 году.

Летом 1983 года поехал в Москву, Россия, чтобы изучать технику легкой атлетики в Советском Союзе... Проработал два года (2004-06) в качестве президента Дивизиона II Ассоциации тренеров по бегу США по пересеченной местности, после чего был вице-президентом в течение двух лет. лет (2002-04) ... Выпускник средней школы Браунфилда (Техас) 1976 года ... Опытный альпинист, покоривший Ренье, Бейкера, Шуксана, Адамса, Ледниковый пик, Шасту и Худ ... Он и его жена Мария, которая была национальной чемпионкой NAIA по метанию копья. в Wayland Baptist есть две дочери, Сара и Лаура.

Обновлено 15 января 2021 г. .

Добавить комментарий

Ваш адрес email не будет опубликован.