Возможно вы искали: 'BugRiders: The Race of...'

May 15 2025 19:31:13
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96111483
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18357
• Обзор The Walking ... 18801
• Обзор DMC: Devil M... 19879
• Обзор на игру Valk... 15877
• Обзор на игру Stars! 17764
• Обзор на Far Cry 3 17948
• Обзор на Resident ... 16024
• Обзор на Chivalry:... 17508
• Обзор на игру Kerb... 17981
• Обзор игры 007: Fr... 16619
Превью о играх
• Превью к игре Comp... 17960
• Превью о игре Mage... 14464
• Превью Incredible ... 14721
• Превью Firefall 13479
• Превью Dead Space 3 16334
• Превью о игре SimC... 14730
• Превью к игре Fuse 15442
• Превью Red Orche... 15542
• Превью Gothic 3 16343
• Превью Black & W... 17354
Главная » Статьи » Разное » Описание Python модуля cx_Oracle (python database oracle sql)

Описание Python модуля cx_Oracle (python database oracle sql)

Ключевые слова: python, database, oracle, sql, (найти похожие документы)

From: Попов О.Б. <opopov at yandex.ru>
Date: Mon, 17 May 2004 18:21:07 +0000 (UTC)
Subject: Описание Python модуля cx_Oracle

Оригинал: http://www.sama.ru/~popovob/pydba.html


Python - глазами DBA
(Описание модуля cx_Oracle)

Попов О.Б.
opopov@yandex.ru
г.Самара,май-август 2003 года

Содержание

* Почему собственно python
* Часть I. Выполняем простой запрос
* Часть II.Запросы с параметрами
* Часть III.Анонимные блоки PL/SQL
* Ссылки
* Листинги


Почему собственно python.
-------------------------

Администраторы БД очень часто нуждаются в инструментах для
автоматизации разной рутинной работы, например: загрузка,
преобразования данных в разного рода форматы или сбор и анализ
различной статистики.Для меня в свое время такой палочкой-выручалочкой
стал perl.

Через некоторое время я набрел на python.Вот все что я могу сказать
после 1 года знакомства:
Это практичный и полезный инструмент.

Несколько слов об инструментах.Вариантов на самом деле немного:
1)гремучая смесь из разных утилит командной строки (bash+awk+tar+...),
2)языки сценариев(perl,tcl/tk... ), 3)классические языки
программирования(С,C++)

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

Третий вариант позволяет получить великолепное решение при
значительных затратах сил и времени на программирование,отладку и
тестирование кода.А если их нет?

Золотой серединой очевидно является вариант номер 2.

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

Проблемы я вижу следующие:
-слишком сложные API,плохая читабельность кода
-отсутствие встроенных современных типов данных,
- крайняя медлительность выполнения,
-необходимость обновлять программы с Oracle Metalink.
- Java API имеет плохую обратную совместимость с предыдущими версиями
-java -это не собственная разработка Oracle corp., а технология ,
лицензированная у Sun , которая кое-что лицензировала еще у нескольких
фирм.

Недостатки применения java с RDBMS Oracle проявились особенно
отчетливо в следущем эпизоде:на компьютерах с процессорами Pentium IV,
отказался запускатьcя Oracle Universal Installer(речь идет о Oracle
8.1.7), написанный на Java . Причина оказалась в JIT compiler, который
Sun лицензировал у Symantec. Понятно почему, фирма Oracle длительное
время не могла решить эту проблему. Пользователи Oracle решали ее
самостоятельно -путем удаления одной dll. Не предсталяю,что бы делал я
в этой (и многих других)ситуации без интернета и духа открытости
пользователей Oracle-администраторов, программистов...

С perl обычно все намного лучше.Дух открытости (движение Open Source и
лицензия GPL) позволил Perl прогрессировать с космической скоростью:
-огромное количество великолепных библиотек,
-встроенные структуры данных-списки,hash-таблицы
-существование многочисленных книг, списков рассылки и просто
энтузиастов значительно облегчают жизнь профессионалу.

