Я написал общий модуль dbhandler, который может запутывать контейнеры данных и загружать их в базу данных mySQL и не зависит от структуры БД. Теперь я хочу добавить значение по умолчанию или возможность помещать данные в базу данных sqlite. По структуре это связано с вопросом . Пакет выглядит так:
dbhandler\
dbhandler.py
models\
meta.py
default\
default_DB_map.py
default_DB.cfg
default.cfg - это файл конфигурации, который описывает базу данных для скрипта dbhandler. default_DB_map.py содержит карту для каждой таблицы БД, которая наследуется от BASE:
from sqlalchemy import BigInteger, Column, Integer, String, Float, DateTime
from sqlalchemy import Date, Enum
from ..meta import BASE
class db_info(BASE):
__tablename__ = "info"
id = Column(Integer, primary_key=True)
name = Column(String)
project = Column(String)
manufacturer = Column(String)
...
class db_probe(BASE):
__tablename__ = "probe"
probeid = Column(Integer, primary_key=True)
id = Column(Integer)
paraX = Column(String)
...
В meta.py я инициализирую объект Declarative_base:
from sqlalchemy.ext.declarative import declarative_base
BASE = declarative_base()
И, в конце концов, я импортирую BASE в dbhandler.py и создаю движок и сессию:
"DBHandler module"
...
import sqlalchemy
from sqlalchemy.orm import sessionmaker
from models import meta #pylint: disable=E0401
....
class DBHandler(object):
"""Database handling
Methods:
- get_dict: returns table row
- add_item: adds dict to DB table
- get_table_keys: gets list of all DB table keys
- get_values: returns all values of key in DB table
- check_for_value: checks if value is in DB table or not
- upload: uploads data container to DB
- get_dbt: returns DBTable object
"""
def __init__(self, db_cfg=None):
"""Load credentials, DB structure and name of DB map from cfg file,
create DB session. Create DBTable object to get table names of DB
from cfg file, import table classes and get name of primary keys.
Args:
- db_cfg (yaml) : contains infos about DB structure and location
of DB credentials.
Misc:
- cred = {"host" : "...",
"database" : "...",
"user" : "...",
"passwd" : "..."}
"""
...
db_cfg = self.load_cfg(db_cfg)
if db_cfg["engine"] == "sqlite":
engine = sqlalchemy.create_engine("sqlite:///mySQlite.db")
meta.BASE.metadata.create_all(engine)
session = sessionmaker(bind=engine)
self.session = session()
elif db_cfg["engine"] == "mysql+mysqlconnector":
cred = self.load_cred(db_cfg["credentials"])
engine = sqlalchemy.create_engine(db_cfg["engine"]
+ "://"
+ cred["user"] + ":"
+ cred["passwd"] + "@"
+ cred["host"] + ":"
+ "3306" + "/"
+ cred["database"])
session = sessionmaker(bind=engine)
self.session = session()
else:
self.log.warning("Unkown engine in DB cfg...")
# here I'm importing the table classes stated in the config file
self.dbt = DBTable(map_file=db_cfg["map"],
table_dict=db_cfg["tables"],
cr_dict=db_cfg["cross-reference"])
Я явно делаю что-то не так в абзаце "if db_cfg [" engine "] ==" sqlite ":", но я не могу понять, что именно. Скрипт прекрасно работает с движком mySQL. Когда я инициализирую объект dhandler, я получаю пустой файл mySQLite.db. Добавление чего-либо с этим сеансом приводит к "(sqlite3.OperationalError) нет такой таблицы: info ...". Однако я могу использовать что-то вроде «sqlalchemy.inspect» для объекта таблицы без каких-либо ошибок. Таким образом, у меня есть правильные объекты таблицы под рукой, но они как-то не связаны с базой?