### Apache Airflow version

2.7.1

### What happened

120 DAGs broke when I updated to Airflow 2.7.1. I had to revert to 2.7.0 again, so the tests below are from a local deployment.

The error message is the same for all DAGs:

```python
Broken DAG: [/opt/airflow/dags/dag-name.py] Traceback (most recent call last):
  File "/home/airflow/.local/lib/python3.11/site-packages/airflow/models/dag.py", line 640, in __init__
    self.validate_schedule_and_params()
  File "/home/airflow/.local/lib/python3.11/site-packages/airflow/models/dag.py", line 3289, in validate_schedule_and_params
    raise AirflowException(
airflow.exceptions.AirflowException: DAG Schedule must be None, if there are any required params without default values
```

After testing, I found that if I change the blob_prefix param to "" instead of None, the DAG imports successfully. I have various other params which are None that I will probably need to assign default values for (in reality, the function which Airflow runs handles cases if the value is None, but I guess I need to add a default in the DAG). All 120 DAGs with errors had a field like this in the "params" dictionary I pass to Airflow params.

```python
params = {
    "exclude_pattern": "*errors*",
    "blob_prefix": None,
```

### What you think should happen instead

These are legacy DAGs which have run for a long time without changes (old Airflow instance), so I did not expect an upgrade to break them. 

### How to reproduce

I believe the root cause is passing a param with the value None to the DAG params:

```python
params = {
  subfolder=None,
  conn_id="gcs_conn_id",
}

@dag(
    dag_id="dag-example",
    start_date=datetime(2023, 2, 2, tz="America/New_York"),
    schedule="41 2 * * *",
    params=params,
)
```

### Operating System

Ubuntu 22.04

### Versions of Apache Airflow Providers

Providers info
apache-airflow-providers-celery          | 3.3.3 
apache-airflow-providers-common-sql      | 1.7.1 
apache-airflow-providers-docker          | 3.7.4 
apache-airflow-providers-ftp             | 3.5.1 
apache-airflow-providers-google          | 10.7.0
apache-airflow-providers-http            | 4.5.1 
apache-airflow-providers-imap            | 3.3.1 
apache-airflow-providers-microsoft-azure | 6.3.0 
apache-airflow-providers-mysql           | 5.3.0 
apache-airflow-providers-odbc            | 4.0.0 
apache-airflow-providers-openlineage     | 1.0.2 
apache-airflow-providers-postgres        | 5.6.0 
apache-airflow-providers-redis           | 3.3.1 
apache-airflow-providers-sftp            | 4.6.0 
apache-airflow-providers-sqlite          | 3.4.3 
apache-airflow-providers-ssh             | 3.7.2 

### Deployment

Other Docker-based deployment

### Deployment details

Docker Swarm using docker stack deploy

### Anything else

DAGs fail to import when deployed on 2.7.1

### Are you willing to submit PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

"""
        Parse a given link, and verifies if it's a valid URL, or a 'mailto' link.
        Returns an iterator of invalid (owner, link) pairs.
        """
        for owner, link in self.owner_links.items():
            result = urlsplit(link)
            if result.scheme == "mailto":
                
                if not result.path:
                    yield result.path, link
            elif not result.scheme or not result.netloc:
                yield owner, link
class DagTag(Base):
    """A tag name per dag, to allow quick filtering in the DAG view."""
    __tablename__ = "dag_tag"
    name = Column(String(TAG_MAX_LEN), primary_key=True)
    dag_id = Column(
        StringID(),
        ForeignKey("dag.dag_id", name="dag_tag_dag_id_fkey", ondelete="CASCADE"),
        primary_key=True,
    )
    def __repr__(self):
        return self.name
class DagOwnerAttributes(Base):