Несмотря на массу положительных свойств, Perl имеет imho ряд
существенных недостатков:
-крайне запутанный и к тому же подверженный изменениям синтаксис.
-значительная интеграция с юниксообразными ОС.
-не очень удачные средства поддержки OOP

Первое затрудняет сопровождение (даже собственных) программ.А второе
ограничивает сферу применимости языка на других платформах.

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

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


Достоинства языка python
------------------------

Python можно охарактеризовать в нескольких словах следующим образом:
многоплатформенный язык сценариев с динамической
типизацией,встроенными структурами данных и поддержкой трех парадигм
программирования-процедурной,объектной, функциональной.
* Многоплатформенность и масштабируемость-работает на большинстве
известных программно-аппаратных платформ от PDA до CRAY и IBM 390
* Гармоничная архитектура языка:
+ Простой и удобный для понимания логики програм синтаксис
+ Встроенные структуры данных-списки, кортежи,словари
+ Огромное количество библиотек:
-XML парсеры
-GUI(Win32,GTK/GNOME,KDE/QT,TK,FOX,WXWindows)
- Сетевые протоколы
- Разработка Web приложений
+ Переносимость кода между различными платформами
+ Мощные интерфейсы к конкретным ОС(особенно к Linux/Unix и
win32)
+ Поддержка разных стилей
программирования-процедурного,объектного,функционального
+ Встроенная поддержка Unicode и множества национальных
кодировок
(включая 5 русских)
+ Возможность писать самодокументированные программы и
автоматическая генерация документации на модули.

С чем реально сталкивается программист(а админитстратор является
таковым часто, но понемногу ) при использовании python.Это простой и
ясный синтаксис. Я ловлю себя часто на мысли,что просмотр чужого кода
зачастую не требует значительного напряжения.И здесь помогает то, что
отступы являются частью синтаксиса и определяют вложенность
операторов.

Библиотеки зачастую имеют очень лаконичную документацию, но этого
достаточно так как API очень выразительны и внятны. Отрадным явлением
в мире питона, является тот факт, что очень многие библиотеки были
разработаны после того, как были согласованы спецификации на
конкретные API.Одной из таких спецификаций является спецификация на
Python Database API 2.0. В соответствии с этой спецификацией
разрабатываются модули для доступа к конкретным СУБД.

К сожалению сам стандарт(как в свое время и cпецификация на ODBC) не
может учесть все специфические особенности конкретной СУБД, так как
фирмы-производители СУБД, используют свои фирменные расширения как
средство в конкуретной борьбе. Поэтому перенос кода с одной платформы
на другую все-таки очень трудно сделать безболезненным, если только
перед разработчиками не ставилась задача писать приложения,
предназначенное для работы с различными SQL серверами.

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

Для работы с RDBMS Oracle существует несколько различных модулей для
Python, использующих разные механизмы:
* ODBC(Win32,Linux)
* DCOM(Win32)
* PERL_DBI(Win32,Linux,Solaris,HP-UX,AIX)
* NATIVE API (Win32,Linux,Solaris,HP-UX,AIX)

Более подробную информацию Вы можете найти на http://www.python.org.


Часть I. Выполняем простой запрос.
----------------------------------

Я предпочитаю использовать модуль cx_Oracle, который был проверен мною
в ОС NT и Linux(автор-Anthony Tuininga утверждает что он работает в
Solaris и похоже, на всех юниксообразных ОС должен также работать ).В
основном этот модуль следует спецификации Python Database API 2.0 и
поддерживает работу с RDBMS Oracle версий 8.1-9.xx.

Модуль написан на языке С, что обеспечивает быструю обработку данных и
позволяет использовать все достоинства языка Python.

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

