天道酬勤,学无止境

SQLAlchemy Custom Type Which Contains Multiple Columns

I would like to represent a datatype as a single column in my model, but really the data will be stored in multiple columns in the database. I cannot find any good resources on how to do this in SQLAlchemy.

I would like my model to look like this(this is a simplified example using geometry instead of my real problem which is harder to explain):

class 3DLine(DeclarativeBase):
    start_point = Column(my.custom.3DPoint)
    end_point = Column(my.custom.3DPoint)

This way I could assign an object with the (x, y, z) components of the point at once without setting them individually. If I had to separate each component, this could get ugly, especially if each class has several of these composite objects. I would combine the values into one encoded field except that I need to query each value separately at times.

I was able to find out how to make custom types using a single column in the documentation. But there's no indication that I can map a single type to multiple columns.

I suppose I could accomplish this by using a separate table, and each column would be a foreign key, but in my case I don't think it makes sense to have a one to one mapping for each point to a separate table, and this still does not give the ability to set the related values all at once.

评论

Here is a minimal example based on documentation:

class 3DPoint(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

     def __composite_values__(self):
        return (self.x, self.y, self.z)

class 3DLine(DeclarativeBase):
    start_point = sqlalchemy.orm.composite(
        3DPoint,
        Column('start_point_x', Integer, nullable=False),
        Column('start_point_y', Integer, nullable=False),
        Column('start_point_z', Integer, nullable=False),
    )

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何使用 SQLAlchemy 将一个类映射到多个表?(How to map one class against multiple tables with SQLAlchemy?)
    问题 假设我有一个包含三个表的数据库结构,如下所示: items - item_id - item_handle attributes - attribute_id - attribute_name item_attributes - item_attribute_id - item_id - attribute_id - attribute_value 我希望能够在 SQLAlchemy 中做到这一点: item = Item('item1') item.foo = 'bar' session.add(item) session.commit() item1 = session.query(Item).filter_by(handle='item1').one() print item1.foo # => 'bar' 我是 SQLAlchemy 的新手,我在文档 (http://www.sqlalchemy.org/docs/05/mappers.html#mapping-a-class-against-multiple-tables) 中找到了这个: j = join(items, item_attributes, items.c.item_id == item_attributes.c.item_id). \ join(attributes, item_attributes
  • sqlalchemy在多列中是唯一的(sqlalchemy unique across multiple columns)
    问题 假设我有一个代表位置的类。 位置“属于”客户。 位置由Unicode 10个字符代码标识。 对于特定客户,“位置代码”在位置之间应该是唯一的。 The two below fields in combination should be unique customer_id = Column(Integer,ForeignKey('customers.customer_id') location_code = Column(Unicode(10)) 因此,如果我有两个客户,客户“ 123”和客户“ 456”。 它们都可以有一个称为“ main”的位置,但都不能有两个称为main的位置。 我可以在业务逻辑中处理此问题,但是我想确保没有办法轻松地在sqlalchemy中添加需求。 unique = True选项似乎仅在应用于特定字段时才起作用,这将导致整个表仅对所有位置具有唯一代码。 回答1 从Column文档中摘录: unique –为True时,指示此列包含唯一约束,或者,如果index也为True,则指示应使用唯一标志创建索引。 要在约束/索引中指定多个列或指定一个显式名称,请显式使用UniqueConstraint或Index构造。 由于这些属于表而不属于映射的类,因此可以在表定义中声明它们,或者在__table_args__使用声明性声明时: # version1
  • sqlalchemy 在多列中是唯一的(sqlalchemy unique across multiple columns)
    问题 假设我有一个表示位置的类。 位置“属于”客户。 位置由 unicode 10 字符代码标识。 “位置代码”在特定客户的位置中应该是唯一的。 The two below fields in combination should be unique customer_id = Column(Integer,ForeignKey('customers.customer_id') location_code = Column(Unicode(10)) 因此,如果我有两个客户,客户“123”和客户“456”。 它们都可以有一个名为“main”的位置,但都不能有两个名为 main 的位置。 我可以在业务逻辑中处理这个问题,但我想确保没有办法在 sqlalchemy 中轻松添加需求。 unique=True 选项似乎只在应用于特定字段时才有效,它会导致整个表只有所有位置的唯一代码。 回答1 摘自Column的文档: unique – 当为 True 时,表示此列包含唯一约束,或者如果index也是 True,则表示应使用唯一标志创建索引。 要在约束/索引中指定多个列或指定显式名称,请显式使用 UniqueConstraint 或 Index 构造。 由于这些属于表而不是映射的类,因此可以在表定义中声明它们,或者如果使用声明性的__table_args__ : # version1
  • Multiple columns index when using the declarative ORM extension of sqlalchemy
    According to the documentation and the comments in the sqlalchemy.Column class, we should use the class sqlalchemy.schema.Index to specify an index that contains multiple columns. However, the example shows how to do it by directly using the Table object like this: meta = MetaData() mytable = Table('mytable', meta, # an indexed column, with index "ix_mytable_col1" Column('col1', Integer, index=True), # a uniquely indexed column with index "ix_mytable_col2" Column('col2', Integer, index=True, unique=True), Column('col3', Integer), Column('col4', Integer), Column('col5', Integer), Column('col6'
  • 在 SQLAlchemy 中创建混合属性的自定义元类(Custom metaclass to create hybrid properties in SQLAlchemy)
    问题 我想在 SQLAlchemy 之上创建一个自定义界面,以便透明地支持一些预定义的混合属性。 具体来说,我想创建一个类SpecialColumn和一个元类,以便当用户添加SpecialColumn作为类的属性时,我的自定义元类用两个 SQLAlchemy Column替换该属性并添加一个混合属性来获取和设置这两列作为一个元组。 到目前为止,这是我的方法: 首先,我定义了我的特殊列类型: class SpecialColumn(object): pass 然后,我定义了一个继承自 DeclarativeMeta 的元类,它扫描类中的SpecialColumn实例并将它们替换为两个Column和一个混合属性(定义为闭包): class MyDeclarativeMeta(DeclarativeMeta): def __new__(cls, name, bases, attrs): for name, col in attrs.items(): if isinstance(col, SpecialColumn): # Replacing the column del attrs[name] col1_name = '_{0}_1'.format(name) col2_name = '_{0}_2'.format(name) attrs[col1_name] = Column(...)
  • Custom metaclass to create hybrid properties in SQLAlchemy
    I want to create a custom interface on top of SQLAlchemy so that some pre-defined hybrid properties are supported transparently. Specifically, I want to create a class SpecialColumn and a metaclass so that when a user adds SpecialColumn as an attribute of a class, my custom metaclass replaces that attribute with two SQLAlchemy Columns and adds a hybrid property that gets and sets those two columns as a tuple. Here's my approach so far: First, I defined my special column type: class SpecialColumn(object): pass Then, I defined a metaclass inheriting from DeclarativeMeta which scans the class for
  • 如何动态更改 SQLAlchemy 声明模型上的列类型?(How do I change column type on SQLAlchemy declarative model dynamically?)
    问题 我正在生产中运行 mysql,但想在内存数据库中的 sqlite 中运行一个简单的测试。 旧版 mysql db 的表中的列是 mysql 特定类型,这些列在声明性模型中声明(子类化 declarative_base)。 我想在不去 mysql 的情况下运行一些简单的测试,因此需要换出模型的列。 我该怎么做呢? 我试过写一个补丁程序/解补丁程序来换出我的模型中的表,但是当我运行一些测试时,我得到 OperationalError: (OperationalError) near ")": syntax error u'\nCREATE TABLE my_table (\n)\n\n' () 这让我认为我没有正确修补列。 有谁知道我怎么能做到这一点? 我究竟做错了什么? 目前,我创建新列并将全新的 Table 对象附加到__table__并保存旧表。 DB 已创建,create_all() 和 convert_columns 在 setUp 中运行。 drop_all() 和 revert_columns 在我的测试中的 tearDown 期间运行 mysql_sqlite_mapping = {INTEGER: Integer, MEDIUMINT: Integer, TEXT: text} def convert_columns(self, my_class
  • 使用原始 SQL 时在 SQLAlchemy 中反序列化 JSON(Deserializing JSON in SQLAlchemy when using raw SQL)
    问题 我有一个存储在文本列中的 JSON 表: import json from sqlalchemy import create_engine, Column, text, Integer, TEXT, TypeDecorator from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker engine = create_engine('sqlite:///:memory:') engine.execute("create table t (t_id int not null primary key, attrs text not null)") engine.execute("insert into t values (1, '{\"a\": 1, \"b\": 2}')") Session = sessionmaker(bind=engine) 我使用 SQLAlchemy 文档中“Marshal JSON Strings”下定义的自定义类型在 SQLAlchemy 中定义了到该表的映射: Base = declarative_base() # http://docs.sqlalchemy.org/en/rel_1_1/core/custom
  • SQLAlchemy中的VALUES子句(VALUES clause in SQLAlchemy)
    问题 有没有一种方法可以在SQLAlchemy中构建一个Query对象,它等效于: SELECT * FROM (VALUES (1, 2, 3)) AS sq; 根据我在文档中看到的内容, VALUES子句仅与INSERT一起使用。 回答1 插入中的“ VALUES”是标准SQL,独立的“ VALUES”关键字是Postgresql。 PGValues上有一份针对此的快速编译器配方(如果有一天我更改了维基,请在此处复制): from sqlalchemy import * from sqlalchemy.ext.compiler import compiles from sqlalchemy.sql.expression import FromClause from sqlalchemy.sql import table, column class values(FromClause): def __init__(self, *args): self.list = args def _populate_column_collection(self): self._columns.update( [("column%d" % i, column("column%d" % i)) for i in xrange(1, len(self.list[0]) + 1)] )
  • SQLAlchemy:查找数组列之间的差异(SQLAlchemy: Find difference between array columns)
    问题 我有一个名为UnitOfWork的表,它有 3 列cases_identified 、 cases_completed和cases_double_check ,所有这些都是 Postgresql 整数数组。 是否可以编写查询(或混合属性)来查找已识别但不在已完成或复核列中的案例? 这是我想出的,但 SQL 表达式不起作用: @hybrid_property def todo(self): return [x for x in self.cases_identified if x not in self.cases_completed and x not in self.cases_double_check] @todo.expression def todo(cls): return [x for x in cls.cases_identified if x not in cls.cases_completed and x not in cls.cases_double_check] 我在测试查询中遇到的错误是: test = Session.query(UnitOfWork.todo).first() NotImplementedError: Operator 'contains' is not supported on this expression 回答1 对于这个答案
  • 如何将查询结果映射到sqlalchemy中的自定义对象?(How to map the result from a query to a custom object in sqlalchemy?)
    问题 我正在寻找一种告诉sqlalchemy将某些表上的复杂查询映射到自定义类MyResult而不是默认RowProxy类的方法。 这是一个简单的工作示例 ''' create table foo(id integer, title text); create table bar(id integer, foo_id integer, name text); insert into foo values(0, 'null'); insert into foo values(1, 'eins'); insert into bar values(0,0, 'nullnull'); insert into bar values(1,0, 'einsnull'); insert into bar values(2,1, 'zweieins'); ''' 和以下代码: from sqlalchemy import * from itertools import imap db = create_engine('sqlite:///test.db') metadata = MetaData(db) class MyResult(object): def __init__(self, id, title, name): self.id = id self.title = title self
  • SQLAlchemy - 使用 DateTime 列查询以按月/日/年过滤(SQLAlchemy - Querying with DateTime columns to filter by month/day/year)
    问题 我正在构建一个涉及跟踪付款的 Flask 网站,但我遇到了一个问题,我似乎无法按日期过滤我的数据库模型之一。 例如,如果这是我的表的样子: payment_to, amount, due_date (a DateTime object) company A, 3000, 7-20-2018 comapny B, 3000, 7-21-2018 company C, 3000, 8-20-2018 我想过滤它,以便获得 7 月 20 日之后的所有行,或 8 月的所有行,等等。 我可以想到一种粗暴的方式来过滤所有付款,然后遍历列表以按月/年进行过滤,但我宁愿远离这些方法。 这是我的付款数据库模型: class Payment(db.Model, UserMixin): id = db.Column(db.Integer, unique = True, primary_key = True) payment_to = db.Column(db.String, nullable = False) amount = db.Column(db.Float, nullable = False) due_date = db.Column(db.DateTime, nullable = False, default = datetime.strftime(datetime.today(), "
  • SQLAlchemy 核心选择其中条件包含布尔表达式`is False`(SQLAlchemy Core select where condition contains boolean expression `is False`)
    问题 如何使用 SQLAlchemy 表达式语言选择带有 where 条件的列来检查布尔表达式。 例子: select([table]).\ where(and_(table.c.col1 == 'abc', table.c.is_num is False )) 这不会给出语法错误,但会错误地评估条件。 我不能使用 == False 这会导致错误。 SQLAlchemy 核心v.1.0.8 回答1 身份比较运算符不能在 Python 中重载,所以 table.c.is_num is False 比较Column对象和False的身份,由于它们显然不是同一个对象,因此计算结果为 False。 经过 我不能使用 == False 这会导致错误 您可能是说某些符合 PEP-8 的 Python linter 会给您一个警告。 根据 True 或 False 检查相等性仍然是有效的 Python,虽然在一般意义上是非 Python 的——但它在 SQLAlchemy 过滤器中确实有意义,并且在文档中使用。 例如: In [5]: t.c.bar == False Out[5]: <sqlalchemy.sql.elements.BinaryExpression object at 0x7fdc355a1da0> In [6]: print(_) foo.bar = false 但是
  • 具有函数的复合 UniqueConstraint(Compound UniqueConstraint with a function)
    问题 一个快速的 SQLAlchemy 问题... 我有一个带有属性“数字”和“日期”的“文档”类。 我需要确保同一年没有重复的数字,有没有办法在“数字+年份(日期)”上设置唯一约束? 我应该使用唯一索引吗? 我将如何声明功能部分? (SQLAlchemy 0.5.5,PostgreSQL 8.3.4) 提前致谢! 回答1 您应该使用功能唯一索引来应用此约束。 不幸的是,SQLAlchemy 中的数据库通用数据库独立模式定义机制还没有抽象功能索引。 您必须使用 DDL 构造来注册自定义架构定义子句。 如果您使用声明性方法来声明架构,请在类定义后添加以下内容: DDL( "CREATE UNIQUE INDEX doc_year_num_uniq ON %(fullname)s " "(EXTRACT(YEAR FROM date), number)" ).execute_at('after-create', Document.__table__) 这种方法工作得很好,但在 v0.7 中抛出了 SADeprecation 警告我成功使用的语法: from sqlalchemy import event event.listen(ModelObject.__table__, 'after_create', DDL("CREATE UNIQUE INDEX term_year ON %
  • 在 SQLAlchemy 列类型和 python 数据类型之间轻松转换?(Easy convert betwen SQLAlchemy column types and python data types?)
    问题 我正在寻找一种简单的 Python 方法来比较 SQLAlchemy 和基本类型中的列类型。 例如,如果我的列类型是任意长度的 VARCHAR,我想将其作为字符串读取。 我可以读取列类型,但是我不确定是否有一种简单的方法来验证它的基本类型......如果我可以使用类似“if isinstance(mycolumn, int)”这样的东西会很好 - 但我是新手到 python 并不确定这将如何工作。 这是我到目前为止所拥有的: from sqlalchemy import MetaData from sqlalchemy import create_engine, Column, Table engine = create_engine('mysql+mysqldb://user:pass@localhost:3306/mydb', pool_recycle=3600) meta = MetaData() meta.bind = engine meta.reflect() datatable = meta.tables['my_data_table'] [c.type for c in datatable.columns] 输出: [INTEGER(display_width=11), DATE(), VARCHAR(length=127), DOUBLE(precision
  • 来自 Python 的多行 UPSERT(插入或更新)(Multi-row UPSERT (INSERT or UPDATE) from Python)
    问题 我目前正在使用 python 执行下面的简单查询,使用 pyodbc 在 SQL 服务器表中插入数据: import pyodbc table_name = 'my_table' insert_values = [(1,2,3),(2,2,4),(3,4,5)] cnxn = pyodbc.connect(...) cursor = cnxn.cursor() cursor.execute( ' '.join([ 'insert into', table_name, 'values', ','.join( [str(i) for i in insert_values] ) ]) ) cursor.commit() 只要没有重复的键,这应该可以工作(假设第一列包含键)。 但是对于具有重复键的数据(表中已经存在的数据),它会引发错误。 我怎样才能一次性使用 pyodbc 在 SQL Server 表中插入多行,以便简单地更新具有重复键的数据。 注意:有针对单行数据提出的解决方案,但是,我想一次插入多行(避免循环)! 回答1 这可以使用MERGE来完成。 假设您有一个键列ID和两列col_a和col_b (您需要在更新语句中指定列名),那么该语句将如下所示: MERGE INTO MyTable as Target USING (SELECT * FROM (VALUES (1
  • 在 Sqlalchemy 中更新多列(Updating multiple columns in Sqlalchemy)
    问题 我有一个在 Flask 上运行并使用 sqlalchemy 与数据库交互的应用程序。 我想用用户指定的值更新表的列。 我正在使用的查询是 def update_table(value1, value2, value3): query = update(Table).where(Table.column1 == value1).values(Table.column2 = value2, Table.column3 = value3) 我不确定我传递值的方式是否正确。 还有 Table.column2/3 i=gives 错误说Can't assign to function call assignment Can't assign to function call 。 column2/3 不是函数,它们是字段名称。 那么,如何更新多个值以及为什么会在此处出错? PS:我参考了sqlalchemy doc 回答1 可以使用 Session 更新多个列: def update_table(session, val1, val2, val3): session.query(Table).filter_by(col=val1).update(dict(col2=val2,col3=val3)) session.commit() 回答2 您可以编写更通用的函数来接受您的表对象
  • Python-Sqlalchemy 二进制列类型 HEX() 和 UNHEX()(Python-Sqlalchemy Binary Column Type HEX() and UNHEX())
    问题 我正在尝试学习 Sqlalchemy 并使用 ORM。 我的一列将文件哈希存储为二进制文件。 在 SQL 中,选择只是 SELECT type, column FROM table WHERE hash = UNHEX('somehash') 如何使用我的 ORM 实现这样的选择(最好也有插入示例)? 我已经开始阅读有关列覆盖的内容,但我很困惑/不确定这真的是我所追求的。 例如res = session.query.filter(Model.hash == __something__? ) 想法? 回答1 仅用于选择和插入 好吧,对于选择,您可以使用: >>> from sqlalchemy import func >>> session = (...) >>> (...) >>> engine = create_engine('sqlite:///:memory:', echo=True) >>> q = session.query(Model.id).filter(Model.some == func.HEX('asd')) >>> print q.statement.compile(bind=engine) SELECT model.id FROM model WHERE model.some = HEX(?) 对于插入: >>> from sqlalchemy
  • Superset介绍及使用说明
    Superset介绍及使用说明 Superset简介 Apache Superset是Airbnb开源的数据挖掘平台。支持丰富的数据源连接,多种可视化方式,并能够对用户实现细粒度的权限控制。该工具主要特点是可自助分析、自定义仪表盘、分析结果可视化(导出)、用户/角色权限控制,还集成了一个SQL编辑器,可以进行SQL编辑查询等。 功能 丰富的数据可视化集 易于使用的界面,用于浏览和可视化数据 创建和共享仪表板 与主要身份验证提供程序(数据库,OpenID,LDAP,OAuth和REMOTE_USER通过Flask AppBuilder集成)集成的企业就绪身份验证 可扩展的高粒度安全性/权限模型,允许有关谁可以访问单个要素和数据集的复杂规则 一个简单的语义层,允许用户通过定义哪些字段应显示在哪个下拉列表中以及哪些聚合和功能度量可供用户使用来控制如何在UI中显示数据源 通过SQLAlchemy与大多数说SQL的RDBMS集成 与Druid.io的深度集成 支持的数据源 凡是有SqlAlchemy支持的数据源,superset都支持,包括下图: Amazon Athena Amazon Redshift Apache Drill Apache Druid Apache Hive Apache Impala Apache Kylin Apache Pinot
  • 如何将SqlAlchemy结果序列化为JSON?(How to serialize SqlAlchemy result to JSON?)
    问题 Django有一些很好的自动ORM模型从数据库返回到JSON格式的自动序列化。 如何将SQLAlchemy查询结果序列化为JSON格式? 我尝试了jsonpickle.encode但它对查询对象本身进行了编码。 我尝试了json.dumps(items)但它返回 TypeError: <Product('3', 'some name', 'some desc')> is not JSON serializable 将SQLAlchemy ORM对象序列化为JSON / XML真的很困难吗? 没有默认的序列化程序吗? 如今,序列化ORM查询结果是非常常见的任务。 我需要的只是返回SQLAlchemy查询结果的JSON或XML数据表示形式。 javascript datagird(JQGrid http://www.trirand.com/blog/)中需要使用JSON / XML格式的SQLAlchemy对象查询结果 回答1 平面实施 您可以使用以下方式: from sqlalchemy.ext.declarative import DeclarativeMeta class AlchemyEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj.__class__, DeclarativeMeta