diff --git a/__pycache__/add_func.cpython-311.pyc b/__pycache__/add_func.cpython-311.pyc new file mode 100644 index 0000000..a1da1c9 Binary files /dev/null and b/__pycache__/add_func.cpython-311.pyc differ diff --git a/__pycache__/dbtable.cpython-311.pyc b/__pycache__/dbtable.cpython-311.pyc index 8f79877..0c7c812 100644 Binary files a/__pycache__/dbtable.cpython-311.pyc and b/__pycache__/dbtable.cpython-311.pyc differ diff --git a/add_func.py b/add_func.py new file mode 100644 index 0000000..163c1fc --- /dev/null +++ b/add_func.py @@ -0,0 +1,5 @@ +import re + +def is_cyr_or_dig(string): + pattern = r'^[\u0400-\u04FF\d]+$' + return bool(re.match(pattern, string)) \ No newline at end of file diff --git a/dbtable.py b/dbtable.py index 62b955f..7888a05 100644 --- a/dbtable.py +++ b/dbtable.py @@ -56,8 +56,10 @@ class DbTable: sql += ", ".join(self.column_names_without_id()) + ") VALUES(" sql += ", ".join(vals) + ")" cur = self.dbconn.conn.cursor() + # cur.execute(sql) try: cur.execute(sql) + self.dbconn.conn.commit() except psycopg2.errors.UniqueViolation: self.dbconn.conn.rollback() return @@ -86,3 +88,26 @@ class DbTable: cur.execute(sql) return cur.fetchall() + def select_one(self, **kwargs): + conditions = [] + values = [] + + sorted_kwargs = sorted(kwargs.items(), key=lambda x: x[0]) + + for key, value in sorted_kwargs(): + conditions.append(f"{key}=%s") + values.append(value) + + sql = f"SELECT * FROM {self.table_name()} WHERE " + " AND ".join(conditions) + cur = self.dbconn.conn.cursor() + cur.execute(sql, tuple(values)) + result = cur.fetchone() + cur.close() + + if result: + return True + else: + return False + + + diff --git a/default_project/config.yaml b/default_project/config.yaml new file mode 100644 index 0000000..843ad1e --- /dev/null +++ b/default_project/config.yaml @@ -0,0 +1,6 @@ +# Базовые параметры настройки конфигурации проекта +dbname: postgres # В классе менять не надо +user: postgres # Замените на свой логин от БД в классе +password: qwerty # Замените на свой пароль от БД в классе +host: localhost # Замените на 192.168.0.48 в классе +dbtableprefix: "public." # Замените на свой логин от БД \ No newline at end of file diff --git a/default_project/dbconnection.py b/default_project/dbconnection.py new file mode 100644 index 0000000..6fac33c --- /dev/null +++ b/default_project/dbconnection.py @@ -0,0 +1,34 @@ +# Установка соединения с базой данных +# (параметры передаются через класс конфиг). +import psycopg2 + +class DbConnection: + + def __init__(self, config): + self.dbname = config.dbname + self.user = config.user + self.password = config.password + self.host = config.host + self.prefix = config.dbtableprefix + self.conn = psycopg2.connect(dbname = self.dbname, + user = self.user, + password = self.password, + host = self.host) + + def __del__(self): + if self.conn: + self.conn.close() + + def test(self): + cur = self.conn.cursor() + cur.execute("DROP TABLE IF EXISTS test CASCADE") + cur.execute("CREATE TABLE test(test integer)") + cur.execute("INSERT INTO test(test) VALUES(1)") + self.conn.commit() + cur.execute("SELECT * FROM test") + result = cur.fetchall() + cur.execute("DROP TABLE test") + self.conn.commit() + return (result[0][0] == 1) + + diff --git a/default_project/dbtable.py b/default_project/dbtable.py new file mode 100644 index 0000000..3971aad --- /dev/null +++ b/default_project/dbtable.py @@ -0,0 +1,86 @@ +# Базовые действия с таблицами + +from dbconnection import * + +class DbTable: + dbconn = None + + def __init__(self): + return + + def table_name(self): + return self.dbconn.prefix + "table" + + def columns(self): + return {"test": ["integer", "PRIMARY KEY"]} + + def column_names(self): + return sorted(self.columns().keys(), key = lambda x: x) + + def primary_key(self): + return ['id'] + + def column_names_without_id(self): + res = sorted(self.columns().keys(), key = lambda x: x) + if 'id' in res: + res.remove('id') + return res + + def table_constraints(self): + return [] + + def create(self): + sql = "CREATE TABLE " + self.table_name() + "(" + arr = [k + " " + " ".join(v) for k, v in sorted(self.columns().items(), key = lambda x: x[0])] + sql += ", ".join(arr + self.table_constraints()) + sql += ")" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def drop(self): + sql = "DROP TABLE IF EXISTS " + self.table_name() + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def insert_one(self, vals): + for i in range(0, len(vals)): + if type(vals[i]) == str: + vals[i] = "'" + vals[i] + "'" + else: + vals[i] = str(vals[i]) + sql = "INSERT INTO " + self.table_name() + "(" + sql += ", ".join(self.column_names_without_id()) + ") VALUES(" + sql += ", ".join(vals) + ")" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def first(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def last(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join([x + " DESC" for x in self.primary_key()]) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def all(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchall() + diff --git a/default_project/main.py b/default_project/main.py new file mode 100644 index 0000000..6b430e5 --- /dev/null +++ b/default_project/main.py @@ -0,0 +1,182 @@ +import sys +sys.path.append('tables') + +from project_config import * +from dbconnection import * +from people_table import * +from phones_table import * + +class Main: + + config = ProjectConfig() + connection = DbConnection(config) + + def __init__(self): + DbTable.dbconn = self.connection + return + + def db_init(self): + pt = PeopleTable() + pht = PhonesTable() + pt.create() + pht.create() + return + + def db_insert_somethings(self): + pt = PeopleTable() + pht = PhonesTable() + pt.insert_one(["Test", "Test", "Test"]) + pt.insert_one(["Test2", "Test2", "Test2"]) + pt.insert_one(["Test3", "Test3", "Test3"]) + pht.insert_one([1, "123"]) + pht.insert_one([2, "123"]) + pht.insert_one([3, "123"]) + + def db_drop(self): + pht = PhonesTable() + pt = PeopleTable() + pht.drop() + pt.drop() + return + + def show_main_menu(self): + menu = """Добро пожаловать! +Основное меню (выберите цифру в соответствии с необходимым действием): + 1 - просмотр людей; + 2 - сброс и инициализация таблиц; + 9 - выход.""" + print(menu) + return + + def read_next_step(self): + return input("=> ").strip() + + def after_main_menu(self, next_step): + if next_step == "2": + self.db_drop() + self.db_init() + self.db_insert_somethings() + print("Таблицы созданы заново!") + return "0" + elif next_step != "1" and next_step != "9": + print("Выбрано неверное число! Повторите ввод!") + return "0" + else: + return next_step + + def show_people(self): + self.person_id = -1 + menu = """Просмотр списка людей! +№\tФамилия\tИмя\tОтчество""" + print(menu) + lst = PeopleTable().all() + for i in lst: + print(str(i[1]) + "\t" + str(i[2]) + "\t" + str(i[0]) + "\t" + str(i[3])) + menu = """Дальнейшие операции: + 0 - возврат в главное меню; + 3 - добавление нового человека; + 4 - удаление человека; + 5 - просмотр телефонов человека; + 9 - выход.""" + print(menu) + return + + def after_show_people(self, next_step): + while True: + if next_step == "4": + print("Пока не реализовано!") + return "1" + elif next_step == "6" or next_step == "7": + print("Пока не реализовано!") + next_step = "5" + elif next_step == "5": + next_step = self.show_phones_by_people() + elif next_step != "0" and next_step != "9" and next_step != "3": + print("Выбрано неверное число! Повторите ввод!") + return "1" + else: + return next_step + + def show_add_person(self): + # Не реализована проверка на максимальную длину строк. Нужно доделать самостоятельно! + data = [] + data.append(input("Введите имя (1 - отмена): ").strip()) + if data[0] == "1": + return + while len(data[0].strip()) == 0: + data[0] = input("Имя не может быть пустым! Введите имя заново (1 - отмена):").strip() + if data[0] == "1": + return + data.append(input("Введите фамилию (1 - отмена): ").strip()) + if data[1] == "1": + return + while len(data[1].strip()) == 0: + data[1] = input("Фамилия не может быть пустой! Введите фамилию заново (1 - отмена):").strip() + if data[1] == "1": + return + data.append(input("Введите отчество (1 - отмена):").strip()) + if data[2] == "1": + return + PeopleTable().insert_one(data) + return + + def show_phones_by_people(self): + if self.person_id == -1: + while True: + num = input("Укажите номер строки, в которой записана интересующая Вас персона (0 - отмена):") + while len(num.strip()) == 0: + num = input("Пустая строка. Повторите ввод! Укажите номер строки, в которой записана интересующая Вас персона (0 - отмена):") + if num == "0": + return "1" + person = PeopleTable().find_by_position(int(num)) + if not person: + print("Введено число, неудовлетворяющее количеству людей!") + else: + self.person_id = int(person[1]) + self.person_obj = person + break + print("Выбран человек: " + self.person_obj[2] + " " + self.person_obj[0] + " " + self.person_obj[3]) + print("Телефоны:") + lst = PhonesTable().all_by_person_id(self.person_id) + for i in lst: + print(i[1]) + menu = """Дальнейшие операции: + 0 - возврат в главное меню; + 1 - возврат в просмотр людей; + 6 - добавление нового телефона; + 7 - удаление телефона; + 9 - выход.""" + print(menu) + return self.read_next_step() + + return self.read_next_step() + + def main_cycle(self): + current_menu = "0" + next_step = None + while(current_menu != "9"): + if current_menu == "0": + self.show_main_menu() + next_step = self.read_next_step() + current_menu = self.after_main_menu(next_step) + elif current_menu == "1": + self.show_people() + next_step = self.read_next_step() + current_menu = self.after_show_people(next_step) + elif current_menu == "2": + self.show_main_menu() + elif current_menu == "3": + self.show_add_person() + current_menu = "1" + print("До свидания!") + return + + def test(self): + DbTable.dbconn.test() + +m = Main() +# Откоментируйте эту строку и закоментируйте следующую для теста +# соединения с БД +# m.test() +m.main_cycle() + diff --git a/default_project/project_config.py b/default_project/project_config.py new file mode 100644 index 0000000..2b451e5 --- /dev/null +++ b/default_project/project_config.py @@ -0,0 +1,21 @@ +# Загрузка настроек проекта (в данном случае только настроек соединения с БД) +# из файла config.yaml. +import yaml + +class ProjectConfig: + """Класс считывает базовые настройки из файла config.yaml""" + + def __init__(self): + with open('config.yaml') as f: + config = yaml.safe_load(f) + self.dbname = config['dbname'] + self.user = config['user'] + self.password = config['password'] + self.host = config['host'] + self.dbtableprefix = config['dbtableprefix'] + +# Этот метод запускается только, если запускать +# данный файл, а не подключать его. +if __name__ == "__main__": + x = ProjectConfig() + print(x.dbfilepath) diff --git a/default_project/tables/people_table.py b/default_project/tables/people_table.py new file mode 100644 index 0000000..d27e8ea --- /dev/null +++ b/default_project/tables/people_table.py @@ -0,0 +1,23 @@ +# Таблица персоны и особые действия с ней + +from dbtable import * + +class PeopleTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "people" + + def columns(self): + return {"id": ["serial", "PRIMARY KEY"], + "last_name": ["varchar(32)", "NOT NULL"], + "first_name": ["varchar(32)", "NOT NULL"], + "second_name": ["varchar(32)"]} + + def find_by_position(self, num): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + sql += " LIMIT 1 OFFSET %(offset)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {"offset": num - 1}) + return cur.fetchone() + diff --git a/default_project/tables/phones_table.py b/default_project/tables/phones_table.py new file mode 100644 index 0000000..c6326f0 --- /dev/null +++ b/default_project/tables/phones_table.py @@ -0,0 +1,27 @@ +# Таблица Телефоны и особые действия с ней. + +from dbtable import * + +class PhonesTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "phones" + + def columns(self): + return {"person_id": ["integer", "REFERENCES people(id)"], + "phone": ["varchar(12)", "NOT NULL"]} + + def primary_key(self): + return ['person_id', 'phone'] + + def table_constraints(self): + return ["PRIMARY KEY(person_id, phone)"] + + def all_by_person_id(self, pid): + sql = "SELECT * FROM " + self.table_name() + sql += " WHERE person_id = %s" + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql, str(pid)) + return cur.fetchall() + diff --git a/main.py b/main.py index 1cf95c4..3018d97 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,10 @@ +import add_func import sys sys.path.append('tables') from project_config import * from dbconnection import * + # from tables.people_table import * # from tables.phones_table import * from tables.dish_table import * @@ -87,12 +89,14 @@ class Main: def show_cath(self): self.cath_id = -1 menu = """Просмотр списка категорий! -№\tНазвание\n------------------------""" +№\tНазвание\n-------------------------------------------------------------------------------------""" print(menu) lst = CathTable().all() + j = 1 for i in lst: - print(str(i[1]) + "\t" + str(i[0])) - menu = """------------------------\nДальнейшие операции: + print(str(j) + "\t" + str(i[0])) + j += 1 + menu = """-------------------------------------------------------------------------------------\nДальнейшие операции: 0 - возврат в главное меню; 3 - добавление новой категории; 4 - удаление категории; @@ -102,12 +106,35 @@ class Main: return def after_show_cath(self, next_step): + """Выбор действий после вывода категорий + """ while True: if next_step == "4": - CathTable().delete(input('Введите название удаляемой категории: ')) + CathTable().delete(input('Введите название удаляемой категории(1 - для отмены): ')) return "1" - elif next_step == "6" or next_step == "7": - print("Пока не реализовано!") + + elif next_step == "6": #Добавление блюда в категорию + DishTable().insert_dishone(self.cath_id) + next_step = "5" + + elif next_step == "7":#Удаление блюда из категории + del_name = input('Введите название удаляемого блюда (1 - для отмены): ') + while (del_name.strip() == '')or(len(del_name.strip()) > 32)or(add_func.is_cyr_or_dig(del_name.strip())==0): + if(del_name.strip() == ''): + del_name = input("Пустая строка. Повторите ввод! Укажите название удаляемого блюда (0 - отмена): ") + if del_name == "0": + return "1" + elif(len(del_name.strip()) > 32): + del_name = input("Слишком длинная строка. Повторите ввод!\ + Укажите название удаляемого блюда (0 - отмена): ") + if del_name == "0": + return "1" + elif(add_func.is_cyr_or_dig(del_name.strip())==0): + del_name = input("Название должно состоять только из символов кириллицы. Повторите ввод!\ + Укажите название удаляемого блюда (0 - отмена): ") + if del_name == "0": + return "1" + DishTable().delete(del_name) next_step = "5" elif next_step == "5": next_step = self.show_dish_in_cath() @@ -118,43 +145,69 @@ class Main: return next_step def add_cath(self): + """ + Добавление новой категории в таблицу + """ data = [] data.append(input("Введите название (1 - отмена): ").strip()) if data[0] == "1": return - while (len(data[0].strip()) == 0)or(len(data[0].strip()) > 32): + while((len(data[0].strip()) == 0)or(len(data[0].strip()) > 32)or(add_func.is_cyr_or_dig(data[0].strip())==0)): if (len(data[0].strip()) > 32): data[0] = input("Название слишком длинное! Введите название заново (1 - отмена):").strip() if data[0] == "1": return + elif add_func.is_cyr_or_dig(data[0].strip())==0: + data[0] = input("Название должно состоять только из символов кириллицы!\ + Введите название заново (1 - отмена):").strip() + if data[0] == "1": + return else: data[0] = input("Название не может быть пустым! Введите название заново (1 - отмена):").strip() if data[0] == "1": return - CathTable().insert_one(data) + CathTable().insert_one(data) return def show_dish_in_cath(self): + """Вывод всех блюд в выбранной пользователем категории + """ if self.cath_id == -1: while True: name = input("Укажите название категории для вывода блюд (0 - отмена):") - while len(name.strip()) == '': - name = input("Пустая строка. Повторите ввод! Укажите название категории для вывода блюд (0 - отмена):") - if name == "0": - return "1" - cath = CathTable().find_by_name(name) - if not cath: + while (name.strip() == '')or(len(name.strip()) > 32)or(add_func.is_cyr_or_dig(name.strip())==0): + if(name.strip() == ''): + name = input("Пустая строка. Повторите ввод! Укажите название категории для вывода блюд (0 - отмена):") + if name == "0": + return "1" + elif(len(name.strip()) > 32): + name = input("Сликшом длинная строка. Повторите ввод!\ + Укажите название категории для вывода блюд (0 - отмена):") + if name == "0": + return "1" + elif(add_func.is_cyr_or_dig(name.strip())==0): + name = input("Название должно состоять только из символов кириллицы. Повторите ввод!\ + Укажите название категории для вывода блюд (0 - отмена):") + if name == "0": + return "1" + flag, cath = CathTable().find_by_name(name) + print(flag) + if flag == 0: print("Введено неверное название!") else: - self.cath_id = int(cath[1]) - self.cath_obj = cath + self.cath_id = cath + # self.cath_obj = cath break - print("Выбрана категория: " + self.cath_obj[1]) - print("Блюда:") - lst = DishTable().all_by_cath_id(self.cath_id) - for i in lst: - print(i[1]) - menu = """Дальнейшие операции: + print("Выбрана категория: " + name) + print("Блюда:") + print("№\tНазвание\tВремя приготовления\tКраткая инструкция\ + \n-------------------------------------------------------------------------------------") + lst = DishTable().all_by_cath_id(cath) + j = 1 + for i in lst: + print(str(j) + "\t" + i[2] + "\t\t" + str(i[1]) + "\t\t\t" + str(i[4])) + j += 1 + menu = """-------------------------------------------------------------------------------------\nДальнейшие операции: 0 - возврат в главное меню; 1 - возврат в просмотр категорий; 6 - добавление нового блюда; @@ -164,22 +217,30 @@ class Main: return self.read_next_step() def main_cycle(self): + """Основной цикл программы, регулирующий порядок действий + """ current_menu = "0" next_step = None + while(current_menu != "9"): + if current_menu == "0": self.show_main_menu() next_step = self.read_next_step() current_menu = self.after_main_menu(next_step) + elif current_menu == "1": self.show_cath() next_step = self.read_next_step() current_menu = self.after_show_cath(next_step) + elif current_menu == "2": self.show_main_menu() + elif current_menu == "3": self.add_cath() current_menu = "1" + print("До свидания!") return diff --git a/tables/__pycache__/cath_table.cpython-311.pyc b/tables/__pycache__/cath_table.cpython-311.pyc index 8b568cb..2ab3c77 100644 Binary files a/tables/__pycache__/cath_table.cpython-311.pyc and b/tables/__pycache__/cath_table.cpython-311.pyc differ diff --git a/tables/__pycache__/dish_table.cpython-311.pyc b/tables/__pycache__/dish_table.cpython-311.pyc index f8401da..147aaaf 100644 Binary files a/tables/__pycache__/dish_table.cpython-311.pyc and b/tables/__pycache__/dish_table.cpython-311.pyc differ diff --git a/tables/cath_table.py b/tables/cath_table.py index 2b4e5b0..5aefaf2 100644 --- a/tables/cath_table.py +++ b/tables/cath_table.py @@ -15,23 +15,29 @@ class CathTable(DbTable): def delete(self, val): sql = "DELETE FROM " + self.table_name() - sql += " WHERE " + "".join(self.column_names_without_id()) + sql += " WHERE cath_name" sql += "=" + "'" + "".join(val) + "';" cur = self.dbconn.conn.cursor() cur.execute(sql) self.dbconn.conn.commit() def find_by_name(self, name): + flag = 0 cur = self.dbconn.conn.cursor() - sql_sel = "SELECT id FROM " + self.table_name() sql_sel += " WHERE cath_name = " + "'" + name + "'" + ";" - cur.execute(sql_sel) + cur.execute(sql_sel) + ret = cur.fetchone() + # print(ret) + if(ret != None): + flag = 1 + return [flag, list(ret)[0]] + else: + return [flag, list(ret)[0]] # sql = "SELECT * FROM " + self.table_name() # sql += " ORDER BY " # sql += ", ".join(self.primary_key()) # sql += " LIMIT 1 OFFSET %(offset)s" # cur.execute(sql, {"offset": num - 1}) - # print(cur) - return cur.fetchone() + # print(cur) diff --git a/tables/dish_table.py b/tables/dish_table.py index 6704b99..8a3850c 100644 --- a/tables/dish_table.py +++ b/tables/dish_table.py @@ -1,6 +1,7 @@ # Таблица с блюдами и действия с ними from dbtable import * +import add_func class DishTable(DbTable): def table_name(self): @@ -27,3 +28,75 @@ class DishTable(DbTable): cur.execute(sql, {"offset": num - 1}) return cur.fetchone() + def all_by_cath_id(self, cath_id): + sql = "SELECT * FROM " + self.table_name() + sql += " WHERE cath_id = " + str(cath_id) + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchall() + + def delete(self, val): + sql = "DELETE FROM dish" + sql += " WHERE dish_name" + sql += "=" + "'" + val + "';" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + + def check_by_name(self, value): + sql = f"SELECT * FROM {self.table_name()} WHERE dish_name='{value}'" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + result = cur.fetchone() + cur.close() + if result: + return True + else: + return False + + def insert_dishone(self, cath_id): + + ins_name = input('Введите название добавляемого блюда (1 - для отмены): ') + + while (ins_name.strip() == '')or(len(ins_name.strip()) > 32)\ + or(add_func.is_cyr_or_dig(ins_name.strip())==0)or(DishTable().check_by_name(ins_name)): + + if(ins_name.strip() == ''): + ins_name = input("Пустая строка. Повторите ввод! Укажите название удаляемого блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + elif(len(ins_name.strip()) > 32): + ins_name = input("Слишком длинная строка. Повторите ввод!\ + Укажите название удаляемого блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + elif(add_func.is_cyr_or_dig(ins_name.strip())==0): + ins_name = input("Название должно состоять только из символов кириллицы. Повторите ввод!\ + Укажите название удаляемого блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + else: + print('Такое блюдо уже существует') + ins_name = input("Повторите ввод! Укажите название блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + ins_time = input(f'Процесс добавления блюда: {ins_name}\ + \nВведите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') + if ins_time == "0": + return "1" + ins_manual = input(f'Процесс добавления блюда: {ins_name}\ + \nВведите краткую инструкцию приготовления блюда (1 - для отмены): ') + if ins_time == "0": + return "1" + + insert = [cath_id, ins_time, ins_name, ins_manual] + DishTable().insert_one(insert) + + + \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..159aed8 --- /dev/null +++ b/test.py @@ -0,0 +1,11 @@ +# import sys +# sys.path.append('tables') + +# from project_config import * +# from dbconnection import * +# # from tables.people_table import * +# # from tables.phones_table import * +# from tables.dish_table import * +# from tables.cath_table import * + +# cath = CathTable().find_by_name('За')