try:
import cx_Oracle
except ImportError,info:
print "Import Error:",info
sys.exit()
if cx_Oracle.version<'3.0':
print "Very old version of cx_Oracle :",cx_Oracle.version
sys.exit()


В этом фрагменте демонстрируется безопасная загрузка модуля cx_Oracle
и проверка версии. Надеюсь, элегантность синтаксиса все-таки заметили
:-)

Далее создадим экземпляр класса connect, именно этот объект и
обеспечивает взаимодействие с сервером Oracle

try:
my_connection=cx_Oracle.connect('system/manager@test_db')
except cx_Oracle.DatabaseError,info:
print "Logon Error:",info
exit(0)

Теперь создаем курсор и выполняем запрос:


my_cursor=my_connection.cursor()
try:
my_cursor.execute("""
SELECT OWNER,SEGMENT_TYPE,TABLESPACE_NAME,SUM(BLOCKS)SIZE_BLOCKS,
COUNT(*) SIZE_EXTENTS FROM DBA_EXTENTS
GROUP BY OWNER,SEGMENT_TYPE,TABLESPACE_NAME
""")
except cx_Oracle.DatabaseError,info:
print "SQL Error:",info
exit(0)

Динамическая типизация и поддержка сложных структур данных позволяет
легко обработать результаты SQL запроса. В результате вызова
my_cursor.fetchall() возращается список записей,каждая из которых
явлеяется кортежем(неизменяемым списком) полей разного типа. Если вы
знакомы с PL/SQL, то тогда цикл по списку записей будет очевидным:

for record in my_cursor.fetchall():
<обработка записи record,
record содержит кортеж из полей текущей записи>

Существует еще более любопытная возможность "разобрать" текущую запись
по полям:

for OWNER,SEGMENT_TYPE,TABLESPACE_NAME,SIZE_BLOCKS,SIZE_EXTENTS in my_cursor.fe
tchall():
<теперь можно обращаться к переменным, содержащим значения
одноименных полей курсора>

Печатаем результат на stdout. Замечу здесь, что my_cursor.description
возвращает описание столбцов запроса в виде списка кортежей. Для
каждого столбца возвращаются следующие данные:(name, type_code,
display_size, internal_size, precision, scale, null_ok). Далее следует
форматированный вывод на stdout( почти как printf в языке C).

print
print 'Database:',my_connection.tnsentry
print
print "Used space by owner, object type, tablespace "
print "----------------------------------------------------------------------------------"
title_mask=('%-16s','%-16s','%-16s','%-8s','%-8s')
i=0
for column_description in my_cursor.description:
print title_mask[i]%column_description[0],
i=1+i
print ''
print "----------------------------------------------------------------------------------"
row_mask='%-16s %-16s %-16s %8.0f %8.0f '
for record in my_cursor.fetchall():
print row_mask%record

В результате мы увидим что-то вроде:

Database: testdb
Used space by owner, object type, tablespace
--------------------------------------------------------------------------------
OWNER SEGMENT_TYPE TABLESPACE_NAME SIZE_BLOCKS SIZE_EXTENTS
--------------------------------------------------------------------------------
ADU2 INDEX USERS 784 25
ADU2 TABLE USERS 512 24
ADUGKS INDEX DEVELOP_DATA 984 123
ADUGKS TABLE DEVELOP_DATA 664 83
ADUGPA INDEX USERS 784 25
ADUGPA TABLE USERS 496 23
AGNKS_SG INDEX USERS 352 22
AGNKS_SG TABLE USERS 240 15
ATU INDEX USERS 3968 244
ATU TABLE DEVELOP_DATA 8 1
ATU TABLE USERS 2688 160
ATU1 INDEX DEVELOP_DATA 1600 200
ATU1 INDEX USERS 608 38
ATU1 TABLE DEVELOP_DATA 1032 129
ATU1 TABLE USERS 544 34
BUX INDEX DEVELOP_DATA 64 8
BUX TABLE DEVELOP_DATA 1736 217
DISP INDEX USERS 400 25
DISP TABLE USERS 528 33
EPE INDEX USERS 80 5
EPE TABLE USERS 48 3
EXZ INDEX USERS 1088 61
EXZ TABLE DEVELOP_DATA 8 1
EXZ TABLE USERS 832 41


