Repository: dj-stripe/dj-stripe

Issue:
Webhook fails to create `Event` for `api_version` like `2018-08-23; orders_beta=v3` (too long for `max_length` constraint)
### Describe the bug

Receiving webhooks is failing, throwing a `django.db.utils.DataError: value too long for type character varying(15)` error when trying to create an Event.

Searching the issues in this repo reveals similar errors (#1211, #1296) and on their advice I looked for model fields with `max_length=15`.

The only field with this constraint is `Event.api_version`:

https://github.com/dj-stripe/dj-stripe/blob/b4b584a932f75c527adb403bab4dee5af318b316/djstripe/models/core.py#L1471-L1472

I checked the `WebhookTrigger` record and noted the api version in the request body was `2018-08-23; orders_beta=v3`, which is 26 characters. This API version has beta/preview Stripe features enabled, hence the additional bits at the end.

Seems to me that this character limit wants to be thrown out the window. I'm going to have to fork this library to make this patch for my project.

### To Reproduce

Create an `Event` object with `api_version="2018-08-23; orders_beta=v3"`.

### Software versions
- Dj-Stripe version: [`2.6.1`](https://github.com/dj-stripe/dj-stripe/tree/stable/2.6)
- Python version: `3.9.12`
- Django version: `4.0.4`
- Stripe API version: `2018-08-23; orders_beta=v3`
- Database type and version: Postgres `14.2`

### Full error log

```
Traceback (most recent call last):
File "/app/.venv/lib/python3.9/site-packages/djstripe/models/base.py", line 583, in _create_from_stripe_object
instance = cls.stripe_objects.get(id=id_)
File "/app/.venv/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/app/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 496, in get
raise self.model.DoesNotExist(
djstripe.models.core.Event.DoesNotExist: Event matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/app/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.StringDataRightTruncation: value too long for type character varying(15)


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/app/.venv/lib/python3.9/site-packages/djstripe/models/webhooks.py", line 203, in from_request
obj.process(save=False)
File "/app/.venv/lib/python3.9/site-packages/djstripe/models/webhooks.py", line 294, in process
self.event = Event.process(self.json_body)
File "/app/.venv/lib/python3.9/site-packages/djstripe/models/core.py", line 1524, in process
ret = cls._create_from_stripe_object(data)
File "/app/.venv/lib/python3.9/site-packages/djstripe/models/base.py", line 596, in _create_from_stripe_object
instance.save()
File "/app/.venv/lib/python3.9/site-packages/django/db/models/base.py", line 806, in save
self.save_base(
File "/app/.venv/lib/python3.9/site-packages/django/db/models/base.py", line 857, in save_base
updated = self._save_table(
File "/app/.venv/lib/python3.9/site-packages/django/db/models/base.py", line 1000, in _save_table
results = self._do_insert(
File "/app/.venv/lib/python3.9/site-packages/django/db/models/base.py", line 1041, in _do_insert
return manager._insert(
File "/app/.venv/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/app/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 1434, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/app/.venv/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1621, in execute_sql
cursor.execute(sql, params)
File "/app/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(
File "/app/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/app/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "/app/.venv/lib/python3.9/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/app/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
django.db.utils.DataError: value too long for type character varying(15)
```



Discussion:

Resolving patch:
diff --git a/djstripe/migrations/0011_alter_event_api_version.py b/djstripe/migrations/0011_alter_event_api_version.py
new file mode 100644
--- /dev/null
+++ b/djstripe/migrations/0011_alter_event_api_version.py
@@ -0,0 +1,31 @@
+# Generated by Django 4.0.1 on 2022-01-12 13:12
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("djstripe", "0010_alter_customer_balance"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="event",
+            name="api_version",
+            field=models.CharField(
+                blank=True,
+                help_text="the API version at which the event data was rendered. Blank for old entries only, all new entries will have this value",
+                max_length=64,
+            ),
+        ),
+        migrations.AlterField(
+            model_name="webhookendpoint",
+            name="api_version",
+            field=models.CharField(
+                max_length=64,
+                blank=True,
+                help_text="The API version events are rendered as for this webhook endpoint.",
+            ),
+        ),
+    ]
diff --git a/djstripe/models/core.py b/djstripe/models/core.py
--- a/djstripe/models/core.py
+++ b/djstripe/models/core.py
@@ -1469,7 +1469,7 @@ class Event(StripeModel):
     stripe_dashboard_item_name = "events"
 
     api_version = models.CharField(
-        max_length=15,
+        max_length=64,
         blank=True,
         help_text="the API version at which the event data was "
         "rendered. Blank for old entries only, all new entries will have this value",
diff --git a/djstripe/models/webhooks.py b/djstripe/models/webhooks.py
--- a/djstripe/models/webhooks.py
+++ b/djstripe/models/webhooks.py
@@ -25,7 +25,7 @@ class WebhookEndpoint(StripeModel):
     stripe_class = stripe.WebhookEndpoint
 
     api_version = models.CharField(
-        max_length=10,
+        max_length=64,
         blank=True,
         help_text="The API version events are rendered as for this webhook endpoint.",
     )


Test patch:
diff --git a/tests/__init__.py b/tests/__init__.py
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -2012,7 +2012,7 @@ class WebhookEndpointDict(StripeItem):
 FAKE_EVENT_CUSTOMER_CREATED = {
     "id": "evt_38DHch3whaDvKYlo2CT2oe5ff3",
     "object": "event",
-    "api_version": "2016-03-07",
+    "api_version": "2016-03-07; orders_beta=v3",
     "created": 1439229084,
     "data": {"object": deepcopy(FAKE_CUSTOMER)},
     "livemode": False,