Получение пустой базы данных sqlite и "(sqlite3.OperationalError) нет такой таблицы: ..:" при попытке добавить элемент - PullRequest
0 голосов
/ 15 мая 2018

Я написал общий модуль 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» для объекта таблицы без каких-либо ошибок. Таким образом, у меня есть правильные объекты таблицы под рукой, но они как-то не связаны с базой?

1 Ответ

0 голосов
/ 15 мая 2018

Для SQLite, по-видимому, импорт классов таблицы должен произойти до создания БД.

    # 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"])

(что делается через pydoc.locate, кстати) должно быть выполнено до вызова

        engine = sqlalchemy.create_engine("sqlite:///mySQlite.db")
        meta.BASE.metadata.create_all(engine)
        session = sessionmaker(bind=engine)
        self.session = session()

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...