Часть II. Запросы с параметрами.
--------------------------------

Согласно спецификации Python Database API 2.0, для выполнения запросов
с параметрами каждый модуль должен реализовывать переменную
paramstyle, которая определяет каким образом будут передаваться
параметры запросов. Текущая версия cx_Oracle(3.0) поддерживает режим
'named', то есть в модуле установлена переменная
cx_Oracle.paramstyle='named' и можно создавать конструкции в запросах
в виде:

select * from all_users where USERNAME LIKE :S

При этом связывание параметров запроса со значениями можно можно
выполнить двумя способами:
* Именованный параметeр метода execute:

cursor2.execute("select * from all_users where USERNAME LIKE :S ",S='S%')
* Словарь {':переменная':значение,...}

cursor2.execute("select * from all_users where USERNAME LIKE :S ",{':S':'S%'})


Часть III. Анонимные блоки PL/SQL
---------------------------------

Несмотря на существавания стандартов на язык SQL, реальные потребности
администратора часто требуют использования нестандартных средств
сервера(более того, написать приложение, работающее с сервером на
стандартном SQL возможно только для весьма тривиальных приложений ),
для Oracle таким нестандартным, но очень удобным механизмом является
возможность исполнения анонимных блоков PL/SQL. Модуль сx_Oracle
реализует этот механизм, который естественно не описан в спецификации
Python Database API 2.0 .

Чтобы связать переменные блока PL/SQL c переменными языка PYTHON, в
модуле сx_Oracle реализован класс var.Эекземпляр можно создать
следующим образом:

var=my_cursor.var(cx_Oracle.DATETIME)

Конструктор my_cursor.var(...) в качестве параметра требует указать
тип создаваемой переменной. Варианты:
* BINARY
* DATETIME
* FIXEDCHAR
* LONGBINARY
* LONGSTRING
* NUMBER
* ROWID
* STRING

var=my_cursor.var(cx_Oracle.DATETIME)
try:
my_cursor.execute("""begin
SELECT SYSDATE INTO :p_Value from dual;
end;""",p_Value = var)

except cx_Oracle.DatabaseError,info:
print "SQL Error:",info
exit(0)

Очевидно, что теперь var содержит текущее время сервера.Доступ к
значениям переменной выполняется с помощью метода var.getvalue():

CDATE=var.getvalue()
print 'Date: %02u/%02u/%4u'%(CDATE.day,CDATE.month,CDATE.year)
print 'Time: %02u:%02u:%02u'%(CDATE.hour,CDATE.minute,CDATE.second)

Этот пример демонстрирует также и форматирование даты и времени для
экземпляра var. В результате напечатается нечто вроде:

Date: 12/05/2003
Time: 16:42:54

Всвязи с тем, что работа с типами времени и даты внутри сервера Oracle
реализованы особенным образом ( независимо от ОС), модуль сx_Oracle
реализует следующие функции для для преобразования значений дат и
времени :
* Date( year, month, day)
* DateFromTicks( ticks)
* Time( hour, minute, second)
* TimeFromTicks( ticks)
* Timestamp( year, month, day, hour, minute, second)
* TimestampFromTicks( ticks)

var=my_cursor.var(cx_Oracle.DATETIME)
var.setvalue(0,cx_Oracle.Date( 2002, 02,12))
CDATE=var.getvalue()
print 'Date: %02u/%02u/%4u'%(CDATE.day,CDATE.month,CDATE.year)
print 'Time: %02u:%02u:%02u'%(CDATE.hour,CDATE.minute,CDATE.second)

Результат будет следующий:

Date: 12/02/2002
Time: 00:00:00

Ссылки

cx_Oracle-Python extension module that allows access to Oracle
Author: Anthony Tuininga http://computronix.com/utilities.shtml

Python Database API specification Python
http://www.python.org/topics/database/DatabaseAPI-2.0.html

Листинги

Листинг 1.
Выполняем простой запрос
_________________________________________________________________

""
cx_Oracle demo
simple query
"""
__AUTHOR__='POPOV O.'
__COPYRIGHT__='POPOV O. 2002 Samara, Russia'
from sys import exit
try:
import cx_Oracle
except ImportError,info:
print "Import Error:",info
sys.exit()

if cx_Oracle.version<'3.0':
print "Very old version of cx_Oracle :",cx_Oracle.version
sys.exit()
try:
my_connection=cx_Oracle.connect('system/gasdba@sqlmt')
except cx_Oracle.DatabaseError,info:
print "Logon Error:",info
exit(0)

my_cursor=my_connection.cursor()
try:
my_cursor.execute("""
SELECT OWNER,SEGMENT_TYPE,TABLESPACE_NAME,SUM(BLOCKS)SIZE_BLOCKS,
COUNT(*) SIZE_EXTENTS FROM DBA_EXTENTS
GROUP BY OWNER,SEGMENT_TYPE,TABLESPACE_NAME
""")
except cx_Oracle.DatabaseError,info:
print "SQL Error:",info
exit(0)

print
print 'Database:',my_connection.tnsentry
print
print "Used space by owner, object type, tablespace "
print "-----------------------------------------------------------"
title_mask=('%-16s','%-16s','%-16s','%-8s','%-8s')
i=0
for column_description in my_cursor.description:
print title_mask[i]%column_description[0],
i=1+i
print ''
print "------------------------------------------------------------"
row_mask='%-16s %-16s %-16s %8.0f %8.0f '
for record in my_cursor.fetchall():
print row_mask%record
for column_description in my_cursor.description:
print column_description




Листинг 2.
Запрос с параметрами
_________________________________________________________________

""
cx_Oracle demo
query with parameters
"""
__AUTHOR__='POPOV O.'
__COPYRIGHT__='POPOV O. 2002 Samara, Russia'
from sys import exit
try:
import cx_Oracle
except ImportError,info:
print "Import Error:",info
sys.exit()

if cx_Oracle.version<'3.0':
print "Very old version of cx_Oracle :",cx_Oracle.version
sys.exit()
try:
my_connection=cx_Oracle.connect('system/manager@test_db')
except cx_Oracle.DatabaseError,info:
print "Logon Error:",info
exit(0)

my_cursor=my_connection.cursor()
try:
my_cursor.execute("""
SELECT OWNER,SEGMENT_TYPE,TABLESPACE_NAME,SUM(BLOCKS)SIZE_BLOCKS,
COUNT(*) SIZE_EXTENTS FROM DBA_EXTENTS
WHERE OWNER LIKE :S
GROUP BY OWNER,SEGMENT_TYPE,TABLESPACE_NAME
""",S='SYS%')
except cx_Oracle.DatabaseError,info:
print "SQL Error:",info
exit(0)

print
print 'Database:',my_connection.tnsentry
print
print "Used space by owner, object type, tablespace "
print "-----------------------------------------------------------"
title_mask=('%-16s','%-16s','%-16s','%-8s','%-8s')
i=0
for column_description in my_cursor.description:
print title_mask[i]%column_description[0],
i=1+i
print ''
print "------------------------------------------------------------"
row_mask='%-16s %-16s %-16s %8.0f %8.0f '
for record in my_cursor.fetchall():
print row_mask%record

_________________________________________________________________

© Попов О.Б. 2003
1498 Прочтений •  [Описание Python модуля cx_Oracle (python database oracle sql)] [08.05.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Описание Python модуля cx_Oracle (p... Ukraine Vova 08.05.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка