ebird-api-data 0.1.1__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/PKG-INFO +1 -1
  2. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/pyproject.toml +2 -2
  3. ebird_api_data-0.2.0/src/ebird/api/data/__init__.py +1 -0
  4. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/loaders.py +24 -10
  5. ebird_api_data-0.2.0/src/ebird/api/data/migrations/0002_convert_foreign_keys_to_integers.py +103 -0
  6. ebird_api_data-0.2.0/src/ebird/api/data/migrations/0003_make_codes_and_identifiers_primary_keys.py +93 -0
  7. ebird_api_data-0.2.0/src/ebird/api/data/migrations/0004_rename_foreign_keys.py +103 -0
  8. ebird_api_data-0.2.0/src/ebird/api/data/migrations/0005_add_new_foreign_keys.py +104 -0
  9. ebird_api_data-0.2.0/src/ebird/api/data/migrations/0006_set_new_foreign_keys.py +266 -0
  10. ebird_api_data-0.2.0/src/ebird/api/data/migrations/0007_remove_old_fields_and_ids.py +188 -0
  11. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/checklist.py +3 -2
  12. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/country.py +1 -1
  13. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/county.py +1 -1
  14. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/location.py +3 -2
  15. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/observation.py +3 -2
  16. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/observer.py +3 -1
  17. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/species.py +3 -2
  18. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/state.py +2 -2
  19. ebird_api_data-0.1.1/src/ebird/api/data/__init__.py +0 -1
  20. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/.gitignore +0 -0
  21. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/LICENSE +0 -0
  22. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/README.rst +0 -0
  23. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/admin.py +0 -0
  24. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/apps.py +0 -0
  25. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/fields.py +0 -0
  26. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/locale/en/LC_MESSAGES/django.mo +0 -0
  27. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/locale/en/LC_MESSAGES/django.po +0 -0
  28. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/management/__init__.py +0 -0
  29. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/management/commands/__init__.py +0 -0
  30. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/management/commands/add_checklists.py +0 -0
  31. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/migrations/0001_initial.py +0 -0
  32. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/migrations/__init__.py +0 -0
  33. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/__init__.py +0 -0
  34. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/models/filter.py +0 -0
  35. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/templates/admin/data/species/change_list_object_tools.html +0 -0
  36. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/templates/admin/data/species/fetch_species.html +0 -0
  37. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/templates/data/widgets/translation_field.html +0 -0
  38. {ebird_api_data-0.1.1 → ebird_api_data-0.2.0}/src/ebird/api/data/widgets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ebird-api-data
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: eBird API Data is a reusable Django app for loading data from eBird into a database.
5
5
  Author-email: Stuart MacKay <smackay@flagstonesoftware.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ebird-api-data"
3
- version = "0.1.1"
3
+ version = "0.2.0"
4
4
  description = "eBird API Data is a reusable Django app for loading data from eBird into a database."
5
5
  keywords = ["checklists", "observations", "species", "Django", "eBird", "models"]
6
6
  license = "MIT"
@@ -64,7 +64,7 @@ dev-dependencies = [
64
64
  ]
65
65
 
66
66
  [tool.bumpversion]
67
- current_version = "0.1.1"
67
+ current_version = "0.2.0"
68
68
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
69
69
  serialize = ["{major}.{minor}.{patch}"]
70
70
  ignore_missing_version = false
@@ -0,0 +1 @@
1
+ __version__ = "0.2.0"
@@ -303,19 +303,33 @@ class APILoader:
303
303
 
304
304
  def get_observer(self, data: dict) -> Observer:
305
305
  name: str = data.get("userDisplayName", "Anonymous eBirder")
306
- observer, created = Observer.objects.get_or_create(
307
- original=name, defaults={"name": name}
308
- )
309
- if observer.multiple:
306
+ is_multiple = Observer.objects.filter(original=name, multiple=True).exists()
307
+ if is_multiple:
308
+ identifier = self.get_observer_identifier(data)
310
309
  observer, created = Observer.objects.get_or_create(
311
- identifier=self.get_observer_identifier(data),
312
- defaults={"original": random_word(8), "name": name},
310
+ identifier=identifier,
311
+ defaults={
312
+ "name":name,
313
+ "original": random_word(8)
314
+ }
313
315
  )
314
- elif observer.identifier == "":
315
- observer.identifier = self.get_observer_identifier(data)
316
- observer.save()
316
+ else:
317
+ if observer := Observer.objects.filter(original=name).first():
318
+ created = False
319
+ else:
320
+ identifier = self.get_observer_identifier(data)
321
+ observer = Observer.objects.create(
322
+ identifier=identifier,
323
+ name=name,
324
+ original=name,
325
+ )
326
+ created = True
327
+
317
328
  if created:
318
- logger.info("Added observer: %s", observer.name)
329
+ logger.info("Added observer: %s", name)
330
+ if Observer.objects.filter(original=name).count() > 1:
331
+ logger.error("Multiple observers exist with same name: %s", name)
332
+
319
333
  return observer
320
334
 
321
335
  def add_checklist(self, identifier: str) -> Checklist | None:
@@ -0,0 +1,103 @@
1
+ # Generated by Django 5.2.4 on 2025-07-14 09:34
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('data', '0001_initial'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='checklist',
15
+ name='country',
16
+ field=models.IntegerField(),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='checklist',
20
+ name='county',
21
+ field=models.IntegerField(null=True),
22
+ ),
23
+ migrations.AlterField(
24
+ model_name='checklist',
25
+ name='location',
26
+ field=models.IntegerField(),
27
+ ),
28
+ migrations.AlterField(
29
+ model_name='checklist',
30
+ name='observer',
31
+ field=models.IntegerField(),
32
+ ),
33
+ migrations.AlterField(
34
+ model_name='checklist',
35
+ name='state',
36
+ field=models.IntegerField(),
37
+ ),
38
+ migrations.AlterField(
39
+ model_name='filter',
40
+ name='location',
41
+ field=models.IntegerField(null=True),
42
+ ),
43
+ migrations.AlterField(
44
+ model_name='filter',
45
+ name='species',
46
+ field=models.IntegerField(),
47
+ ),
48
+ migrations.AlterField(
49
+ model_name='filter',
50
+ name='update_species',
51
+ field=models.IntegerField(),
52
+ ),
53
+ migrations.AlterField(
54
+ model_name='location',
55
+ name='country',
56
+ field=models.IntegerField(),
57
+ ),
58
+ migrations.AlterField(
59
+ model_name='location',
60
+ name='county',
61
+ field=models.IntegerField(null=True),
62
+ ),
63
+ migrations.AlterField(
64
+ model_name='location',
65
+ name='state',
66
+ field=models.IntegerField(),
67
+ ),
68
+ migrations.AlterField(
69
+ model_name='observation',
70
+ name='checklist',
71
+ field=models.IntegerField(),
72
+ ),
73
+ migrations.AlterField(
74
+ model_name='observation',
75
+ name='country',
76
+ field=models.IntegerField(),
77
+ ),
78
+ migrations.AlterField(
79
+ model_name='observation',
80
+ name='county',
81
+ field=models.IntegerField(null=True),
82
+ ),
83
+ migrations.AlterField(
84
+ model_name='observation',
85
+ name='location',
86
+ field=models.IntegerField(),
87
+ ),
88
+ migrations.AlterField(
89
+ model_name='observation',
90
+ name='observer',
91
+ field=models.IntegerField(),
92
+ ),
93
+ migrations.AlterField(
94
+ model_name='observation',
95
+ name='species',
96
+ field=models.IntegerField(),
97
+ ),
98
+ migrations.AlterField(
99
+ model_name='observation',
100
+ name='state',
101
+ field=models.IntegerField(),
102
+ ),
103
+ ]
@@ -0,0 +1,93 @@
1
+ # Generated by Django 5.2.4 on 2025-07-14 09:49
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('data', '0002_convert_foreign_keys_to_integers'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='checklist',
15
+ name='id',
16
+ field=models.IntegerField(),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='country',
20
+ name='id',
21
+ field=models.IntegerField(),
22
+ ),
23
+ migrations.AlterField(
24
+ model_name='county',
25
+ name='id',
26
+ field=models.IntegerField(),
27
+ ),
28
+ migrations.AlterField(
29
+ model_name='location',
30
+ name='id',
31
+ field=models.IntegerField(),
32
+ ),
33
+ migrations.AlterField(
34
+ model_name='observation',
35
+ name='id',
36
+ field=models.IntegerField(),
37
+ ),
38
+ migrations.AlterField(
39
+ model_name='observer',
40
+ name='id',
41
+ field=models.IntegerField(),
42
+ ),
43
+ migrations.AlterField(
44
+ model_name='species',
45
+ name='id',
46
+ field=models.IntegerField(),
47
+ ),
48
+ migrations.AlterField(
49
+ model_name='state',
50
+ name='id',
51
+ field=models.IntegerField(),
52
+ ),
53
+ migrations.AlterField(
54
+ model_name='checklist',
55
+ name='identifier',
56
+ field=models.CharField(help_text='The unique identifier for the checklist.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier'),
57
+ ),
58
+ migrations.AlterField(
59
+ model_name='country',
60
+ name='code',
61
+ field=models.CharField(help_text='The code used to identify the country.', max_length=2, primary_key=True, serialize=False, verbose_name='code'),
62
+ ),
63
+ migrations.AlterField(
64
+ model_name='county',
65
+ name='code',
66
+ field=models.CharField(help_text='The code used to identify the county.', max_length=10, primary_key=True, serialize=False, verbose_name='code'),
67
+ ),
68
+ migrations.AlterField(
69
+ model_name='location',
70
+ name='identifier',
71
+ field=models.CharField(help_text='The unique identifier for the location.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier'),
72
+ ),
73
+ migrations.AlterField(
74
+ model_name='observation',
75
+ name='identifier',
76
+ field=models.CharField(help_text='A global unique identifier for the observation.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier'),
77
+ ),
78
+ migrations.AlterField(
79
+ model_name='observer',
80
+ name='identifier',
81
+ field=models.CharField(help_text='The code for the person submitted the checklist.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier'),
82
+ ),
83
+ migrations.AlterField(
84
+ model_name='species',
85
+ name='species_code',
86
+ field=models.CharField(help_text='The species code, e.g. ostric2, used in the eBird API.', max_length=10, primary_key=True, serialize=False, verbose_name='species code'),
87
+ ),
88
+ migrations.AlterField(
89
+ model_name='state',
90
+ name='code',
91
+ field=models.CharField(help_text='The code used to identify the state.', max_length=6, primary_key=True, serialize=False, verbose_name='code'),
92
+ ),
93
+ ]
@@ -0,0 +1,103 @@
1
+ # Generated by Django 5.2.4 on 2025-07-14 09:59
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('data', '0003_make_codes_and_identifiers_primary_keys'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.RenameField(
14
+ model_name='checklist',
15
+ old_name='country',
16
+ new_name='country_old',
17
+ ),
18
+ migrations.RenameField(
19
+ model_name='checklist',
20
+ old_name='county',
21
+ new_name='county_old',
22
+ ),
23
+ migrations.RenameField(
24
+ model_name='checklist',
25
+ old_name='location',
26
+ new_name='location_old',
27
+ ),
28
+ migrations.RenameField(
29
+ model_name='checklist',
30
+ old_name='observer',
31
+ new_name='observer_old',
32
+ ),
33
+ migrations.RenameField(
34
+ model_name='checklist',
35
+ old_name='state',
36
+ new_name='state_old',
37
+ ),
38
+ migrations.RenameField(
39
+ model_name='filter',
40
+ old_name='location',
41
+ new_name='location_old',
42
+ ),
43
+ migrations.RenameField(
44
+ model_name='filter',
45
+ old_name='species',
46
+ new_name='species_old',
47
+ ),
48
+ migrations.RenameField(
49
+ model_name='filter',
50
+ old_name='update_species',
51
+ new_name='update_species_old',
52
+ ),
53
+ migrations.RenameField(
54
+ model_name='location',
55
+ old_name='country',
56
+ new_name='country_old',
57
+ ),
58
+ migrations.RenameField(
59
+ model_name='location',
60
+ old_name='county',
61
+ new_name='county_old',
62
+ ),
63
+ migrations.RenameField(
64
+ model_name='location',
65
+ old_name='state',
66
+ new_name='state_old',
67
+ ),
68
+ migrations.RenameField(
69
+ model_name='observation',
70
+ old_name='checklist',
71
+ new_name='checklist_old',
72
+ ),
73
+ migrations.RenameField(
74
+ model_name='observation',
75
+ old_name='country',
76
+ new_name='country_old',
77
+ ),
78
+ migrations.RenameField(
79
+ model_name='observation',
80
+ old_name='county',
81
+ new_name='county_old',
82
+ ),
83
+ migrations.RenameField(
84
+ model_name='observation',
85
+ old_name='location',
86
+ new_name='location_old',
87
+ ),
88
+ migrations.RenameField(
89
+ model_name='observation',
90
+ old_name='observer',
91
+ new_name='observer_old',
92
+ ),
93
+ migrations.RenameField(
94
+ model_name='observation',
95
+ old_name='species',
96
+ new_name='species_old',
97
+ ),
98
+ migrations.RenameField(
99
+ model_name='observation',
100
+ old_name='state',
101
+ new_name='state_old',
102
+ ),
103
+ ]
@@ -0,0 +1,104 @@
1
+ # Generated by Django 5.2.4 on 2025-07-14 10:06
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('data', '0004_rename_foreign_keys'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AddField(
15
+ model_name='checklist',
16
+ name='country',
17
+ field=models.ForeignKey(help_text='The country where the checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.country', verbose_name='country'),
18
+ ),
19
+ migrations.AddField(
20
+ model_name='checklist',
21
+ name='county',
22
+ field=models.ForeignKey(blank=True, help_text='The county where the checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.county', verbose_name='county'),
23
+ ),
24
+ migrations.AddField(
25
+ model_name='checklist',
26
+ name='location',
27
+ field=models.ForeignKey(help_text='The location where checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.location', verbose_name='location'),
28
+ ),
29
+ migrations.AddField(
30
+ model_name='checklist',
31
+ name='observer',
32
+ field=models.ForeignKey(help_text='The person who submitted the checklist.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.observer', verbose_name='observer'),
33
+ ),
34
+ migrations.AddField(
35
+ model_name='checklist',
36
+ name='state',
37
+ field=models.ForeignKey(help_text='The state where the checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.state', verbose_name='state'),
38
+ ),
39
+ migrations.AddField(
40
+ model_name='filter',
41
+ name='location',
42
+ field=models.ForeignKey(blank=True, help_text='The location used to find matching Observations.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='filtered_on', to='data.location', verbose_name='location'),
43
+ ),
44
+ migrations.AddField(
45
+ model_name='filter',
46
+ name='species',
47
+ field=models.ForeignKey(help_text='The species used to find matching Observations.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='filtered_on', to='data.species', verbose_name='species'),
48
+ ),
49
+ migrations.AddField(
50
+ model_name='filter',
51
+ name='update_species',
52
+ field=models.ForeignKey(help_text='Matching Observations are updated to this species.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='filtered_by', to='data.species', verbose_name='update species'),
53
+ ),
54
+ migrations.AddField(
55
+ model_name='location',
56
+ name='country',
57
+ field=models.ForeignKey(help_text='The country for the location.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.country', verbose_name='country'),
58
+ ),
59
+ migrations.AddField(
60
+ model_name='location',
61
+ name='county',
62
+ field=models.ForeignKey(blank=True, help_text='The county for the location.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.county', verbose_name='county'),
63
+ ),
64
+ migrations.AddField(
65
+ model_name='location',
66
+ name='state',
67
+ field=models.ForeignKey(help_text='The state for the location.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.state', verbose_name='state'),
68
+ ),
69
+ migrations.AddField(
70
+ model_name='observation',
71
+ name='checklist',
72
+ field=models.ForeignKey(help_text='The checklist this observation belongs to.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='observations', to='data.checklist', verbose_name='checklist'),
73
+ ),
74
+ migrations.AddField(
75
+ model_name='observation',
76
+ name='country',
77
+ field=models.ForeignKey(help_text='The country where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.country', verbose_name='country'),
78
+ ),
79
+ migrations.AddField(
80
+ model_name='observation',
81
+ name='county',
82
+ field=models.ForeignKey(blank=True, help_text='The county where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.county', verbose_name='county'),
83
+ ),
84
+ migrations.AddField(
85
+ model_name='observation',
86
+ name='location',
87
+ field=models.ForeignKey(help_text='The location where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.location', verbose_name='location'),
88
+ ),
89
+ migrations.AddField(
90
+ model_name='observation',
91
+ name='observer',
92
+ field=models.ForeignKey(help_text='The person who made the observation.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.observer', verbose_name='observer'),
93
+ ),
94
+ migrations.AddField(
95
+ model_name='observation',
96
+ name='species',
97
+ field=models.ForeignKey(help_text='The identified species.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.species', verbose_name='species'),
98
+ ),
99
+ migrations.AddField(
100
+ model_name='observation',
101
+ name='state',
102
+ field=models.ForeignKey(help_text='The state where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.state', verbose_name='state'),
103
+ ),
104
+ ]
@@ -0,0 +1,266 @@
1
+ # Generated by Django 5.2.4 on 2025-07-14 10:06
2
+
3
+ import django.db.models.deletion
4
+ from django.db import connection, migrations, models
5
+
6
+
7
+ def update_location_country(apps, schema_editor):
8
+ with connection.cursor() as cursor:
9
+ cursor.execute(
10
+ "UPDATE data_location "
11
+ "SET country_id = data_country.code "
12
+ "FROM data_country "
13
+ "WHERE data_location.country_old = data_country.id"
14
+ )
15
+
16
+
17
+ def update_location_state(apps, schema_editor):
18
+ with connection.cursor() as cursor:
19
+ cursor.execute(
20
+ "UPDATE data_location "
21
+ "SET state_id = data_state.code "
22
+ "FROM data_state "
23
+ "WHERE data_location.state_old = data_state.id"
24
+ )
25
+
26
+
27
+ def update_location_county(apps, schema_editor):
28
+ with connection.cursor() as cursor:
29
+ cursor.execute(
30
+ "UPDATE data_location "
31
+ "SET county_id = data_county.code "
32
+ "FROM data_county "
33
+ "WHERE data_location.county_old = data_county.id"
34
+ )
35
+
36
+
37
+ def update_checklist_country(apps, schema_editor):
38
+ with connection.cursor() as cursor:
39
+ cursor.execute(
40
+ "UPDATE data_checklist "
41
+ "SET country_id = data_country.code "
42
+ "FROM data_country "
43
+ "WHERE data_checklist.country_old = data_country.id"
44
+ )
45
+
46
+
47
+ def update_checklist_state(apps, schema_editor):
48
+ with connection.cursor() as cursor:
49
+ cursor.execute(
50
+ "UPDATE data_checklist "
51
+ "SET state_id = data_state.code "
52
+ "FROM data_state "
53
+ "WHERE data_checklist.state_old = data_state.id"
54
+ )
55
+
56
+
57
+ def update_checklist_county(apps, schema_editor):
58
+ with connection.cursor() as cursor:
59
+ cursor.execute(
60
+ "UPDATE data_checklist "
61
+ "SET county_id = data_county.code "
62
+ "FROM data_county "
63
+ "WHERE data_checklist.county_old = data_county.id"
64
+ )
65
+
66
+
67
+ def update_checklist_location(apps, schema_editor):
68
+ with connection.cursor() as cursor:
69
+ cursor.execute(
70
+ "UPDATE data_checklist "
71
+ "SET location_id = data_location.identifier "
72
+ "FROM data_location "
73
+ "WHERE data_checklist.location_old = data_location.id"
74
+ )
75
+
76
+
77
+ def update_checklist_observer(apps, schema_editor):
78
+ with connection.cursor() as cursor:
79
+ cursor.execute(
80
+ "UPDATE data_checklist "
81
+ "SET observer_id = data_observer.identifier "
82
+ "FROM data_observer "
83
+ "WHERE data_checklist.observer_old = data_observer.id"
84
+ )
85
+
86
+
87
+ def update_observation_country(apps, schema_editor):
88
+ with connection.cursor() as cursor:
89
+ cursor.execute(
90
+ "UPDATE data_observation "
91
+ "SET country_id = data_country.code "
92
+ "FROM data_country "
93
+ "WHERE data_observation.country_old = data_country.id"
94
+ )
95
+
96
+
97
+ def update_observation_state(apps, schema_editor):
98
+ with connection.cursor() as cursor:
99
+ cursor.execute(
100
+ "UPDATE data_observation "
101
+ "SET state_id = data_state.code "
102
+ "FROM data_state "
103
+ "WHERE data_observation.state_old = data_state.id"
104
+ )
105
+
106
+
107
+ def update_observation_county(apps, schema_editor):
108
+ with connection.cursor() as cursor:
109
+ cursor.execute(
110
+ "UPDATE data_observation "
111
+ "SET county_id = data_county.code "
112
+ "FROM data_county "
113
+ "WHERE data_observation.county_old = data_county.id"
114
+ )
115
+
116
+
117
+ def update_observation_location(apps, schema_editor):
118
+ with connection.cursor() as cursor:
119
+ cursor.execute(
120
+ "UPDATE data_observation "
121
+ "SET location_id = data_location.identifier "
122
+ "FROM data_location "
123
+ "WHERE data_observation.location_old = data_location.id"
124
+ )
125
+
126
+
127
+ def update_observation_observer(apps, schema_editor):
128
+ with connection.cursor() as cursor:
129
+ cursor.execute(
130
+ "UPDATE data_observation "
131
+ "SET observer_id = data_observer.identifier "
132
+ "FROM data_observer "
133
+ "WHERE data_observation.observer_old = data_observer.id"
134
+ )
135
+
136
+
137
+ def update_observation_checklist(apps, schema_editor):
138
+ with connection.cursor() as cursor:
139
+ cursor.execute(
140
+ "UPDATE data_observation "
141
+ "SET checklist_id = data_checklist.identifier "
142
+ "FROM data_checklist "
143
+ "WHERE data_observation.checklist_old = data_checklist.id"
144
+ )
145
+
146
+
147
+ def update_observation_species(apps, schema_editor):
148
+ with connection.cursor() as cursor:
149
+ cursor.execute(
150
+ "UPDATE data_observation "
151
+ "SET species_id = data_species.species_code "
152
+ "FROM data_species "
153
+ "WHERE data_observation.species_old = data_species.id"
154
+ )
155
+
156
+
157
+ def update_filter_species(apps, schema_editor):
158
+ with connection.cursor() as cursor:
159
+ cursor.execute(
160
+ "UPDATE data_filter "
161
+ "SET species_id = data_species.species_code "
162
+ "FROM data_species "
163
+ "WHERE data_filter.species_old = data_species.id"
164
+ )
165
+
166
+
167
+ def update_filter_location(apps, schema_editor):
168
+ with connection.cursor() as cursor:
169
+ cursor.execute(
170
+ "UPDATE data_filter "
171
+ "SET location_id = data_location.identifier "
172
+ "FROM data_location "
173
+ "WHERE data_filter.location_old = data_location.id"
174
+ )
175
+
176
+
177
+ def update_filter_update_species(apps, schema_editor):
178
+ with connection.cursor() as cursor:
179
+ cursor.execute(
180
+ "UPDATE data_filter "
181
+ "SET update_species_id = data_species.species_code "
182
+ "FROM data_species "
183
+ "WHERE data_filter.update_species_old = data_species.id"
184
+ )
185
+
186
+
187
+ class Migration(migrations.Migration):
188
+
189
+ dependencies = [
190
+ ('data', '0005_add_new_foreign_keys'),
191
+ ]
192
+
193
+ operations = [
194
+ migrations.RunPython(
195
+ update_location_country,
196
+ reverse_code=migrations.RunPython.noop
197
+ ),
198
+ migrations.RunPython(
199
+ update_location_state,
200
+ reverse_code=migrations.RunPython.noop
201
+ ),
202
+ migrations.RunPython(
203
+ update_location_county,
204
+ reverse_code=migrations.RunPython.noop
205
+ ),
206
+ migrations.RunPython(
207
+ update_checklist_country,
208
+ reverse_code=migrations.RunPython.noop
209
+ ),
210
+ migrations.RunPython(
211
+ update_checklist_state,
212
+ reverse_code=migrations.RunPython.noop
213
+ ),
214
+ migrations.RunPython(
215
+ update_checklist_county,
216
+ reverse_code=migrations.RunPython.noop
217
+ ),
218
+ migrations.RunPython(
219
+ update_checklist_location,
220
+ reverse_code=migrations.RunPython.noop
221
+ ),
222
+ migrations.RunPython(
223
+ update_checklist_observer,
224
+ reverse_code=migrations.RunPython.noop
225
+ ),
226
+ migrations.RunPython(
227
+ update_observation_country,
228
+ reverse_code=migrations.RunPython.noop
229
+ ),
230
+ migrations.RunPython(
231
+ update_observation_state,
232
+ reverse_code=migrations.RunPython.noop
233
+ ),
234
+ migrations.RunPython(
235
+ update_observation_county,
236
+ reverse_code=migrations.RunPython.noop
237
+ ),
238
+ migrations.RunPython(
239
+ update_observation_location,
240
+ reverse_code=migrations.RunPython.noop
241
+ ),
242
+ migrations.RunPython(
243
+ update_observation_observer,
244
+ reverse_code=migrations.RunPython.noop
245
+ ),
246
+ migrations.RunPython(
247
+ update_observation_checklist,
248
+ reverse_code=migrations.RunPython.noop
249
+ ),
250
+ migrations.RunPython(
251
+ update_observation_species,
252
+ reverse_code=migrations.RunPython.noop
253
+ ),
254
+ migrations.RunPython(
255
+ update_filter_species,
256
+ reverse_code=migrations.RunPython.noop
257
+ ),
258
+ migrations.RunPython(
259
+ update_filter_location,
260
+ reverse_code=migrations.RunPython.noop
261
+ ),
262
+ migrations.RunPython(
263
+ update_filter_update_species,
264
+ reverse_code=migrations.RunPython.noop
265
+ ),
266
+ ]
@@ -0,0 +1,188 @@
1
+ # Generated by Django 5.2.4 on 2025-07-14 10:34
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('data', '0006_set_new_foreign_keys'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.RemoveField(
15
+ model_name='checklist',
16
+ name='country_old',
17
+ ),
18
+ migrations.RemoveField(
19
+ model_name='checklist',
20
+ name='county_old',
21
+ ),
22
+ migrations.RemoveField(
23
+ model_name='checklist',
24
+ name='id',
25
+ ),
26
+ migrations.RemoveField(
27
+ model_name='checklist',
28
+ name='location_old',
29
+ ),
30
+ migrations.RemoveField(
31
+ model_name='checklist',
32
+ name='observer_old',
33
+ ),
34
+ migrations.RemoveField(
35
+ model_name='checklist',
36
+ name='state_old',
37
+ ),
38
+ migrations.RemoveField(
39
+ model_name='country',
40
+ name='id',
41
+ ),
42
+ migrations.RemoveField(
43
+ model_name='county',
44
+ name='id',
45
+ ),
46
+ migrations.RemoveField(
47
+ model_name='filter',
48
+ name='location_old',
49
+ ),
50
+ migrations.RemoveField(
51
+ model_name='filter',
52
+ name='species_old',
53
+ ),
54
+ migrations.RemoveField(
55
+ model_name='filter',
56
+ name='update_species_old',
57
+ ),
58
+ migrations.RemoveField(
59
+ model_name='location',
60
+ name='country_old',
61
+ ),
62
+ migrations.RemoveField(
63
+ model_name='location',
64
+ name='county_old',
65
+ ),
66
+ migrations.RemoveField(
67
+ model_name='location',
68
+ name='id',
69
+ ),
70
+ migrations.RemoveField(
71
+ model_name='location',
72
+ name='state_old',
73
+ ),
74
+ migrations.RemoveField(
75
+ model_name='observation',
76
+ name='checklist_old',
77
+ ),
78
+ migrations.RemoveField(
79
+ model_name='observation',
80
+ name='country_old',
81
+ ),
82
+ migrations.RemoveField(
83
+ model_name='observation',
84
+ name='county_old',
85
+ ),
86
+ migrations.RemoveField(
87
+ model_name='observation',
88
+ name='id',
89
+ ),
90
+ migrations.RemoveField(
91
+ model_name='observation',
92
+ name='location_old',
93
+ ),
94
+ migrations.RemoveField(
95
+ model_name='observation',
96
+ name='observer_old',
97
+ ),
98
+ migrations.RemoveField(
99
+ model_name='observation',
100
+ name='species_old',
101
+ ),
102
+ migrations.RemoveField(
103
+ model_name='observation',
104
+ name='state_old',
105
+ ),
106
+ migrations.RemoveField(
107
+ model_name='observer',
108
+ name='id',
109
+ ),
110
+ migrations.RemoveField(
111
+ model_name='species',
112
+ name='id',
113
+ ),
114
+ migrations.RemoveField(
115
+ model_name='state',
116
+ name='id',
117
+ ),
118
+ migrations.AlterField(
119
+ model_name='checklist',
120
+ name='country',
121
+ field=models.ForeignKey(help_text='The country where the checklist was made.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.country', verbose_name='country'),
122
+ ),
123
+ migrations.AlterField(
124
+ model_name='checklist',
125
+ name='location',
126
+ field=models.ForeignKey(help_text='The location where checklist was made.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.location', verbose_name='location'),
127
+ ),
128
+ migrations.AlterField(
129
+ model_name='checklist',
130
+ name='observer',
131
+ field=models.ForeignKey(help_text='The person who submitted the checklist.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.observer', verbose_name='observer'),
132
+ ),
133
+ migrations.AlterField(
134
+ model_name='checklist',
135
+ name='state',
136
+ field=models.ForeignKey(help_text='The state where the checklist was made.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.state', verbose_name='state'),
137
+ ),
138
+ migrations.AlterField(
139
+ model_name='filter',
140
+ name='species',
141
+ field=models.ForeignKey(help_text='The species used to find matching Observations.', on_delete=django.db.models.deletion.CASCADE, related_name='filtered_on', to='data.species', verbose_name='species'),
142
+ ),
143
+ migrations.AlterField(
144
+ model_name='filter',
145
+ name='update_species',
146
+ field=models.ForeignKey(help_text='Matching Observations are updated to this species.', on_delete=django.db.models.deletion.CASCADE, related_name='filtered_by', to='data.species', verbose_name='update species'),
147
+ ),
148
+ migrations.AlterField(
149
+ model_name='location',
150
+ name='country',
151
+ field=models.ForeignKey(help_text='The country for the location.', on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.country', verbose_name='country'),
152
+ ),
153
+ migrations.AlterField(
154
+ model_name='location',
155
+ name='state',
156
+ field=models.ForeignKey(help_text='The state for the location.', on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.state', verbose_name='state'),
157
+ ),
158
+ migrations.AlterField(
159
+ model_name='observation',
160
+ name='checklist',
161
+ field=models.ForeignKey(help_text='The checklist this observation belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='observations', to='data.checklist', verbose_name='checklist'),
162
+ ),
163
+ migrations.AlterField(
164
+ model_name='observation',
165
+ name='country',
166
+ field=models.ForeignKey(help_text='The country where the observation was made.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.country', verbose_name='country'),
167
+ ),
168
+ migrations.AlterField(
169
+ model_name='observation',
170
+ name='location',
171
+ field=models.ForeignKey(help_text='The location where the observation was made.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.location', verbose_name='location'),
172
+ ),
173
+ migrations.AlterField(
174
+ model_name='observation',
175
+ name='observer',
176
+ field=models.ForeignKey(help_text='The person who made the observation.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.observer', verbose_name='observer'),
177
+ ),
178
+ migrations.AlterField(
179
+ model_name='observation',
180
+ name='species',
181
+ field=models.ForeignKey(help_text='The identified species.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.species', verbose_name='species'),
182
+ ),
183
+ migrations.AlterField(
184
+ model_name='observation',
185
+ name='state',
186
+ field=models.ForeignKey(help_text='The state where the observation was made.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.state', verbose_name='state'),
187
+ ),
188
+ ]
@@ -26,8 +26,9 @@ class Checklist(models.Model):
26
26
  verbose_name=_("published"),
27
27
  )
28
28
 
29
- identifier = models.TextField(
30
- unique=True,
29
+ identifier = models.CharField(
30
+ max_length=15,
31
+ primary_key=True,
31
32
  verbose_name=_("identifier"),
32
33
  help_text=_("The unique identifier for the checklist."),
33
34
  )
@@ -9,7 +9,7 @@ class Country(models.Model):
9
9
 
10
10
  code = models.CharField(
11
11
  max_length=2,
12
- db_index=True,
12
+ primary_key=True,
13
13
  verbose_name=_("code"),
14
14
  help_text=_("The code used to identify the country."),
15
15
  )
@@ -9,7 +9,7 @@ class County(models.Model):
9
9
 
10
10
  code = models.CharField(
11
11
  max_length=10,
12
- db_index=True,
12
+ primary_key=True,
13
13
  verbose_name=_("code"),
14
14
  help_text=_("The code used to identify the county."),
15
15
  )
@@ -64,8 +64,9 @@ class Location(models.Model):
64
64
  verbose_name = _("location")
65
65
  verbose_name_plural = _("locations")
66
66
 
67
- identifier = models.TextField(
68
- unique=True,
67
+ identifier = models.CharField(
68
+ max_length=15,
69
+ primary_key=True,
69
70
  verbose_name=_("identifier"),
70
71
  help_text=_("The unique identifier for the location."),
71
72
  )
@@ -28,8 +28,9 @@ class Observation(models.Model):
28
28
  verbose_name=_("published"),
29
29
  )
30
30
 
31
- identifier = models.TextField(
32
- unique=True,
31
+ identifier = models.CharField(
32
+ max_length=15,
33
+ primary_key=True,
33
34
  verbose_name=_("identifier"),
34
35
  help_text=_("A global unique identifier for the observation."),
35
36
  )
@@ -7,7 +7,9 @@ class Observer(models.Model):
7
7
  verbose_name = _("observer")
8
8
  verbose_name_plural = _("observers")
9
9
 
10
- identifier = models.TextField(
10
+ identifier = models.CharField(
11
+ max_length=15,
12
+ primary_key=True,
11
13
  verbose_name=_("identifier"),
12
14
  help_text=_("The code for the person submitted the checklist."),
13
15
  )
@@ -44,8 +44,9 @@ class Species(models.Model):
44
44
  help_text=_("The category from the eBird/Clements taxonomy."),
45
45
  )
46
46
 
47
- species_code = models.TextField(
48
- blank=True,
47
+ species_code = models.CharField(
48
+ max_length=10,
49
+ primary_key=True,
49
50
  verbose_name=_("species code"),
50
51
  help_text=_("The species code, e.g. ostric2, used in the eBird API."),
51
52
  )
@@ -8,8 +8,8 @@ class State(models.Model):
8
8
  verbose_name_plural = _("states")
9
9
 
10
10
  code = models.CharField(
11
- max_length=10,
12
- db_index=True,
11
+ max_length=6,
12
+ primary_key=True,
13
13
  verbose_name=_("code"),
14
14
  help_text=_("The code used to identify the state."),
15
15
  )
@@ -1 +0,0 @@
1
- __version__ = "0.1.1"
File without changes