Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在SQLAlchemy中声明和初始化查找表数据? 动机_Python_Enums_Sqlalchemy - Fatal编程技术网

Python 如何在SQLAlchemy中声明和初始化查找表数据? 动机

Python 如何在SQLAlchemy中声明和初始化查找表数据? 动机,python,enums,sqlalchemy,Python,Enums,Sqlalchemy,举一个简单的例子,其中一列数据需要用SQL中的枚举类型表示: +------------------------------------------+ | user | +----+------+-----+------------------------+ | id | name | age | relationship_status_id | +----+------+-----+--------------------

举一个简单的例子,其中一列数据需要用SQL中的枚举类型表示:

+------------------------------------------+
| user                                     |
+----+------+-----+------------------------+
| id | name | age | relationship_status_id |
+----+------+-----+------------------------+
| 1  | John | 27  | 3                      |
| 2  | Mary | 77  | 1                      |
| 3  | Jack | 40  | 4                      |
+----+------+-----+------------------------+

+---------------------+
| relationship_status |
+----+----------------+
| id | name           |
+----+----------------+
| 1  | married        |
| 2  | widowed        |
| 3  | single         |
| 4  | divorced       |
+----+----------------+
在SQLAlchemy中定义(声明)表本身相对简单:

from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)
    relationship_status_id = Column(Integer, ForeignKey('relationship_status.id'))


class RelationshipStatus(Base):
    __tablename__ = 'relationship_status'

    id = Column(Integer, primary_key=True)
    name = Column(String)
初始化数据库时,可以使用
Base.metadata.create\u all(引擎)
指令创建表。
user
表将在应用程序的运行生命周期内填写;但是,
relationship\u status
lookup表的数据保持不变,似乎应该将此数据与表定义一起“声明”

然而,将数据持久化到表中自然需要一个
会话
,并且与表定义本身不同,SQLAlchemy似乎没有为给定表中的“预期行”提供任何声明性构造(自然地,因为任何应用程序中的大多数表都类似于带有动态数据的
用户

问题 使用SQLAlchemy,如何在应用程序运行时之前声明查找表的模式和数据?理想情况下,解决方案将涉及创建一些类似枚举的构造,其中包含应用程序其他部分可以引用的数据

研究 炼金术的创造者提出。这种解决方案唯一明显的缺点是必须依赖所使用的DBMS中的
enum
数据类型。对于这个问题的范围,首选独立于DBMS的查找表解决方案。

SQLAlchemy的创建者也提出了一个相关的替代方案是。这样的实现确保了查找表查询返回的行没有重复,但是仍然需要一个
会话
对象来进行任何声明或请求——模糊了数据库定义和实现之间的关注点分离。此外,客户机都只需要“只知道”要请求什么行,而不是(在Python中)使用某种枚举作为参考



问题的根源可能是概念性的,而不是SQLAlchemy或Python。无论是哪种情况,任何建议都将不胜感激

首先,我认为在大多数情况下,应用程序开发时已知的恒定数据通常不适合存储在数据库中。我将使用基于DBMS的枚举或基于Python的枚举以及检查约束来保证users表中的每一行都具有有效的关系状态。 既然你说你不打算这么做,听起来你在寻找一种方法,在创建关系状态表时触发一些插入。 我已经习惯于在表格中插入一些东西,而不是改变表格。您应该能够调整此设置以插入关系状态值

from sqlalchemy import event
from sqlalchemy import Table, Column, Metadata, Integer

m = MetaData()
some_table = Table('some_table', m, Column('data', Integer))

def after_create(target, connection, **kw):
    connection.execute("insert into  %s values ('1','single');" %
                            (target.name))

event.listen(some_table, "after_create", after_create)

您可以使用:
connection.execute(table(target.name).insert().values([{'name':'single'},…])
完全避免字符串格式设置,这也允许将初始值定义为python结构,而不是内联到SQL查询。感谢您在创建
触发器之后参考
;这似乎是最合适的解决办法。我对你提到的这种数据不适合存储在数据库中的说法很感兴趣,我倾向于同意。但是,由于基于DBMS的枚举在各个系统之间不一致,对于上述情况,有什么替代方案?我的印象是查找表是公认的最佳实践。如何使用python枚举实现检查约束?