(core) Fix imports into reference columns, and support two ways to import Numeric as a reference.

Summary:
- When importing into a Ref column, use lookupOne() formula for correct previews.
- When selecting columns to import into a Ref column, now a Numeric column like
  'Order' will produce two options: "Order" and "Order (as row ID)".
- Fixes exports to correct the formatting of visible columns. This addresses multiple bugs:
  1. Formatting wasn't used, e.g. a Ref showing a custom-formatted date was still presented as YYYY-MM-DD in CSVs.
  2. Ref showing a Numeric column was formatted as if a row ID (e.g. `Table1[1.5]`), which is very wrong.
- If importing into a table that doesn't have a primary view, don't switch page after import.

Refactorings:
- Generalize GenImporterView to be usable in more cases; removed near-duplicated logic from node side
- Some other refactoring in importing code.
- Fix field/column option selection in ValueParser
- Add NUM() helper to turn integer-valued floats into ints, useful for "as row ID" lookups.

Test Plan: Added test cases for imports into reference columns, updated Exports test fixtures.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3875
This commit is contained in:
Dmitry S
2023-04-25 17:11:25 -04:00
parent 7a12a8ef28
commit 65013331a3
17 changed files with 290 additions and 339 deletions

View File

@@ -5,10 +5,9 @@ from __future__ import absolute_import
import datetime
import math as _math
import operator
import os
import random
import uuid
from functools import reduce
from functools import reduce # pylint: disable=redefined-builtin
from six.moves import zip, xrange
import six
@@ -491,6 +490,25 @@ def MULTINOMIAL(value1, *more_values):
res *= COMBIN(s, v)
return res
def NUM(value):
"""
For a Python floating-point value that's actually an integer, returns a Python integer type.
Otherwise, returns the value unchanged. This is helpful sometimes when a value comes from a
Numeric Grist column (represented as floats), but when int values are actually expected.
>>> NUM(-17.0)
-17
>>> NUM(1.5)
1.5
>>> NUM(4)
4
>>> NUM("NA")
'NA'
"""
if isinstance(value, float) and value.is_integer():
return int(value)
return value
def ODD(value):
"""
Rounds a number up to the nearest odd integer.
@@ -869,10 +887,12 @@ def TRUNC(value, places=0):
def UUID():
"""
Generate a random UUID-formatted string identifier.
Since UUID() produces a different value each time it's called, it is best to use it in
[trigger formula](formulas.md#trigger-formulas) for new records.
This would only calculate UUID() once and freeze the calculated value. By contrast, a regular formula
may get recalculated any time the document is reloaded, producing a different value for UUID() each time.
This would only calculate UUID() once and freeze the calculated value. By contrast, a regular
formula may get recalculated any time the document is reloaded, producing a different value for
UUID() each time.
"""
try:
uid = uuid.uuid4()