得到空的sqlite DB和“(sqlite3.OperationalError)没有这样的表:..:”当试图添加项目时

时间:2018-05-15 14:00:27

标签: mysql database python-3.x sqlite sqlalchemy

我编写了一个通用的dbhandler模​​块,它可以纠缠数据容器并将它们上传到mySQL数据库,并且独立于数据库结构。现在我想添加一个默认值或将数据推送到sqlite DB的可能性。结构方面,这与此question有关。包看起来像这样:

dbhandler\
    dbhandler.py
    models\
       meta.py
       default\   
          default_DB_map.py 
          default_DB.cfg 

default.cfg是描述dbhandler脚本数据库的配置文件。 default_DB_map.py包含DB的每个表的映射,它继承自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()

最后,我在dbhandler.py中导入BASE并创建引擎和会话:

"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 :(得分:0)

对于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 btw完成)必须在

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

被调用。我认为这并不重要,因为我在开始时导入了BASE,因为它在使用不同的引擎时工作得很好。