我正在做一個項目,我需要創建一個具有連接到數據庫並從中獲取數據(我使用SQLite作爲後端)的方法的類實例。 我已經有了一些flask-sqlalchemy的經驗,但是當談到純粹的SQLAlchemy時,我迷失了方向。 概念如下: 用戶創建DataSet
的實例,並將路徑作爲__init__
參數傳遞給數據庫。如果數據庫已經存在,我只想連接它並執行查詢,如果不存在,我想使用模型創建一個新的查詢。但我無法理解如何去做。從類訪問SQLalchemy
這裏的DataSet
代碼:
from os.path import normcase, split, join, isfile
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import errors
import trainset
import testset
class DataSet:
def __init__(self, path_to_set, path_to_db, train_set=False, path_to_labels=None, label_dict=None,
custom_name=None):
self.__path_to_set = path_to_set
self.__label_dict = label_dict
if custom_name is None:
dbpath = join(path_to_db, 'train.db')
if train_set is False:
dbpath = join(path_to_db, 'test.db')
else:
dbpath = join(path_to_db, custom_name)
if isfile(dbpath):
self.__prepopulated = True
else:
self.__prepopulated = False
self.__dbpath = dbpath
if train_set is True and path_to_labels is None:
raise errors.InsufficientData('labels', 'specified')
if train_set is True and not isfile(path_to_labels):
raise errors.InsufficientData('labels', 'found at specified path', path_to_labels)
def prepopulate(self):
engine = create_engine('sqlite:////' + self.__dbpath)
self.__prepopulated = True
這裏的trainset
代碼:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, PickleType, Integer, MetaData
Base = declarative_base()
metadata = MetaData()
class TrainSet(Base):
__tablename__ = 'train set'
id = Column(Integer, primary_key=True)
real_id = Column(String(60))
path = Column(String(120))
labels = Column(PickleType)
features = Column(PickleType)
這裏的testset
代碼:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, PickleType, Integer, MetaData
Base = declarative_base()
metadata = MetaData()
class TestSet(Base):
__tablename__ = 'test set'
id = Column(Integer, primary_key=True)
real_id = Column(String(60))
path = Column(String(120))
features = Column(PickleType)
因此,如果用戶創建時通過train_set=True
DataSet
ins我想創建一個使用TrainSet
模型的數據庫,否則創建一個TestSet
數據庫。我希望在prepopulate
方法中發生這種情況,但是,我不明白該怎麼做 - 文檔調用了這個:Base.metadata.create_all(engine)
,但我失去了將代碼放在哪裏。
太好了,謝謝!我只需要將'testset.Base.create_all(引擎)'改成'testset.Base.metadata.create_all(引擎)'(同樣適用於'train set'),但它現在都可以工作。 此外,由於我將編寫很多查詢內容的函數,因此將引擎存儲在類實例中是一個好主意嗎? (而不是在每個類方法中創建它)? –
我不會在任何模型類中存儲引擎,因爲您會將錯誤的東西混合在一起,並會以一種更奇怪的方式將所有東西混合在一起(*模型*不應該知道有關*連接的任何信息*)。相反,在類方法中使用['object_session(self)'](http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#sqlalchemy.orm.session.object_session)來獲取會話( a-la'transaction')並根據需要查詢其他數據。 – van