Доброго времени суток, Codeby !
В первой части я писал про авторизацию веб-приложения, где в роли главной страницы выступала заглушка. Сейчас я решил сделать что-то полезное для себя: у меня достаточно много всяких скриптов, которые рассованы по папкам, флешкам и т.д. Приходится каждый раз копать, но иногда мне нужна только часть кода или какие то функции для быстрого запуска. На рабочем ПК у меня поднят MySQL и я решил хранить код дополнительно в БД, а доступ получать к нему из веб-морды. Зная название скрипта можно будет получить его в браузере и сразу записать в интерпретатор или файл.
Новая модель в БД :
Помимо таблицы users для авторизации, я добавил новую модель (таблицу) в БД:
Чтобы ничего не усложнять тут будет два поля ( не считая id ) - название скрипта и сам код. Надо отметить, что может быть лучше использовать другой тип данных в базе, но я думаю 32728 текстовых символа мне будет пока достаточно.
HTML и роутинг страниц:
Помимо авторизации и регистрации будет два новых маршрута, которые будут возвращать страницы добавления и извлечения записей из БД соответственно.
Доставая данные из базы в цикле надо заменить спец.символы - у SQL с ними возникают проблемы, а заменяя их на тэг <br> можно получить нужные переносы строк в HTML. По команде * можно достать имена всех скриптов, которые хранятся в таблице.
Сам HTML database не содержит ничего особенного, кроме, наверное <pre> тэга, о котором я не знал и который мне очень помог. Обернутые им элементы сохраняют свои первоначальные отступы, это нужно чтобы сохранять питоновские отступы в скриптах из БД. Ну, и к слову, autoescape - элемент шаблонизатора Jinja, который надо вырубить, чтобы превратить тэг <br> в реальный отступ, выводя на веб страницу.
Библиотека для работы с MySQL:
Для дополнительных запросов к БД я использую еще один файлик с библиотекой mysql.connector. Вообще, мне нравится работать с SQL на Python - очень удобно и мало кода. Можно пробежаться ранером сразу по нескольким базам и прогнать запрос. Принцип везде общий - создается объект коннекта, который передается дальше для создания курсора, отправки запроса и получения ответа. Сами запросы прописываются в виде строк и могут принимать переменные.
Этот класс используется по /db URL, при клике на кнопку submit создается объект этого класса и выполняется функция execute_read_query, которая принимает на вход переменную (название скрипта) и по ней в базе ищет нужные записи. Основная проблема с которой я столкнулся была в том, чтобы правильно сохранить и вывести данные из базы. Для промежуточного хранения ответа создан массив datas = [ ] из которого шаблонизатор jinja и выбирает данные в цикле внутри database.html
Куда же без черепов :
Люблю я всякие хардкорские штуки ( черепа, розы, паучки ) и уж не могу удержаться чтобы куда-нибудь не добавить
И вот так это выглядит. Просто вставляем нужный скрипт в textarea и сохраняем в базу. Так как моих папок развелось ну прям очень много, а среди них есть и тестовые, и не юзабельные, то на рабочем ПК будет удобненько это держать.
Получаем такой вывод :
Ниже находится весь код. Шрифт конечно большой, зато все как на ладони ). Ну и отступы тоже нормально выводятся, чтобы можно было копировать и сразу выполнить.
Теория по максимальным значениям SQL:
Инфа с MySQL форума по максимальным значениям, которые могут храниться в БД.
Для справки :
- Максимальное количество таблиц: 4 ГБ
- Максимальный размер таблицы: 32 ТБ
- Столбцы в таблице: 1000
- Максимальный размер строки: n * 4 ГБ
- 8 КБ, если хранятся на той же странице
- n * 4 ГБ с n BLOB-объекты
- Максимальная длина ключа: 3500
- Максимальный размер табличного пространства: 64 ТБ
- Максимальное количество одновременных транзакций: 1023
Спасибо за внимание
Не знаю, на сколько это будет полезно для меня, но в целом было интересно поработать и есть особый кайф, когда ошибки не дают тебе двинуться дальше и ты лихорадочно пытаешься их решить). И весь кайф в том, что тебе все таки удается это сделать и это может относиться не только к коду или к ИТ, а вообще к жизни в целом наверное. В общем, не буду флудить не по теме ( а хочется ) и, пожалуй, на этом закончу.
Чекаем название последнего пункта, всем спасибо )
В первой части я писал про авторизацию веб-приложения, где в роли главной страницы выступала заглушка. Сейчас я решил сделать что-то полезное для себя: у меня достаточно много всяких скриптов, которые рассованы по папкам, флешкам и т.д. Приходится каждый раз копать, но иногда мне нужна только часть кода или какие то функции для быстрого запуска. На рабочем ПК у меня поднят MySQL и я решил хранить код дополнительно в БД, а доступ получать к нему из веб-морды. Зная название скрипта можно будет получить его в браузере и сразу записать в интерпретатор или файл.
Новая модель в БД :
Помимо таблицы users для авторизации, я добавил новую модель (таблицу) в БД:
Python:
class Scripts(db.Model):
id = db.Column(db.Integer, primary_key=True)
typeof = db.Column(db.String(1024))
info = db.Column(db.String(32768))
Чтобы ничего не усложнять тут будет два поля ( не считая id ) - название скрипта и сам код. Надо отметить, что может быть лучше использовать другой тип данных в базе, но я думаю 32728 текстовых символа мне будет пока достаточно.
HTML и роутинг страниц:
Помимо авторизации и регистрации будет два новых маршрута, которые будут возвращать страницы добавления и извлечения записей из БД соответственно.
Python:
@app.route("/", methods=["GET", "POST"])
@login_required
def add_position():
connect = selecter.create_connection('db', 'user', 'pwd', 'localhost')
if request.method == 'POST':
typeof = request.form["typeof"]
info = request.form["info"]
print(info.replace('\r\n', '\n'))
new_position = Scripts(typeof=typeof, info='\n' + info.replace('\r\n', '\n'))
db.session.add(new_position)
db.session.commit()
return redirect(url_for('add_position'))
return render_template('index.html')
@app.route("/db", methods=["GET", "POST"])
@login_required
def check_position():
connect = selecter.create_connection('db', 'user', 'pwd', 'localhost')
if request.method == 'POST':
datas.clear()
typeof = request.form["typeof"]
if typeof:
if typeof == '*':
response = selecter.execute_read_query_all(connect)
for res in response:
datas.append('\n' + res[0])
else:
response = selecter.execute_read_query(connect, typeof)
for res in response:
datas.append(res[1].replace('\r\n', '<br>'))
return render_template('database.html', datas=datas)
Доставая данные из базы в цикле надо заменить спец.символы - у SQL с ними возникают проблемы, а заменяя их на тэг <br> можно получить нужные переносы строк в HTML. По команде * можно достать имена всех скриптов, которые хранятся в таблице.
Сам HTML database не содержит ничего особенного, кроме, наверное <pre> тэга, о котором я не знал и который мне очень помог. Обернутые им элементы сохраняют свои первоначальные отступы, это нужно чтобы сохранять питоновские отступы в скриптах из БД. Ну, и к слову, autoescape - элемент шаблонизатора Jinja, который надо вырубить, чтобы превратить тэг <br> в реальный отступ, выводя на веб страницу.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
<link href="{{ url_for('static', filename='css/index.css') }}" rel='stylesheet' type='text/css'/>
</head>
<body>
<H1>MY SCRIPTS</H1>
<form action="/db" method="POST" class="form">
<div>
<label>NAME SCRIPT</label>
<input name="typeof" placeholder="name script">
</div>
<button type="submit">select</button>
</form>
<img src="{{ url_for('static', filename='img/auth.png') }}" class="img">
<div class="scripts">
<pre>
{% autoescape false %}
{% for data in datas %}
{{data}}
{% endfor %}
{% endautoescape %}
</pre>
</div>
</body>
</html>
Библиотека для работы с MySQL:
Для дополнительных запросов к БД я использую еще один файлик с библиотекой mysql.connector. Вообще, мне нравится работать с SQL на Python - очень удобно и мало кода. Можно пробежаться ранером сразу по нескольким базам и прогнать запрос. Принцип везде общий - создается объект коннекта, который передается дальше для создания курсора, отправки запроса и получения ответа. Сами запросы прописываются в виде строк и могут принимать переменные.
Python:
import mysql.connector
from mysql.connector import Error
class Selecter:
def create_connection(self, db_name, db_user, db_password, db_host):
connection = None
try:
connection = mysql.connector.connect(
database=db_name,
user=db_user,
password=db_password,
host=db_host
)
print("Connection to PostgreSQL DB successful")
except OperationalError as e:
print(f"The error '{e}' occurred")
return connection
def execute_read_query(self, connection, select_data):
cursor = connection.cursor()
result = None
try:
cursor.execute("SELECT typeof, info FROM scripts WHERE typeof = %s",
[select_data])
result = cursor.fetchall()
return result
except OperationalError as e:
print(f"The error '{e}' occurred")
def execute_read_query_all(self, connection):
cursor = connection.cursor()
result = None
try:
cursor.execute("SELECT typeof FROM scripts")
result = cursor.fetchall()
return result
except OperationalError as e:
print(f"The error '{e}' occurred")
Этот класс используется по /db URL, при клике на кнопку submit создается объект этого класса и выполняется функция execute_read_query, которая принимает на вход переменную (название скрипта) и по ней в базе ищет нужные записи. Основная проблема с которой я столкнулся была в том, чтобы правильно сохранить и вывести данные из базы. Для промежуточного хранения ответа создан массив datas = [ ] из которого шаблонизатор jinja и выбирает данные в цикле внутри database.html
Куда же без черепов :
Люблю я всякие хардкорские штуки ( черепа, розы, паучки ) и уж не могу удержаться чтобы куда-нибудь не добавить
И вот так это выглядит. Просто вставляем нужный скрипт в textarea и сохраняем в базу. Так как моих папок развелось ну прям очень много, а среди них есть и тестовые, и не юзабельные, то на рабочем ПК будет удобненько это держать.
Получаем такой вывод :
Ниже находится весь код. Шрифт конечно большой, зато все как на ладони ). Ну и отступы тоже нормально выводятся, чтобы можно было копировать и сразу выполнить.
Теория по максимальным значениям SQL:
Инфа с MySQL форума по максимальным значениям, которые могут храниться в БД.
Для справки :
- Максимальное количество таблиц: 4 ГБ
- Максимальный размер таблицы: 32 ТБ
- Столбцы в таблице: 1000
- Максимальный размер строки: n * 4 ГБ
- 8 КБ, если хранятся на той же странице
- n * 4 ГБ с n BLOB-объекты
- Максимальная длина ключа: 3500
- Максимальный размер табличного пространства: 64 ТБ
- Максимальное количество одновременных транзакций: 1023
Спасибо за внимание
Не знаю, на сколько это будет полезно для меня, но в целом было интересно поработать и есть особый кайф, когда ошибки не дают тебе двинуться дальше и ты лихорадочно пытаешься их решить). И весь кайф в том, что тебе все таки удается это сделать и это может относиться не только к коду или к ИТ, а вообще к жизни в целом наверное. В общем, не буду флудить не по теме ( а хочется ) и, пожалуй, на этом закончу.
Чекаем название последнего пункта, всем спасибо )
Последнее редактирование модератором: