Skip to content

When using JSONB with BlobColumn nullable, it doesn't accept null #3441

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wtomezaki opened this issue Jan 29, 2025 · 3 comments
Closed

When using JSONB with BlobColumn nullable, it doesn't accept null #3441

wtomezaki opened this issue Jan 29, 2025 · 3 comments

Comments

@wtomezaki
Copy link

wtomezaki commented Jan 29, 2025

I'm using the new JSONB column, but I want it to be nullable, and it seems that the converter doesn't accept "null"

Also, I'm using the develop branch files which contain the fix #3436

type 'Null' is not a subtype of type 'Uint8List' of 'fromDb'
#0      _DefaultJsonConverter.fromSql (package:drift/src/runtime/types/converters.dart:379:15)
@j.JsonSerializable()
class PropertyArea {
  final String propertyAreaId;
  final GeoJson? mapBoundaries;
  final double area;
  final int areaType;
  final String propertyId;
  final DateTime createdAt;

  PropertyArea(
    this.propertyAreaId,
    this.mapBoundaries,
    this.area,
    this.areaType,
    this.propertyId,
    this.createdAt,
  );

  factory PropertyArea.fromJson(Map<String, dynamic> json) => _$PropertyAreaFromJson(json);

  Map<String, dynamic> toJson() => _$PropertyAreaToJson(this);

  static JsonTypeConverter2<PropertyArea?, Uint8List?, Object?> binaryConverter = TypeConverter.jsonb(
    fromJson: (json) => PropertyArea.fromJson(json as Map<String, Object?>),
    toJson: (pref) => pref?.toJson(),
  );
}
class Properties extends Table {
  TextColumn get propertyId => text()();
  BlobColumn get propertyArea => blob().nullable().map(PropertyArea.binaryConverter)();

  @override
  Set<Column> get primaryKey => {propertyId};
}

Even if I try exactly like the documentation using:

  static JsonTypeConverter2<PropertyArea, Uint8List, Object?> binaryConverter = TypeConverter.jsonb(
    fromJson: (json) => PropertyArea.fromJson(json as Map<String, Object?>),
    toJson: (pref) => pref.toJson(),
  );

I get this error in the drift generated file:

The argument type 'JsonTypeConverter2<PropertyArea, Uint8List, Object?>' can't be assigned to the parameter type 'JsonTypeConverter2<PropertyArea, Uint8List, Object>'.
@simolus3
Copy link
Owner

I will take a look at this example, but the best way to apply type converters to nullable columns is to just make the converter non-nullable, e.g.

  static JsonTypeConverter2<PropertyArea, Uint8List, Object`> binaryConverter = TypeConverter.jsonb(
    fromJson: (json) => PropertyArea.fromJson(json as Map<String, Object?>),
    toJson: (pref) => pref.toJson(),
  );

If drift encounters such a type converter on a nullable column, it will implicitly add the .? and serialize nulls from and to nulls.

@wtomezaki
Copy link
Author

wtomezaki commented Jan 29, 2025

I've tried to use it like that, but it still gives me an error:

A value of type 'JsonTypeConverter2<PropertyArea, Uint8List, Object?>' can't be assigned to a variable of type 'JsonTypeConverter2<PropertyArea, Uint8List, Object>'.

The only way drift generates this:

  static JsonTypeConverter2<PropertyArea, Uint8List, Object?>
      $converterpropertyArea = PropertyArea.binaryConverter;
  static JsonTypeConverter2<PropertyArea?, Uint8List?, Object?>
      $converterpropertyArean =
      JsonTypeConverter2.asNullable($converterpropertyArea);

is using it like this:

  static JsonTypeConverter2<PropertyArea, Uint8List, Object?> binaryConverter = TypeConverter.jsonb(
    fromJson: (json) => PropertyArea.fromJson(json as Map<String, Object?>),
    toJson: (pref) => pref.toJson(),
  );

or else it never generates the "asNullable" part. But then it goes back to the error in the generated file

@simolus3
Copy link
Owner

Sorry, I didn't see that you tried the intended way in the issue description already. That problem should be fixed with 00e65cb.

The reason the first approach doesn't work is essentially a variance issue. TypeConverter.jsonb will always return a converter mapping to a non-nullable blob in SQL. But since Uint8List is a subtype of Uint8List? in Dart, you can assign that converter to an entirely nullable converter and get a runtime error. So the converter always expects an Uint8List but it's possible to make Dart believe that a Uint8List? is fine too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants