微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否可以更改表以在 python 的 datajoint 中包含对上游表的引用?

如何解决是否可以更改表以在 python 的 datajoint 中包含对上游表的引用?

我们想要修改一个表以包含对新表的非主键引用。旧的定义是:

@schema
class SpikeSortingParameters(dj.Manual):
    deFinition = """
    # Table for holding parameters for each spike sorting run
    -> SortGroup
    -> SpikeSorterParameters
    -> SortInterval
    ---
    -> SpikeSortingMetrics
    -> IntervalList
    import_path = '': varchar(200) # optional path to prevIoUs curated sorting output
    """

我们想添加

-> SpikeSortingArtifactParameters 

作为非主键,在我们花时间尝试让它工作之前,我们想知道是否有可能,因为我们不知道在此处分配认值的方法

提前致谢...

罗兰

解决方法

遗憾的是,table.alter() 目前不支持外键更新。有一个可以使用的变通方法,但有几个步骤,应该小心执行。最好将此作为功能请求提交到 issue tracker

使用改变

例如,考虑以下内容:

如果你有 2 个表定义如下:

import datajoint as dj

schema = dj.Schema('rguzman_alter_example')

@schema
class Student(dj.Lookup):
    definition = """
    student_first_name: varchar(30)
    student_last_name: varchar(30)
    ---
    student_location: varchar(30)
    """
    contents = [('Joe','Schmoe','Los Angeles,CA'),('Suzie','Queue','Miami,FL')]

@schema
class Assignment (dj.Lookup):
    definition = """
    assignment_id: int
    ---
    assignment_due_date: date
    #-> [nullable] Student # Standard way to define a foreign key on secondary attributes with NULL as default
    """
    contents = [dict(assignment_id=100,assignment_due_date='2021-04-21')]

现在假设您希望在二级属性上有一个外键,默认值为 NULL。您可以将选项传递给辅助属性中的外键(请参阅上面的注释,我们允许它默认为 NULL)。以这种方式从头开始初始化一个表工作得很好。对于我们想在使用现有数据初始化表后在辅助属性上添加外键的情况,Assignment.alter() 将是实现此目的的最佳方法,只要我们建立一个默认值来填充现有记录和。让我们看看当我们取消对辅助属性的外键的注释,重新定义 Assignment 表类并尝试更改时会发生什么。

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-23-09997168281c> in <module>
----> 1 Assignment.alter()

~/.local/lib/python3.7/site-packages/datajoint/table.py in alter(self,prompt,context)
     84             del frame
     85         old_definition = self.describe(context=context,printout=False)
---> 86         sql,external_stores = alter(self.definition,old_definition,context)
     87         if not sql:
     88             if prompt:

~/.local/lib/python3.7/site-packages/datajoint/declare.py in alter(definition,context)
    367         raise NotImplementedError('table.alter cannot alter the primary key (yet).')
    368     if foreign_key_sql != foreign_key_sql_:
--> 369         raise NotImplementedError('table.alter cannot alter foreign keys (yet).')
    370     if index_sql != index_sql_:
    371         raise NotImplementedError('table.alter cannot alter indexes (yet)')

NotImplementedError: table.alter cannot alter foreign keys (yet).

哦,有一个例外......所以事实证明它尚未针对此用例实现。但是,有一个可以利用的手动解决方法,所以让我详细说明这些步骤,直到获得支持为止。

解决方法

  1. 不是像上面那样在辅助属性上定义外键,而是这样定义:
    @schema
    class Assignment (dj.Lookup):
        definition = f"""
        assignment_id: int
        ---
        assignment_due_date: date
        {newline.join(['' + a.name + '=null: ' + a.type for a in Student.heading.attributes.values() if a.in_key])}
        """
        contents = [dict(assignment_id=100,assignment_due_date='2021-04-21')]
    
    这会将父表的主要属性“复制”到子表的次要属性中。
  2. 照常执行变更:Assignment.alter()
  3. 直接使用 SQL 查询手动添加外键。像这样:
    q = """
        ALTER TABLE {table}
        ADD FOREIGN KEY ({fk})
        REFERENCES {ref} ({pk})
        ON UPDATE CASCADE
        ON DELETE RESTRICT
        """.format(table=Assignment.full_table_name,fk=','.join([f'`{k}`' for k in Student.primary_key]),ref=f'`{Student.table_name}`',pk=','.join([f'`{k}`' for k in Student.primary_key]))
    dj.conn().query(q)
    
  4. 确保删除在步骤 1 中添加的部分,并用正确的规范替换它,即 -> [nullable] Student
  5. 重启你的内核
  6. 要验证是否已正确设置,请检查 Assignment.describe()。如果一切正常,结果应该是:
    assignment_id        : int                          
    ---
    assignment_due_date  : date                         
    -> [nullable] Student
    
    此外,任何预先存在的记录现在都应预先填充 NULL

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?