SQLAlchemy:数据库创建代码小于数据库
Posted
技术标签:
【中文标题】SQLAlchemy:数据库创建代码小于数据库【英文标题】:SQLAlchemy: database creation code smaller than database 【发布时间】:2016-03-07 11:06:54 【问题描述】:我有两个用于创建数据库的 python 文件:
一个包含所有的类声明,开头是这样的:
from sqlalchemy import create_engine, Column, Integer, String, Sequence, Table, ForeignKey, Float, DateTime, ForeignKeyConstraint
from sqlalchemy.orm import backref, relationship, sessionmaker
from os import path
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
genotype_association = Table('gt_association', Base.metadata,
Column('genotypes_id', Integer, ForeignKey('genotypes.id')),
Column('animals_id', Integer, ForeignKey('animals.id'))
)
treatment_association = Table('tr_association', Base.metadata,
Column('chronic_treatments_id', Integer, ForeignKey('chronic_treatments.id')),
Column('animals_id', Integer, ForeignKey('animals.id'))
)
substance_association = Table('st_association', Base.metadata,
Column('substance_administrations_id', Integer, ForeignKey('substance_administrations.id')),
Column('solutions_id', Integer, ForeignKey('solutions.id'))
)
operator_association = Table('op_association', Base.metadata,
Column('operator_id', Integer, ForeignKey('operators.id')),
Column('fmri_measurements_id', Integer, ForeignKey('fmri_measurements.id'))
)
ingredients_association = Table('ig_association', Base.metadata,
Column('solutions_id', Integer, ForeignKey('solutions.id')),
Column('ingredients_id', Integer, ForeignKey('ingredients.id'))
)
laser_association = Table('ls_association', Base.metadata,
Column('laser_stimulation_protocols_id', Integer, ForeignKey('laser_stimulation_protocols.id')),
Column('fmri_measurements_id', Integer, ForeignKey('fmri_measurements.id'))
)
#general classes:
class Operator(Base):
__tablename__ = "operators"
id = Column(Integer, primary_key=True)
code = Column(String, unique=True)
full_name = Column(String)
affiliation = Column(String)
class MeasurementUnit(Base):
__tablename__ = "measurement_units"
id = Column(Integer, primary_key=True)
code = Column(String, unique=True)
long_name = Column(String)
siunitx = Column(String)
class Ingredient(Base):
__tablename__ = "ingredients"
id = Column(Integer, primary_key=True)
code = Column(String, unique=True)
name = Column(String)
concentration = Column(Float, default=100)
concentration_unit_id = Column(String, ForeignKey('measurement_units.id'))
concentration_unit = relationship("MeasurementUnit")
supplier = Column(String)
supplier_id = Column(String)
contained = Column(Integer, ForeignKey("ingredients.id"))
contains = relationship("Ingredient")
class Solution(Base):
__tablename__ = "solutions"
id = Column(Integer, primary_key=True)
code = Column(String, unique=True)
name = Column(String)
supplier = Column(String)
supplier_id = Column(String)
contains = relationship("Ingredient", secondary=ingredients_association, backref="ingredient_of")
def __repr__(self):
return "<Solution(name='%s' (long_name='%s'), concentration=%s%s contains: %s)>"\
% (self.name, self.long_name, self.concentration, self.concentration_unit, self.contains)
另一个文件导入类,并创建一些条目,如下所示:
from sqlalchemy import create_engine, literal
from os import path
from common_classes import *
from sqlalchemy.orm import sessionmaker
from add import loadSession, commit_and_close, double_entry
from datetime import datetime
def initialize_main_entries(db_path):
session,engine = loadSession(db_path)
christ = Operator(code="Chr", full_name="Horea Christian", affiliation="ETH")
#Measurement Units
s = MeasurementUnit(code="s", long_name="second", siunitx="\\second")
session.add(s)
g = MeasurementUnit(code="g", long_name="gram", siunitx="\\gram")
hz = MeasurementUnit(code="Hz", long_name="hertz", siunitx="\\hertz")
session.add(hz)
percent = MeasurementUnit(code="%", long_name="percent", siunitx="\\percentt")
session.add(percent)
mi = MeasurementUnit(code="min", long_name="minute", siunitx="\\arcminute")
session.add(mi)
mg_l = MeasurementUnit(code="mg/l", long_name="milligram per litre", siunitx="\\milli\\gram\\per\\litre")
mg_ml = MeasurementUnit(code="mg/ml", long_name="milligram per millilitre", siunitx="\\milli\\gram\\per\\milli\\litre")
mul_g = MeasurementUnit(code="mul/g", long_name="microlitre per gram", siunitx="\\micro\\litre\\per\\gram")
#Ingredients
flu = Ingredient(name="Fluoxetine Hydrochloride", concentration="2.25", concentration_unit=mg_ml, supplier="Tocris")
med = Ingredient(name="Medetomidine", concentration=38.5, concentration_unit=mg_l, supplier="Provert AG, Orion Pharma", supplier_id="DOMITOR")
sal = Ingredient(name="Sodium Chloride", concentration=86.535, concentration_unit=mg_ml)
sal_flu = Ingredient(name="Sodium Chloride", concentration=997.75, concentration_unit=mg_ml)
iso_3 = Ingredient(name="Isoflurane", concentration=3, concentration_unit=percent, supplier="Piramal Healthcare")
iso_05 = Ingredient(name="Isoflurane", concentration=0.5, concentration_unit=percent, supplier="Piramal Healthcare")
air = Ingredient(name="Air", concentration=80, concentration_unit=percent)
oxy = Ingredient(name="Oxygen", concentration=20, concentration_unit=percent)
e_air_3 = Ingredient(name="Enriched Air", concentration=97, concentration_unit=percent, contains=[air, oxy])
e_air_05 = Ingredient(name="Enriched Air", concentration=99.5, concentration_unit=percent, contains=[air, oxy])
rnasea10 = Ingredient(name="RNase A", concentration=10, concentration_unit=mg_ml)
这些文件分别为 13KB 和 28KB - 而它们生成的数据库文件为 60KB。
这是意料之中的,还是表明我的数据库结构混乱了?
【问题讨论】:
你的.py源代码大小与数据库大小无关。 但是适合 28KB 的 python 源代码(包括所有的导入、函数调用、语法和 cmets)的信息怎么会占用 .db 格式的 60KB 呢?如果有的话,我希望 .db 能够更好地利用空间。 @Selzuk,我猜第二个文件的大小可能与数据库的大小成正比,但是数据库会保留更多的东西,比如元数据,所以对于小数据来说它肯定会更高。如果我错了,请纠正我。 数据库通常也声明了额外的空间,例如用于索引。这将显示为“已用空间”,但实际上仍未使用。原因是索引需要一些松弛空间来快速填充新条目。 每个数据库都有自己的数据存储方式,有的效率更高,有的效率不高。您可以通过示例了解更多关于 SQLite 文件结构的信息:sqlite.org/fileformat2.html 【参考方案1】:SQLite 数据库文件被组织成页面(默认页面大小可能为 4 KB),表或索引不能共享页面。 因此,每个数据库对象至少需要一页。
新行将能够使用这些页面中的可用空间,因此插入前几条记录不会增加数据库文件的大小。
【讨论】:
以上是关于SQLAlchemy:数据库创建代码小于数据库的主要内容,如果未能解决你的问题,请参考以下文章
from flask_sqlalchemy import SQLAlchemy 无法创建数据库表,代码无报错,代码如下,python版本是3.5